diff --git a/arkguard/BUILD.gn b/arkguard/BUILD.gn index 9a76b306ea414eea8db028ca3d2f2ff5e6106915..66e5c5af551dc921e74843c7ebb7a4e2adf95826 100644 --- a/arkguard/BUILD.gn +++ b/arkguard/BUILD.gn @@ -13,6 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + import("//arkcompiler/runtime_core/static_core/ark_config.gni") +} else { + import( + "//build/config/components/runtime_core/static_core/ark_common_config.gni") +} + typescript_dir = get_label_info("//third_party/typescript:build_typescript", "target_out_dir") @@ -50,7 +58,7 @@ action("build_arkguard") { "src/utils/TypeUtils.ts", ] - deps = [ "//third_party/typescript:build_typescript" ] + external_deps = [ "typescript:build_typescript_etc" ] script = "compile_arkguard.py" args = [ rebase_path(get_path_info("./", "abspath")), @@ -60,3 +68,12 @@ action("build_arkguard") { outputs = [ "${target_out_dir}/arkguard-1.1.3.tgz" ] } + +if (!(defined(ark_static_standalone_build) && ark_static_standalone_build)) { + ohos_shared_headers("build_arkguard_etc") { + include_dirs = [] + deps = [ ":build_arkguard" ] + part_name = "ets_frontend" + subsystem_name = "arkcompiler" + } +} diff --git a/bundle.json b/bundle.json index bf8ba46efbe882be0889479425cf5e31f163b5b5..884e4a747cad1a8994818df5be8eb2a87e89d72b 100644 --- a/bundle.json +++ b/bundle.json @@ -30,7 +30,8 @@ }, "build": { "sub_component": [ - "//arkcompiler/ets_frontend:ets_frontend_build" + "//arkcompiler/ets_frontend:ets_frontend_build", + "//arkcompiler/ets_frontend/ets2panda:libes2panda_public(//build/toolchain/linux:clang_x64)" ], "inner_kits": [ { @@ -38,10 +39,23 @@ }, { "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" + }, + { + "name": "//arkcompiler/ets_frontend/ets2panda:libes2panda_public_headers" + }, + { + "name": "//arkcompiler/ets_frontend/arkguard:build_arkguard_etc" } ], "test": [ - "//arkcompiler/ets_frontend/es2panda:es2abc_tests" + "//arkcompiler/ets_frontend/es2panda:es2abc_tests", + "//arkcompiler/ets_frontend/ets2panda/bindings/test:bindings_test" ] } } diff --git a/codecheck_ignore.json b/codecheck_ignore.json index 775d3e87749d84a686e43295bed4f0abf0ba279e..a30bb19d2b134825596abb32890795d7089fd638 100755 --- a/codecheck_ignore.json +++ b/codecheck_ignore.json @@ -8,9 +8,18 @@ "test_ecma_bcopt": "*", "legacy_bin": "*", "merge_abc": "*", + "ets2panda/bindings/src": "*", + "ets2panda/driver/build_system/src": "*", "ets2panda/public/headers_parser": "*", "ets2panda/linter/arkanalyzer": "*", "ets2panda/linter/homecheck": "*", + "ets2panda/linter/build_linter.py": "*", + "ets2panda/linter/src/cli/CommandLineParser.ts": "*", + "ets2panda/linter/src/lib/TypeScriptLinter.ts": "*", + "ets2panda/linter/src/lib/autofixes/Autofixer.ts": "*", + "ets2panda/linter/src/lib/autofixes/QuasiEditor.ts": "*", + "ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsCommonFunction.ts": "*", + "ets2panda/linter/src/lib/utils/functions/ConfiguredRulesProcess.ts": "*", "*": ["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 bf961713972d335e111a24b6f0ff27694f984cf7..3a4f766e5a064d40b9e26d26c797b459ce850f18 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 612e64e4b0497b9ed461c4b6e392bf61a5832917..c26216945a93b8924f2a8439e2e3c1eb86f95a2c 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -769,11 +769,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/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 1041491304f62e8dce90cdc9d2799999af33bc6f..3855d73498c1fc3809c821a5a5a9f66fbc519d3e 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 d92e9c42d222d8ef922dd87de6f599e755e3eabd..0dab3b7005fa022e95dab4bb43f5501d3e77ae12 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -120,6 +120,7 @@ Program ParserImpl::Parse(const SourceFile &sourceFile, const CompilerOptions &o if (util::Helpers::IsSupportAnnotationVersion(program_.TargetApiVersion())) { 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 ed6e6ca1be382373ac1cc73d1b0f5a2be50bb1c7..992292ea0023783bce88558618fc237f0615d396 100644 --- a/es2panda/parser/program/program.cpp +++ b/es2panda/parser/program/program.cpp @@ -49,6 +49,7 @@ Program::Program(Program &&other) useDefineSemantic_(other.useDefineSemantic_), isShared_(other.isShared_), enableAnnotations_(other.enableAnnotations_), + enableEtsImplements_(other.enableEtsImplements_), targetApiSubVersion_(other.targetApiSubVersion_), moduleRecordFieldName_(other.moduleRecordFieldName_), sourceLang_(other.sourceLang_) @@ -80,6 +81,7 @@ Program &Program::operator=(Program &&other) useDefineSemantic_ = other.useDefineSemantic_; isShared_ = other.isShared_; enableAnnotations_ = other.enableAnnotations_; + 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 cba731c6c7afed44b9741bb73d218e1f60691855..f19e6ed06982fb58a80bb259ab59e2fa98fc8e4a 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/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/util/helpers.cpp b/es2panda/util/helpers.cpp index 02a0df64f11a2c727441985c79255e933f4f970e..e0cd4127024cff5e8002f30f66880dc8fc786b29 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -803,8 +803,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()) { @@ -829,34 +828,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 91e738b542e215bacb8684e51d064101eb20b3f6..d2a0614fab33466bdd8a5d1c8f5ba974435d1b5f 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 @@ -184,6 +190,7 @@ public: static bool IsSupportLazyImportVersion(int apiVersion, std::string subApiVersion); static bool IsEnableExpectedPropertyCountApiVersion(int apiVersion); static bool IsSupportAnnotationVersion(int apiVersion); + static bool IsSupportEtsImplementsVersion(int apiVersion); static const uint32_t MAX_DOUBLE_DIGIT = 310; static const uint32_t MAX_DOUBLE_PRECISION_DIGIT = 17; @@ -197,6 +204,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 = "*"; @@ -230,8 +238,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 a7d027eff524491a00c579190885a3e525b7ee38..f3b5725553cfb9b5e3a70f389a2e6ef32363c658 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -11,7 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/runtime_core/static_core/ark_config.gni") +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + import("//arkcompiler/runtime_core/static_core/ark_config.gni") +} else { + import( + "//build/config/components/runtime_core/static_core/ark_common_config.gni") +} if (ark_standalone_build) { import("$build_root/ark.gni") @@ -23,12 +29,22 @@ config("libes2panda_public_config") { include_dirs = [ "$target_gen_dir", "$target_gen_dir/include", - "$target_gen_dir/generated", - "//third_party/icu/icu4c/source/common", - "//third_party/icu/icu4c/source/i18n", - "//third_party/icu/icu4c/source", "$ark_es2panda_root", ] + if (ark_standalone_build || ark_static_standalone_build) { + include_dirs += [ + "$target_gen_dir/generated", + "//third_party/icu/icu4c/source/common", + "//third_party/icu/icu4c/source/i18n", + "//third_party/icu/icu4c/source", + ] + } +} + +action("check_build_system_consistency") { + script = "./scripts/check_build_system_consistency.py" + args = [ rebase_path(".", root_build_dir) ] + outputs = [ "$target_gen_dir/consistency_check.stamp" ] } libes2panda_sources = [ @@ -73,12 +89,9 @@ libes2panda_sources = [ "checker/ets/castingContext.cpp", "checker/ets/conversion.cpp", "checker/ets/dynamic.cpp", - "checker/ets/dynamic/dynamicCall.cpp", "checker/ets/etsWarningAnalyzer.cpp", "checker/ets/function.cpp", "checker/ets/helpers.cpp", - "checker/ets/narrowingConverter.cpp", - "checker/ets/narrowingWideningConverter.cpp", "checker/ets/object.cpp", "checker/ets/typeCheckingHelpers.cpp", "checker/ets/typeConverter.cpp", @@ -100,11 +113,12 @@ libes2panda_sources = [ "checker/types/ets/byteType.cpp", "checker/types/ets/charType.cpp", "checker/types/ets/doubleType.cpp", + "checker/types/ets/etsAnyType.cpp", "checker/types/ets/etsArrayType.cpp", "checker/types/ets/etsAsyncFuncReturnType.cpp", + "checker/types/ets/etsAwaitedType.cpp", "checker/types/ets/etsBigIntType.cpp", "checker/types/ets/etsBooleanType.cpp", - "checker/types/ets/etsDynamicType.cpp", "checker/types/ets/etsEnumType.cpp", "checker/types/ets/etsExtensionFuncHelperType.cpp", "checker/types/ets/etsFunctionType.cpp", @@ -114,6 +128,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", @@ -126,6 +141,7 @@ libes2panda_sources = [ "checker/types/ets/shortType.cpp", "checker/types/ets/wildcardType.cpp", "checker/types/globalTypesHolder.cpp", + "checker/types/gradualType.cpp", "checker/types/signature.cpp", "checker/types/ts/anyType.cpp", "checker/types/ts/arrayType.cpp", @@ -201,39 +217,54 @@ libes2panda_sources = [ "compiler/function/generatorFunctionBuilder.cpp", "compiler/lowering/checkerPhase.cpp", "compiler/lowering/ets/ambientLowering.cpp", + "compiler/lowering/ets/annotationCopyLowering.cpp", + "compiler/lowering/ets/annotationCopyPostLowering.cpp", + "compiler/lowering/ets/arrayLiteralLowering.cpp", "compiler/lowering/ets/asyncMethodLowering.cpp", "compiler/lowering/ets/bigintLowering.cpp", - "compiler/lowering/ets/boxedTypeLowering.cpp", + "compiler/lowering/ets/binaryExpressionLowering.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/declGenPhase.cpp", "compiler/lowering/ets/declareOverloadLowering.cpp", "compiler/lowering/ets/defaultParametersInConstructorLowering.cpp", "compiler/lowering/ets/defaultParametersLowering.cpp", + "compiler/lowering/ets/dynamicImport.cpp", "compiler/lowering/ets/enumLowering.cpp", "compiler/lowering/ets/enumPostCheckLowering.cpp", + "compiler/lowering/ets/enumPropertiesInAnnotationsLowering.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/gradualTypeNarrowing.cpp", + "compiler/lowering/ets/insertOptionalParametersAnnotation.cpp", "compiler/lowering/ets/interfaceObjectLiteralLowering.cpp", "compiler/lowering/ets/interfacePropertyDeclarations.cpp", "compiler/lowering/ets/lambdaLowering.cpp", - "compiler/lowering/ets/localClassLowering.cpp", + "compiler/lowering/ets/lateInitialization.cpp", "compiler/lowering/ets/objectIndexAccess.cpp", "compiler/lowering/ets/objectIterator.cpp", "compiler/lowering/ets/objectLiteralLowering.cpp", "compiler/lowering/ets/opAssignment.cpp", "compiler/lowering/ets/optionalArgumentsLowering.cpp", "compiler/lowering/ets/optionalLowering.cpp", + "compiler/lowering/ets/overloadMappingLowering.cpp", "compiler/lowering/ets/packageImplicitImport.cpp", "compiler/lowering/ets/partialExportClassGen.cpp", + "compiler/lowering/ets/primitiveConversionPhase.cpp", "compiler/lowering/ets/promiseVoid.cpp", "compiler/lowering/ets/recordLowering.cpp", + "compiler/lowering/ets/relaxedAnyLowering.cpp", + "compiler/lowering/ets/resizableArrayLowering.cpp", + "compiler/lowering/ets/restArgsLowering.cpp", "compiler/lowering/ets/restTupleLowering.cpp", "compiler/lowering/ets/setJumpTarget.cpp", + "compiler/lowering/ets/setterLowering.cpp", "compiler/lowering/ets/spreadLowering.cpp", "compiler/lowering/ets/stringComparison.cpp", "compiler/lowering/ets/stringConstantsLowering.cpp", @@ -242,6 +273,8 @@ libes2panda_sources = [ "compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp", "compiler/lowering/ets/topLevelStmts/importExportDecls.cpp", "compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp", + "compiler/lowering/ets/typeFromLowering.cpp", + "compiler/lowering/ets/unboxLowering.cpp", "compiler/lowering/ets/unionLowering.cpp", "compiler/lowering/phase.cpp", "compiler/lowering/plugin_phase.cpp", @@ -275,6 +308,7 @@ libes2panda_sources = [ "ir/base/decorator.cpp", "ir/base/metaProperty.cpp", "ir/base/methodDefinition.cpp", + "ir/base/overloadDeclaration.cpp", "ir/base/property.cpp", "ir/base/scriptFunction.cpp", "ir/base/scriptFunctionSignature.cpp", @@ -287,13 +321,14 @@ libes2panda_sources = [ "ir/brokenTypeNode.cpp", "ir/ets/etsClassLiteral.cpp", "ir/ets/etsFunctionType.cpp", + "ir/ets/etsIntrinsicNode.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", @@ -455,6 +490,7 @@ libes2panda_sources = [ "parser/ETSparserStatements.cpp", "parser/ETSparserTypes.cpp", "parser/JSparser.cpp", + "parser/JsdocHelper.cpp", "parser/TSparser.cpp", "parser/ThrowingTypedParser.cpp", "parser/TypedParser.cpp", @@ -467,6 +503,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", @@ -476,7 +513,9 @@ libes2panda_sources = [ "util/es2pandaMacros.cpp", "util/helpers.cpp", "util/importPathManager.cpp", + "util/nameMangler.cpp", "util/path.cpp", + "util/perfMetrics.cpp", "util/plugin.cpp", "util/ustring.cpp", "varbinder/ASBinder.cpp", @@ -519,6 +558,7 @@ HEADERS_TO_BE_PARSED = [ "ir/statement.h", "ir/irnode.h", "checker/types/typeRelation.h", + "ir/ets/etsIntrinsicNode.h", "ir/visitor/AstVisitor.h", "ir/statements/classDeclaration.h", "ir/base/tsMethodSignature.h", @@ -527,7 +567,6 @@ HEADERS_TO_BE_PARSED = [ "checker/types/ts/nonPrimitiveType.h", "ir/ts/tsTypeParameterInstantiation.h", "ir/module/importDeclaration.h", - "checker/types/ets/etsDynamicType.h", "ir/statements/doWhileStatement.h", "ir/expressions/literals/bigIntLiteral.h", "ir/expressions/assignmentExpression.h", @@ -599,8 +638,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", @@ -615,7 +654,6 @@ HEADERS_TO_BE_PARSED = [ "ir/ts/tsParenthesizedType.h", "ir/ts/tsModuleDeclaration.h", "ir/ets/etsPackageDeclaration.h", - "checker/types/ets/etsDynamicFunctionType.h", "ir/expressions/literals/regExpLiteral.h", "ir/ets/etsNewArrayInstanceExpression.h", "checker/types/ets/etsVoidType.h", @@ -705,6 +743,7 @@ HEADERS_TO_BE_PARSED = [ "ir/ts/tsImportEqualsDeclaration.h", "ir/validationInfo.h", "ir/base/methodDefinition.h", + "ir/base/overloadDeclaration.h", "ir/ts/tsIntersectionType.h", "checker/types/ts/nullType.h", "checker/types/ts/unknownType.h", @@ -758,6 +797,9 @@ HEADERS_TO_BE_PARSED = [ "es2panda.h", "ast_verifier/ASTVerifier.h", "util/importPathManager.h", + "util/options.h", + "util/path.h", + "util/arktsconfig.h", ] ES2PANDA_API_GENERATED = [ @@ -786,7 +828,6 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/expressions/objectExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/module/importSpecifier.yaml", "$LIBGEN_DIR/gen/headers/ir/expressions/conditionalExpression.yaml", - "$LIBGEN_DIR/gen/headers/checker/types/ets/etsDynamicFunctionType.yaml", "$LIBGEN_DIR/gen/headers/ir/expressions/callExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/expressions/literals/bigIntLiteral.yaml", "$LIBGEN_DIR/gen/headers/ir/base/classElement.yaml", @@ -796,6 +837,7 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/visitor/IterateAstVisitor.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/functionDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/ets/etsTypeReference.yaml", + "$LIBGEN_DIR/gen/headers/ir/ets/etsIntrinsicNode.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/tupleType.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsTypeReference.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/functionType.yaml", @@ -900,7 +942,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", @@ -911,7 +952,6 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/expressions/blockExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsTypeLiteral.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsTypeParameter.yaml", - "$LIBGEN_DIR/gen/headers/checker/types/ets/etsDynamicType.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ets/charType.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsBooleanKeyword.yaml", "$LIBGEN_DIR/gen/headers/ir/base/spreadElement.yaml", @@ -951,6 +991,7 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/expressions/directEvalExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsTypeParameterDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/base/methodDefinition.yaml", + "$LIBGEN_DIR/gen/headers/ir/base/overloadDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsNullKeyword.yaml", "$LIBGEN_DIR/gen/headers/ir/ts/tsInterfaceHeritage.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/enumLiteralType.yaml", @@ -1025,6 +1066,9 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/parser/program/program.yaml", "$LIBGEN_DIR/gen/headers/ast_verifier/ASTVerifier.yaml", "$LIBGEN_DIR/gen/headers/util/importPathManager.yaml", + "$LIBGEN_DIR/gen/headers/util/path.yaml", + "$LIBGEN_DIR/gen/headers/util/arktsconfig.yaml", + "$LIBGEN_DIR/gen/headers/util/options.yaml", ] ES2PANDA_API = [ @@ -1042,6 +1086,7 @@ action("libes2panda_public_parse_headers") { script = "./public/headers_parser/main.py" deps = [ + ":check_build_system_consistency", ":es2panda_options_gen_options_h", ":gen_es2panda_lexer_tokenType_h", ] @@ -1072,6 +1117,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/" @@ -1083,6 +1129,7 @@ ark_gen("gen") { # libarkruntime, and conflict with JIT setup ensues libes2panda_public_sources = [ "declgen_ets2ts/declgenEts2Ts.cpp", + "declgen_ets2ts/isolatedDeclgenChecker.cpp", "public/${LIB_NAME}.cpp", "util/generateBin.cpp", "util/options.cpp", @@ -1093,27 +1140,58 @@ config("libes2panda_config") { "-fexceptions", "-Werror=shadow", ] + + if (!is_debug && !is_mac) { + cflags_cc += [ + "-flto=thin", + "-O3", + ] + ldflags = [ + "-flto=thin", + "-O3", + ] + } +} + +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + libes2panda_configs = [ "$ark_root:ark_config" ] + libes2panda_public_configs = [ "$ark_root:ark_config" ] +} else { + libes2panda_configs = + [ "//build/config/components/runtime_core/static_core:ark_common_config" ] + libes2panda_public_configs = + [ "//build/config/components/runtime_core/static_core:ark_common_config" ] } -libes2panda_configs = [ - "$ark_root/assembler:arkassembler_public_config", - "$ark_root:ark_config", +if (ark_standalone_build || ark_static_standalone_build) { + libes2panda_configs += [ + "$ark_root/assembler:arkassembler_public_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/libarkfile:arkfile_public_config", + "$ark_root/abc2program:arkts_abc2program_public_config", + ] +} + +libes2panda_configs += [ ":libes2panda_public_config", ":libes2panda_config", - "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", ] -libes2panda_public_configs = [ - "$ark_root/assembler:arkassembler_public_config", - "$ark_root:ark_config", +if (ark_standalone_build || ark_static_standalone_build) { + libes2panda_public_configs += [ + "$ark_root/assembler:arkassembler_public_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/libarkfile:arkfile_public_config", + "$ark_root/bytecode_optimizer:bytecodeopt_public_config", + "$ark_root/runtime:arkruntime_public_config", + "$ark_root/compiler:arkcompiler_public_config", + ] +} + +libes2panda_public_configs += [ ":libes2panda_public_config", ":libes2panda_config", - "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", - "$ark_root/bytecode_optimizer:bytecodeopt_public_config", - "$ark_root/compiler:arkcompiler_public_config", - "$ark_root/runtime:arkruntime_public_config", ] ohos_shared_library("libes2panda") { @@ -1133,6 +1211,7 @@ ohos_source_set("libes2panda_frontend_static") { ":es2panda_options_gen_options_h", ":gen_${LIB_NAME}_decl_inc", ":gen_${LIB_NAME}_enums_inc", + ":gen_${LIB_NAME}_idl", ":gen_${LIB_NAME}_impl_inc", ":gen_${LIB_NAME}_include_inc", ":gen_${LIB_NAME}_list_inc", @@ -1144,6 +1223,7 @@ ohos_source_set("libes2panda_frontend_static") { ":isa_gen_es2panda_isa_h", ] external_deps = [ + "runtime_core:libarktsabc2program_package", "runtime_core:libarktsassembler_package", "runtime_core:libarktsbase_package", "runtime_core:libarktscompiler_package", @@ -1159,6 +1239,11 @@ ohos_source_set("libes2panda_frontend_static") { external_deps += [ "icu:static_icui18n", "icu:static_icuuc", + "runtime_core:arkts_abc2program_public_headers", + "runtime_core:assembler_headers", + "runtime_core:libpandabase_headers", + "runtime_core:libpandafile_headers", + "runtime_core:runtime_gen_headers", ] } part_name = "ets_frontend" @@ -1166,6 +1251,7 @@ ohos_source_set("libes2panda_frontend_static") { } ohos_shared_library("libes2panda_public") { + configs = [ ":libes2panda_config" ] deps = [ ":libes2panda_public_frontend_static" ] if (is_mingw || is_win) { output_extension = "dll" @@ -1182,6 +1268,22 @@ ohos_shared_library("libes2panda_public") { subsystem_name = "arkcompiler" } +if (!(defined(ark_static_standalone_build) && ark_static_standalone_build)) { + ohos_shared_headers("libes2panda_public_headers") { + include_dirs = [ "$ark_es2panda_root/public" ] + deps = [ + ":gen_${LIB_NAME}_decl_inc", + ":gen_${LIB_NAME}_enums_inc", + ":gen_${LIB_NAME}_idl", + ":gen_${LIB_NAME}_impl_inc", + ":gen_${LIB_NAME}_include_inc", + ":gen_${LIB_NAME}_list_inc", + ] + part_name = "ets_frontend" + subsystem_name = "arkcompiler" + } +} + action("generate_ets2panda_info") { script = "$ark_root/gn/build/es2panda_info.sh" outputs = [ "$target_gen_dir/generated/es2panda_build_info.h" ] @@ -1198,19 +1300,39 @@ ohos_source_set("libes2panda_public_frontend_static") { deps = [ ":libes2panda_frontend_static" ] - if (ark_standalone_build || ark_static_standalone_build) { - deps += [ "$ark_root/bytecode_optimizer:libarktsbytecodeopt_package" ] - } - if (target_os != "win" && target_os != "mingw" && target_os != "winuwp") { deps += [ ":generate_ets2panda_info" ] defines = [ "ES2PANDA_COMPILE_BY_GN" ] } external_deps = [ + "runtime_core:libarktsabc2program_package", "runtime_core:libarktsbytecodeopt_package", sdk_libc_secshared_dep, ] + + if (ark_standalone_build || ark_static_standalone_build) { + deps += [ + "$ark_root/abc2program:libarktsabc2program_package", + "$ark_root/assembler:libarktsassembler", + "$ark_root/bytecode_optimizer:libarktsbytecodeopt_package", + "$ark_root/compiler:libarktscompiler", + "$ark_root/libarkfile:libarktsfile", + "$ark_root/libpandabase:libarktsbase", + ] + } else { + external_deps += [ + "runtime_core:assembler_headers", + "runtime_core:bytecode_optimizer_headers", + "runtime_core:compiler_headers", + "runtime_core:libpandabase_headers", + "runtime_core:libpandafile_headers", + "runtime_core:runtime_gen_headers", + "runtime_core:runtime_headers", + "runtime_core:verification_headers", + ] + } + part_name = "ets_frontend" subsystem_name = "arkcompiler" } @@ -1240,6 +1362,7 @@ ark_gen("es2panda_diagnostic_gen") { "util/diagnostic/fatal.yaml", "declgen_ets2ts/declgen_ets2ts_error.yaml", "declgen_ets2ts/declgen_ets2ts_warning.yaml", + "declgen_ets2ts/isolated_declgen.yaml", "util/diagnostic/arktsconfig_error.yaml", ] template_files = [ "diagnostic.h.erb" ] @@ -1253,6 +1376,7 @@ ark_gen("es2panda_diagnostic_gen") { "util/diagnostic/diagnostic.rb", "util/diagnostic/diagnostic.rb", "util/diagnostic/diagnostic.rb", + "util/diagnostic/diagnostic.rb", ] } @@ -1281,3 +1405,41 @@ ark_gen("gen_es2panda_compiler") { destination = "$target_gen_dir/generated" api = [ "compiler/scripts/signatures.rb" ] } + +template("panda_code_fix_gen") { + code_fix_api = "$ark_es2panda_root/lsp/code_fix_register.rb" + api_list = [] + foreach(i, invoker.data) { + api_list += [ code_fix_api ] + } + + ark_gen("$target_name") { + data = invoker.data + template_files = invoker.template_files + sources = invoker.sources + destination = invoker.destination + api = api_list + if (defined(invoker.requires)) { + requires = invoker.requires + } + if (defined(invoker.extra_dependencies)) { + extra_dependencies = invoker.extra_dependencies + } + } +} + +panda_code_fix_gen("es2panda_lsp_code_fix_register_gen") { + data = [ + "util/diagnostic/syntax.yaml", + "util/diagnostic/semantic.yaml", + "util/diagnostic/warning.yaml", + "util/diagnostic/fatal.yaml", + "declgen_ets2ts/declgen_ets2ts_error.yaml", + "declgen_ets2ts/declgen_ets2ts_warning.yaml", + "declgen_ets2ts/isolated_declgen.yaml", + "util/diagnostic/arktsconfig_error.yaml", + ] + template_files = [ "code_fix_register.h.erb" ] + sources = "lsp" + destination = "$target_gen_dir/generated" +} diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index bd09554954d0b099ab6e2231ca696034cf7c411b..13f327c3b7ec485f05315d4b60ea8850455b88e6 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -14,10 +14,23 @@ cmake_minimum_required (VERSION 3.5.0) include(cmake/coverage.cmake) +include(cmake/PandaCmakeFunctions.cmake) project (es2panda) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# ----- Aliases ---------------------------------------------------------------- + +add_custom_target(frontend_bins COMMENT "Build all common frontend binaries") +add_dependencies(frontend_bins + es2panda + es2panda-lib + es2panda-public + dependency_analyzer + dependency_analyzer_lib + declgen_ets2ts +) + set(ES2PANDA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) set(ES2PANDA_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}) @@ -61,6 +74,7 @@ if(PANDA_WITH_ETS) " \"@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" @@ -69,12 +83,13 @@ if(PANDA_WITH_ETS) " \"@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" + " \"dependencies\": {\n" " \"dynamic_import_tests\": {\"language\": \"js\", \"ohmUrl\": \"dynamic_import_tests\"},\n" - " \"dynamic_import_tests/modules/instanceof\": {\"language\": \"js\", \"declPath\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/instanceof.ets\", \"ohmUrl\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/instanceof.ets\"},\n" - " \"dynamic_import_tests/modules/module\": {\"language\": \"js\", \"declPath\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/module.ets\", \"ohmUrl\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/module.ets\"}\n" + " \"dynamic_import_tests/modules/instanceof\": {\"language\": \"js\", \"path\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/instanceof.ets\", \"ohmUrl\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/instanceof.ets\"},\n" + " \"dynamic_import_tests/modules/module\": {\"language\": \"js\", \"path\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/module.ets\", \"ohmUrl\": \"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/dynamic_import_tests/modules/module.ets\"}\n" " }\n" " }\n" "}\n" @@ -142,6 +157,7 @@ panda_gen( ${DIAGNOSTIC_DIR}/fatal.yaml ${CMAKE_CURRENT_SOURCE_DIR}/declgen_ets2ts/declgen_ets2ts_error.yaml ${CMAKE_CURRENT_SOURCE_DIR}/declgen_ets2ts/declgen_ets2ts_warning.yaml + ${CMAKE_CURRENT_SOURCE_DIR}/declgen_ets2ts/isolated_declgen.yaml ${DIAGNOSTIC_DIR}/arktsconfig_error.yaml TARGET_NAME es2panda_diagnostic_gen TEMPLATES diagnostic.h.erb @@ -155,6 +171,7 @@ panda_gen( ${DIAGNOSTIC_DIR}/diagnostic.rb ${DIAGNOSTIC_DIR}/diagnostic.rb ${DIAGNOSTIC_DIR}/diagnostic.rb + ${DIAGNOSTIC_DIR}/diagnostic.rb ) panda_gen( @@ -272,30 +289,40 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/expressionLambdaLowering.cpp compiler/lowering/ets/extensionAccessorLowering.cpp compiler/lowering/ets/genericBridgesLowering.cpp - compiler/lowering/ets/boxedTypeLowering.cpp + compiler/lowering/ets/gradualTypeNarrowing.cpp + compiler/lowering/ets/arrayLiteralLowering.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/declGenPhase.cpp compiler/lowering/ets/defaultParametersInConstructorLowering.cpp compiler/lowering/ets/defaultParametersLowering.cpp + compiler/lowering/ets/exportAnonymousConst.cpp + compiler/lowering/ets/lateInitialization.cpp compiler/lowering/ets/lambdaLowering.cpp + compiler/lowering/ets/dynamicImport.cpp compiler/lowering/ets/restTupleLowering.cpp compiler/lowering/ets/spreadLowering.cpp - compiler/lowering/ets/localClassLowering.cpp compiler/lowering/ets/objectIndexAccess.cpp compiler/lowering/ets/objectIterator.cpp + compiler/lowering/ets/insertOptionalParametersAnnotation.cpp 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/binaryExpressionLowering.cpp compiler/lowering/ets/recordLowering.cpp + compiler/lowering/ets/relaxedAnyLowering.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 + compiler/lowering/ets/overloadMappingLowering.cpp compiler/lowering/ets/expandBrackets.cpp compiler/lowering/ets/packageImplicitImport.cpp compiler/lowering/ets/partialExportClassGen.cpp @@ -305,9 +332,16 @@ 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/enumPropertiesInAnnotationsLowering.cpp compiler/lowering/ets/setJumpTarget.cpp + compiler/lowering/ets/setterLowering.cpp + compiler/lowering/ets/annotationCopyLowering.cpp + compiler/lowering/ets/annotationCopyPostLowering.cpp + compiler/lowering/ets/primitiveConversionPhase.cpp + compiler/lowering/ets/unboxLowering.cpp ir/astDump.cpp ir/srcDump.cpp ir/astNode.cpp @@ -324,6 +358,7 @@ set(ES2PANDA_LIB_SRC ir/base/decorator.cpp ir/base/metaProperty.cpp ir/base/methodDefinition.cpp + ir/base/overloadDeclaration.cpp ir/base/property.cpp ir/base/scriptFunction.cpp ir/base/scriptFunctionSignature.cpp @@ -411,15 +446,17 @@ set(ES2PANDA_LIB_SRC ir/as/namedType.cpp ir/as/prefixAssertionExpression.cpp ir/ets/etsClassLiteral.cpp + ir/ets/etsIntrinsicNode.cpp ir/ets/etsFunctionType.cpp + ir/ets/etsIntrinsicNode.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 @@ -495,6 +532,7 @@ set(ES2PANDA_LIB_SRC parser/expressionTSParser.cpp parser/ASparser.cpp parser/JSparser.cpp + parser/JsdocHelper.cpp parser/parserImpl.cpp parser/ETSFormattedParser.cpp parser/ETSparser.cpp @@ -513,6 +551,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 @@ -534,13 +573,10 @@ set(ES2PANDA_LIB_SRC checker/ets/castingContext.cpp checker/ets/conversion.cpp checker/ets/dynamic.cpp - checker/ets/dynamic/dynamicCall.cpp checker/ets/function.cpp checker/ets/validateHelpers.cpp checker/ets/typeCheckingHelpers.cpp checker/ets/helpers.cpp - checker/ets/narrowingConverter.cpp - checker/ets/narrowingWideningConverter.cpp checker/ets/object.cpp checker/ets/typeConverter.cpp checker/ets/typeCreation.cpp @@ -560,6 +596,7 @@ set(ES2PANDA_LIB_SRC checker/types/type.cpp checker/types/typeRelation.cpp checker/types/globalTypesHolder.cpp + checker/types/gradualType.cpp checker/types/ets/byteType.cpp checker/types/ets/charType.cpp checker/types/ets/doubleType.cpp @@ -567,15 +604,16 @@ set(ES2PANDA_LIB_SRC checker/types/ets/intType.cpp checker/types/ets/longType.cpp checker/types/ets/shortType.cpp + checker/types/ets/etsAnyType.cpp checker/types/ets/etsArrayType.cpp checker/types/ets/etsBooleanType.cpp - checker/types/ets/etsDynamicType.cpp checker/types/ets/etsEnumType.cpp checker/types/ets/etsExtensionFuncHelperType.cpp checker/types/ets/etsFunctionType.cpp 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 @@ -584,6 +622,7 @@ set(ES2PANDA_LIB_SRC checker/types/ets/etsTypeAliasType.cpp checker/types/ets/etsTypeParameter.cpp checker/types/ets/etsPartialTypeParameter.cpp + checker/types/ets/etsAwaitedType.cpp checker/types/ets/etsUnionType.cpp checker/types/ets/etsVoidType.cpp checker/types/ets/wildcardType.cpp @@ -626,9 +665,11 @@ set(ES2PANDA_LIB_SRC util/es2pandaMacros.cpp util/helpers.cpp util/importPathManager.cpp + util/nameMangler.cpp util/path.cpp + util/plugin.cpp + util/perfMetrics.cpp util/ustring.cpp - test/utils/panda_executable_path_getter.cpp evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp evaluate/debugInfoDeserialization/inheritanceResolution.cpp evaluate/debugInfoDeserialization/methodBuilder.cpp @@ -645,7 +686,7 @@ set(ES2PANDA_LIB_SRC # libes2panda does not include bytecode optimizer, because it is used in # libarkruntime, and conflict with JIT setup ensues -panda_add_library(es2panda-lib ${PANDA_DEFAULT_LIB_TYPE} ${ES2PANDA_LIB_SRC}) +panda_frontend_add_library(es2panda-lib ${PANDA_DEFAULT_LIB_TYPE} ${ES2PANDA_LIB_SRC}) add_dependencies(es2panda-lib isa_gen_es2panda es2panda_options_gen es2panda_diagnostic_gen es2panda_keywords es2panda_signatures) set(ICU_INCLUDE_DIRS @@ -667,9 +708,16 @@ panda_target_compile_options(es2panda-lib PRIVATE -fexceptions -Werror=shadow ) +if (EN_ISOLATED_DECLGEN) + message(STATUS "Isolated declgen enabled") + panda_target_compile_definitions(es2panda-lib + PRIVATE -DENABLE_ISOLATED_DECLGEN + ) +endif() + panda_target_link_libraries(es2panda-lib PUBLIC arkbase hmicuuc.z - PRIVATE arkassembler arkdisassembler arkfile + PRIVATE arkassembler arkdisassembler arkfile abc2program ) if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) OR diff --git a/ets2panda/REVIEWERS b/ets2panda/REVIEWERS index fb870eeee4fee1dc7dd5a278626d1ff5846d012b..d2433e767d8e64e93baeed9298341e8f481d3612 100644 --- a/ets2panda/REVIEWERS +++ b/ets2panda/REVIEWERS @@ -18,12 +18,11 @@ /es2panda/ @gavin1012_hw /ets2panda/ @igelhaus @Prof1983 /ets2panda/aot @dkofanov @gavin1012_hw ^igelhaus ^Prof1983 -/ets2panda/ast_verifier @mbolshov @dkofanov ^yyang16 ^igelhaus ^Prof1983 -/ets2panda/bindings ^igelhaus ^Prof1983 @dreamdoomwalker @Ascnbio ^muhammet-fevzi-bayiroglu @utkugursel -/ets2panda/lexer @chernykhsergey @igelhaus ^zelentsovdmitry @Prof1983 -/ets2panda/lsp ^igelhaus ^Prof1983 @dreamdoomwalker @Ascnbio ^muhammet-fevzi-bayiroglu @utkugursel -/ets2panda/parser @chernykhsergey ^igelhaus ^Prof1983 -/ets2panda/public @mbolshov @yyang16 ^igelhaus ^Prof1983 +/ets2panda/ast_verifier ^mbolshov @dkofanov ^igelhaus ^Prof1983 +/ets2panda/bindings ^igelhaus ^Prof1983 @dreamdoomwalker @Ascnbio +/ets2panda/lexer @robertsipka ^chernykhsergey ^csabaosztrogonac @igelhaus ^zelentsovdmitry @Prof1983 +/ets2panda/lsp ^igelhaus ^Prof1983 @dreamdoomwalker @Ascnbio +/ets2panda/public @mbolshov @zhelyapovaleksey ^igelhaus ^Prof1983 /ets2panda/test ^akmaevaleksey ^igelhaus ^Prof1983 /legacy_bin/ @ctw-ian /merge_abc/ @gavin1012_hw @@ -33,54 +32,63 @@ /test262/*.py @shirunova_viktoria @gavin1012_hw @zhuheng27 /test262/ignored*.txt @shirunova_viktoria @gavin1012_hw @kuchkovairina @zhuheng27 /test_ecma_bcopt/ @gavin1012_hw -/ets2panda/checker/ @akmaevaleksey @zelentsovdmitry ^lirismankarina ^igelhaus ^Prof1983 +/ets2panda/checker/ @rtakacs ^akmaevaleksey @zelentsovdmitry ^csabaosztrogonac ^lirismankarina ^igelhaus ^Prof1983 /ets2panda/checker/ETS*.* @zelentsovdmitry ^igelhaus ^Prof1983 -/ets2panda/checker/ETSAnalyzer.cpp ^akmaevaleksey @Ekkoruse ^igelhaus ^Prof1983 +/ets2panda/checker/ETSAnalyzer.cpp ^akmaevaleksey @martinsajti @Ekkoruse ^igelhaus ^Prof1983 /ets2panda/checker/ETSAnalyzerHelpers.* @lirismankarina ^igelhaus ^Prof1983 -/ets2panda/compiler/ @xuxjeeee @gogabr ^igelhaus ^Prof1983 ^zelentsovdmitry -/ets2panda/declgen_ets2ts/ @dreamdoomwalker ^trubachevilya ^ivagin ^hufeng20 ^igelhaus ^Prof1983 @zenghang11 -/ets2panda/driver/ @trubachevilya @dreamdoomwalker ^chenqy930 ^hufeng20 ^igelhaus ^Prof1983 @zenghang11 -/ets2panda/ir/ @ziziziiziziz @gavin1012_hw ^igelhaus ^Prof1983 -/ets2panda/linter/ @ragnvald @rosinskiyigor @eokolnov1 @liwentao_uiw ^utkugursel -/ets2panda/parser/ @mkaskov ^igelhaus ^Prof1983 ^chernykhsergey ^zelentsovdmitry +/ets2panda/compiler/ @xuxjeeee @gogabr ^csabaosztrogonac ^igelhaus ^Prof1983 ^zelentsovdmitry +/ets2panda/declgen_ets2ts/ @dreamdoomwalker ^trubachevilya ^ivagin ^igelhaus ^Prof1983 +/ets2panda/driver/ @trubachevilya @dreamdoomwalker ^igelhaus ^Prof1983 +/ets2panda/ir/ @ziziziiziziz ^gavin1012_hw @csabaosztrogonac ^igelhaus ^Prof1983 +/ets2panda/linter/ @rosinskiyigor @eokolnov1 @yyytiancai ^utkugursel +/ets2panda/parser/ @robertsipka @shimenkovmikhail ^igelhaus ^csabaosztrogonac ^Prof1983 ^chernykhsergey ^zelentsovdmitry /ets2panda/scripts/*-build.sh @titovatatiana ^igelhaus ^Prof1983 /ets2panda/scripts/arkui* @titovatatiana ^igelhaus ^Prof1983 -/ets2panda/test/ast @mbolshov ^igelhaus ^Prof1983 +/ets2panda/scripts/normalize_yaml @peterpronai ^igelhaus ^Prof1983 +/ets2panda/test/ast @ozerovnikita ^igelhaus ^Prof1983 +/ets2panda/test/benchmarks @pishin /ets2panda/test/depanalyzer @trubachevilya @dreamdoomwalker ^igelhaus ^Prof1983 /ets2panda/test/srcdump @mbolshov ^igelhaus ^Prof1983 /ets2panda/test/test-lists @igelhaus ^Prof1983 /ets2panda/test/utils @mbolshov ^igelhaus ^Prof1983 -/ets2panda/util/ @mkaskov @dkofanov ^igelhaus ^Prof1983 +/ets2panda/util/ @shimenkovmikhail @dkofanov ^igelhaus ^Prof1983 /ets2panda/util/arktsconfig* @dreamdoomwalker @trubachevilya ^igelhaus ^Prof1983 -/ets2panda/util/diagnostic* @chernykhsergey @mkaskov ^igelhaus ^Prof1983 +/ets2panda/util/diagnostic* @peterpronai ^chernykhsergey @shimenkovmikhail ^igelhaus ^Prof1983 /ets2panda/util/importPathManager* @dreamdoomwalker @trubachevilya ^igelhaus ^Prof1983 -/ets2panda/util/plugin.* @yyang16 @mbolshov ^igelhaus ^Prof1983 +/ets2panda/util/plugin.* @zhelyapovaleksey @mbolshov ^igelhaus ^Prof1983 /ets2panda/varbinder/ @lirismankarina @akmaevaleksey ^Ekkoruse ^zelentsovdmitry ^igelhaus ^Prof1983 +/ets2panda/varbinder/ETSBinder.* @torokg ^zelentsovdmitry ^igelhaus ^Prof1983 +/ets2panda/varbinder/TypedBinder.* @torokg ^zelentsovdmitry ^igelhaus ^Prof1983 +/ets2panda/varbinder/recordTable.* @torokg ^zelentsovdmitry ^igelhaus ^Prof1983 +/ets2panda/varbinder/scope.* @torokg ^zelentsovdmitry ^igelhaus ^Prof1983 +/ets2panda/varbinder/varbinder.* @torokg ^zelentsovdmitry ^igelhaus ^Prof1983 /test/workload/ignored*.txt @shirunova_viktoria @kuchkovairina @gavin1012_hw @zhuheng27 /ets2panda/checker/ets/ @lirismankarina ^igelhaus ^Prof1983 +/ets2panda/checker/ets/*converter* @martinsajti ^pimenovdmitry ^igelhaus ^Prof1983 /ets2panda/checker/ets/function.cpp @gogabr ^vpukhov ^igelhaus ^Prof1983 /ets2panda/checker/ets/helpers.cpp @xuxjeeee @zelentsovdmitry ^igelhaus ^Prof1983 /ets2panda/checker/ets/object.cpp @xuxjeeee @zelentsovdmitry ^vpukhov ^igelhaus ^Prof1983 -/ets2panda/checker/types/ets @dkofanov ^igelhaus ^Prof1983 -/ets2panda/checker/types/signature.* ^vpukhov ^igelhaus ^Prof1983 @zelentsovdmitry -/ets2panda/checker/types/typeFlag.h ^vpukhov ^igelhaus ^Prof1983 @mkaskov -/ets2panda/checker/types/typeRelation.* ^vpukhov ^igelhaus ^Prof1983 @mkaskov +/ets2panda/checker/ets/utilityTypeHandlers.cpp @martinsajti ^pimenovdmitry ^igelhaus ^Prof1983 +/ets2panda/checker/types/ets @torokg ^martinsajti ^igelhaus ^Prof1983 +/ets2panda/checker/types/signature.* ^vpukhov ^martinsajti ^igelhaus ^Prof1983 @zelentsovdmitry +/ets2panda/checker/types/typeFlag.h ^vpukhov ^martinsajti ^igelhaus ^Prof1983 @shimenkovmikhail +/ets2panda/checker/types/typeRelation.* ^vpukhov @martinsajti ^igelhaus ^Prof1983 ^shimenkovmikhail /ets2panda/compiler/core/ @zelentsovdmitry @xuxjeeee ^vpukhov ^igelhaus ^Prof1983 -/ets2panda/compiler/core/compilerImpl.* @yyang16 @dkofanov ^xuxjeeee ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/phase.* @yyang16 ^mbolshov ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/plugin_phase.* @yyang16 ^mbolshov ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/util.* @yyang16 ^mbolshov ^igelhaus ^Prof1983 +/ets2panda/compiler/core/compilerImpl.* @pimenovdmitry @dkofanov ^xuxjeeee ^igelhaus ^Prof1983 +/ets2panda/compiler/lowering/phase.* @pimenovdmitry ^mbolshov ^igelhaus ^Prof1983 +/ets2panda/compiler/lowering/plugin_phase.* @pimenovdmitry ^mbolshov ^igelhaus ^Prof1983 +/ets2panda/compiler/lowering/util.* @pimenovdmitry ^mbolshov ^igelhaus ^Prof1983 /ets2panda/ir/ets/ @lirismankarina @xuxjeeee ^igelhaus ^Prof1983 -/ets2panda/ir/expressions/ @mkaskov @ziziziiziziz ^igelhaus ^Prof1983 +/ets2panda/ir/expressions/ @shimenkovmikhail @ziziziiziziz ^igelhaus ^Prof1983 /ets2panda/ir/statements/ @dkofanov @Ekkoruse ^akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/ir/statements/annotation* @lirismankarina @xuxjeeee ^igelhaus ^Prof1983 /ets2panda/test/test-lists/astchecker @chernykhsergey ^igelhaus ^Prof1983 -/ets2panda/test/test-lists/declgenets2ts @dreamdoomwalker ^hufeng20 ^igelhaus ^Prof1983 @zenghang11 +/ets2panda/test/test-lists/declgenets2ts @dreamdoomwalker ^igelhaus ^Prof1983 /ets2panda/test/test-lists/parser @chernykhsergey ^igelhaus ^Prof1983 /ets2panda/test/unit/arktsconfig-parser @trubachevilya @dreamdoomwalker ^igelhaus ^Prof1983 -/ets2panda/test/unit/lsp @dreamdoomwalker @utkugursel ^igelhaus ^Prof1983 -/ets2panda/test/unit/plugin* @mbolshov ^igelhaus ^Prof1983 -/ets2panda/test/unit/public @mbolshov ^igelhaus ^Prof1983 +/ets2panda/test/unit/lsp @dreamdoomwalker @Ascnbio ^igelhaus ^Prof1983 +/ets2panda/test/unit/plugin* @zhelyapovaleksey ^mbolshov ^igelhaus ^Prof1983 +/ets2panda/test/unit/public @zhelyapovaleksey ^mbolshov ^igelhaus ^Prof1983 /ets2panda/checker/types/ets/Nullish.* ^vpukhov @gogabr ^igelhaus ^Prof1983 /ets2panda/checker/types/ets/etsA* @xuxjeeee ^gogabr ^igelhaus ^Prof1983 /ets2panda/checker/types/ets/etsE* @ziziziiziziz ^zelentsovdmitry ^igelhaus ^Prof1983 @@ -90,12 +98,12 @@ /ets2panda/checker/types/ets/etsTypeParameter.* ^vpukhov @gogabr ^igelhaus ^Prof1983 /ets2panda/checker/types/ets/etsUnionType.* @akmaevaleksey ^vpukhov ^igelhaus ^Prof1983 /ets2panda/checker/types/ets/wildcardType.* ^vpukhov @gogabr ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/ets/ @gogabr ^igelhaus ^Prof1983 ^zelentsovdmitry +/ets2panda/compiler/lowering/ets/ @gogabr ^torokg ^igelhaus ^Prof1983 ^zelentsovdmitry /ets2panda/compiler/lowering/ets/const* @ziziziiziziz @lirismankarina ^akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/enum* @ziziziiziziz @dkofanov ^akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/lambdaLowering.cpp @Ekkoruse @gogabr ^vpukhov ^akmaevaleksey ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/ets/localClassLowering.cpp @gogabr ^akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/optionalLowering.cpp @akmaevaleksey ^vpukhov ^igelhaus ^Prof1983 +/ets2panda/compiler/lowering/ets/partialExportClassGen.* @pimenovdmitry ^martinsajti ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/spread* @ziziziiziziz @dkofanov ^akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/unionLowering.cpp @Ekkoruse @akmaevaleksey ^vpukhov ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/topLevelStmts/.* @lirismankarina @xuxjeeee ^akmaevaleksey ^vpukhov ^igelhaus ^Prof1983 diff --git a/ets2panda/aot/BUILD.gn b/ets2panda/aot/BUILD.gn index 0a8d75cffd5c6a880a53e3d4721e60d59b3b342b..a861d7d1a4751dc7daa6d89d5dceff79f7fda1e0 100644 --- a/ets2panda/aot/BUILD.gn +++ b/ets2panda/aot/BUILD.gn @@ -11,7 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/runtime_core/static_core/ark_config.gni") +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + import("//arkcompiler/runtime_core/static_core/ark_config.gni") +} else { + import( + "//build/config/components/runtime_core/static_core/ark_common_config.gni") +} if (ark_standalone_build) { import("$build_root/ark.gni") @@ -26,16 +32,29 @@ ohos_executable("ets2panda") { "$target_gen_dir", "$target_gen_dir/include", ] + if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + configs = [ "$ark_root:ark_config" ] + } else { + configs = [ + "//build/config/components/runtime_core/static_core:ark_common_config", + ] + } + + if (ark_standalone_build || ark_static_standalone_build) { + configs += [ + "$ark_root/assembler:arkassembler_public_config", + "$ark_root/libarkfile:arkfile_public_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/bytecode_optimizer:bytecodeopt_public_config", + "$ark_root/runtime:arkruntime_public_config", + "$ark_root/compiler:arkcompiler_public_config", + ] + } - configs = [ - "$ark_root:ark_config", - "$ark_root/assembler:arkassembler_public_config", + configs += [ "$ark_es2panda_root:libes2panda_public_config", - "$ark_root/libpandafile:arkfile_public_config", - "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/bytecode_optimizer:bytecodeopt_public_config", - "$ark_root/compiler:arkcompiler_public_config", - "$ark_root/runtime:arkruntime_public_config", + "$ark_es2panda_root:libes2panda_config", ] deps = [ @@ -47,7 +66,7 @@ ohos_executable("ets2panda") { deps += [ "$ark_root/bytecode_optimizer:libarktsbytecodeopt_package", "$ark_root/libpandabase:libarktsbase_package", - "$ark_root/libpandafile:libarktsfile_package", + "$ark_root/libarkfile:libarktsfile_package", ] } @@ -57,9 +76,23 @@ ohos_executable("ets2panda") { "runtime_core:libarktsbytecodeopt_package", "runtime_core:libarktscompiler_package", "runtime_core:libarktsfile_package", + "runtime_core:libarktsabc2program_package", sdk_libc_secshared_dep, ] + if (!(ark_standalone_build || ark_static_standalone_build)) { + external_deps += [ + "runtime_core:assembler_headers", + "runtime_core:bytecode_optimizer_headers", + "runtime_core:libpandabase_headers", + "runtime_core:libpandafile_headers", + "runtime_core:runtime_gen_headers", + "runtime_core:runtime_headers", + "runtime_core:compiler_headers", + "runtime_core:verification_headers", + ] + } + if (defined(ohos_indep_compiler_enable) && ohos_indep_compiler_enable) { external_deps += [ "icu:shared_icuuc" ] } diff --git a/ets2panda/aot/CMakeLists.txt b/ets2panda/aot/CMakeLists.txt index 5da24a781ac5ae19b637f3d8eb2023e9c670a584..b0fccc82c774b5423d550b2f69c6c8f5bb94e75f 100644 --- a/ets2panda/aot/CMakeLists.txt +++ b/ets2panda/aot/CMakeLists.txt @@ -15,7 +15,7 @@ set(ES2PANDA_AOT_SRC main.cpp ) -panda_add_executable(es2panda ${ES2PANDA_AOT_SRC}) +panda_frontend_add_executable(es2panda ${ES2PANDA_AOT_SRC}) panda_target_link_libraries(es2panda es2panda-public es2panda-lib arkassembler arkbytecodeopt) panda_target_include_directories(es2panda PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) panda_target_include_directories(es2panda PRIVATE ${OUTPUT_DIR}) diff --git a/ets2panda/aot/main.cpp b/ets2panda/aot/main.cpp index face618ccbbcf2bd1ccc1d567dfbebd1be7b9f0b..420240cb0ee8c3f829f32ba08e3e68afa017d0f0 100644 --- a/ets2panda/aot/main.cpp +++ b/ets2panda/aot/main.cpp @@ -24,12 +24,14 @@ #include "util/generateBin.h" #include "util/options.h" #include "util/plugin.h" +#include "util/perfMetrics.h" #include "libpandabase/os/stacktrace.h" #include "generated/diagnostic.h" #include #include #include + namespace ark::es2panda::aot { using mem::MemConfig; @@ -76,6 +78,38 @@ static int CompileFromSource(es2panda::Compiler &compiler, es2panda::SourceFile }); } +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 ReleaseInputsAndReturn(std::vector &parserInputs, unsigned int returnCode) +{ + for (auto *input : parserInputs) { + delete input; + } + parserInputs.clear(); + return returnCode; +} + static int CompileFromConfig(es2panda::Compiler &compiler, util::Options *options, util::DiagnosticEngine &diagnosticEngine) { @@ -85,31 +119,39 @@ static int CompileFromConfig(es2panda::Compiler &compiler, util::Options *option return 1; } - unsigned overallRes = 0; + std::vector inputs {}; + std::vector parserInputs; + 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(); + parserInputs.push_back(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, *parserInputs.back(), options->IsModule(), std::string_view(dst)); + inputs.push_back(input); + } + if (options->IsPermArena() && (options->GetExtension() == util::gen::extension::ETS)) { + return ReleaseInputsAndReturn(parserInputs, 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; + return ReleaseInputsAndReturn(parserInputs, overallRes); } static std::optional> InitializePlugins(std::vector const &names, @@ -134,6 +176,7 @@ static int Run(Span args) auto diagnosticEngine = util::DiagnosticEngine(); auto options = std::make_unique(args[0], diagnosticEngine); if (!options->Parse(args)) { + diagnosticEngine.FlushDiagnostic(); return 1; } diagnosticEngine.SetWError(options->IsEtsWarningsWerror()); @@ -144,6 +187,7 @@ static int Run(Span args) auto pluginsOpt = InitializePlugins(options->GetPlugins(), diagnosticEngine); if (!pluginsOpt.has_value()) { + diagnosticEngine.FlushDiagnostic(); return 1; } @@ -151,25 +195,32 @@ static int Run(Span args) if (options->IsListPhases()) { std::cerr << "Available phases:" << std::endl; std::cerr << compiler.GetPhasesList(); + diagnosticEngine.FlushDiagnostic(); return 1; } + int res; if (options->GetCompilationMode() == CompilationMode::PROJECT) { - return CompileFromConfig(compiler, options.get(), diagnosticEngine); - } - - std::string sourceFile; - std::string_view parserInput; - if (options->GetCompilationMode() == CompilationMode::GEN_STD_LIB) { - sourceFile = "etsstdlib.ets"; - parserInput = ""; + res = CompileFromConfig(compiler, options.get(), diagnosticEngine); } else { - sourceFile = options->SourceFileName(); - auto [buf, size] = options->CStrParserInputContents(); - parserInput = std::string_view(buf, size); + std::string sourceFile; + std::string_view parserInput; + if (options->GetCompilationMode() == CompilationMode::GEN_STD_LIB) { + sourceFile = "etsstdlib.ets"; + parserInput = ""; + } else { + sourceFile = options->SourceFileName(); + auto [buf, size] = options->CStrParserInputContents(); + parserInput = std::string_view(buf, size); + } + es2panda::SourceFile input(sourceFile, parserInput, options->IsModule(), options->GetOutput()); + res = CompileFromSource(compiler, input, *options.get(), diagnosticEngine); + } + if (options->IsDumpPerfMetrics()) { + util::DumpPerfMetrics(); } - es2panda::SourceFile input(sourceFile, parserInput, options->IsModule()); - return CompileFromSource(compiler, input, *options.get(), diagnosticEngine); + diagnosticEngine.FlushDiagnostic(); + return res; } } // namespace ark::es2panda::aot diff --git a/ets2panda/ast_verifier/ASTVerifier.cpp b/ets2panda/ast_verifier/ASTVerifier.cpp index 9854161341dad190e547fec914f090536c2a9f5e..e55eaac5bb4bfcf16edb00c06b1de418aba183b4 100644 --- a/ets2panda/ast_verifier/ASTVerifier.cpp +++ b/ets2panda/ast_verifier/ASTVerifier.cpp @@ -80,7 +80,7 @@ static auto ExtractAst(const parser::Program &program, bool checkFullProgram) return astToCheck; } -void ASTVerifier::Verify(std::string_view phaseName) +void ASTVerifier::Verify(std::string_view phaseName) noexcept { if (context_.diagnosticEngine->IsAnyError()) { // NOTE(dkofanov): As for now, the policy is that ASTVerifier doesn't interrupt pipeline if there were errors diff --git a/ets2panda/ast_verifier/ASTVerifier.h b/ets2panda/ast_verifier/ASTVerifier.h index 9aaa1aecc3e55d08feea243f73b2f6329e0b46f7..edd854d180e676902b83c79a880c711717515d54 100644 --- a/ets2panda/ast_verifier/ASTVerifier.h +++ b/ets2panda/ast_verifier/ASTVerifier.h @@ -91,24 +91,34 @@ public: for (size_t i = 0; i < VerifierInvariants::COUNT; i++) { enabled_[i] = TreatAsWarning(VerifierInvariants {i}) || TreatAsError(VerifierInvariants {i}); } - if (Options().IsAstVerifierBeforePhases()) { - Verify("before"); - } } ~ASTVerifier() { - if (!suppressed_) { - if (Options().IsAstVerifierAfterPhases()) { - Verify("after"); - } - if (HasErrors() || HasWarnings()) { - DumpMessages(); - } + ES2PANDA_ASSERT(!HasErrors()); + ES2PANDA_ASSERT(!HasWarnings()); + } + + void After() + { + if (Options().IsAstVerifierAfterPhases()) { + Verify("after"); + } + if (!suppressed_ && (HasErrors() || HasWarnings())) { + DumpMessages(); + hasErrors_ = false; + hasWarnings_ = false; + } + } + + void Before() + { + if (Options().IsAstVerifierBeforePhases()) { + Verify("before"); } } - void Verify(std::string_view phaseName); + void Verify(std::string_view phaseName) noexcept; void IntroduceNewInvariants(std::string_view occurredPhaseName) { @@ -129,7 +139,8 @@ public: i <= VerifierInvariants::AFTER_CHECKER_PHASE_LAST; i++) { allowed_[i] = true; } - // NOTE(dkofanov): This should be called after "NumberLowering" phase: + } + if (occurredPhaseName == "Unbox") { Get()->SetNumberLoweringOccured(); } if (occurredPhaseName == "UnionLowering") { diff --git a/ets2panda/ast_verifier/README.md b/ets2panda/ast_verifier/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9c4948a299621ec888c4df76c773b84c6937807d --- /dev/null +++ b/ets2panda/ast_verifier/README.md @@ -0,0 +1,94 @@ +# ASTVerifier + +The `ASTVerifier` is a class that checks whether specific invariants hold over an Abstract Syntax Tree (AST) from a source code perspective. For `es2panda` users, it provides a set of configurable checks that can be controlled through CLI options. + +## (Some of) Currently Implemented Checks + +- [ ] For every node, each child has its `Parent()` pointer correctly set to that node +- [ ] (By the time of lowerings) Every typed node has a valid `TsType` +- [ ] Every identifier has a non-null `Variable()` reference +- [ ] All `LocalVariables` referred to by identifiers have scopes that properly enclose those identifiers +- [ ] No visibility rules are violated +- [ ] Scopes are properly nested +- [ ] Operands of arithmetic expressions have numeric types (except for `+` operator on strings) +- [ ] In `forIn`, `forOf`, and `forUpdate` statements: + - The `left_` field is either an expression or a single variable declaration + - In `forUpdate`, the variable has an initializer + - In `forIn` and `forOf`, the variable has no initializer +- [ ] In sequence expressions, the type of the expression matches the type of its last member + +## CLI Options + +For complete and up-to-date options, run `es2panda --help`. + +### Usage Examples + +```sh +# Run verifier after each phase +es2panda --ast-verifier:each +``` +Note: +- `before` runs only after parsing +- `after` runs only after all lowerings +- `each` runs after each phase + +```sh +# Customize warning/error behavior +es2panda --ast-verifier:warnings=NodeHasParent:errors=ArithmeticOperationsValid,NodeHasType,NoPrimitiveTypes +``` + +## Adding a New Invariant + +### Invariant Design Principles + +An invariant should: +- Match patterns in AST subtrees that will be processed +- Explicitly handle exceptions by skipping non-matching subtrees +- Determine subtree correctness and report errors when needed + +An invariant should not: +- Iterate over the AST or apply itself recursively (this would slow down verification as all invariants run in parallel) +- Call other invariants directly + - If invariant `A` depends on invariant `B`: + - Explicitly mark the dependency + - `B` should execute first and prepare required data + - Example: `NoPrimitiveType` depends on `NodeHasType`, so `NodeHasType` executes first and provides type information + +### Implementation Steps + +1. **Register the invariant**: + - Add to `VerifierInvariants` enum in `util/options.yaml` + - This generates the corresponding C++ enum entry + +2. **Implement the check class**: + - Location: `/ets2panda/ast_verifier/invariants` + - Structure: + ```cpp + class SomeCheck : public InvariantBase { + public: + using Base::Base; + [[nodiscard]] CheckResult operator()(const ir::AstNode *ast) {...} + }; + ``` + - Naming convention: Use descriptive names (e.g., `VariableInitialized` for variable initialization checks) + +3. **Add documentation**: + - Describe the expected condition + - Specify when the check becomes relevant (which phase) + - Control execution timing via `ASTVerifier::IntroduceNewInvariants(phaseName)` in `ASTVerifier.h` + - Indicate whether it applies to: + - Main program only + - External sources as well + +4. **Error handling**: + - Use `AddCheckMessage` for error reporting + - Return `CheckResult` tuples: + - `CheckDecision::CORRECT` for passing analysis + - `CheckDecision::INCORRECT` for failures + - `CheckAction::CONTINUE` to proceed to children (in `ForAll` mode) + - `CheckAction::SKIP_SUBTREE` to skip subtree processing + +5. **Best practices**: + - Use descriptive error messages + - Study existing checks for implementation patterns + - Maintain clear separation of concerns between invariants diff --git a/ets2panda/ast_verifier/helpers.cpp b/ets2panda/ast_verifier/helpers.cpp index 13d55e496cb3a1ff72fa56415462b0b8b08664a9..a2179fc411ba0b24db631a82db400ba318fc1b32 100644 --- a/ets2panda/ast_verifier/helpers.cpp +++ b/ets2panda/ast_verifier/helpers.cpp @@ -19,6 +19,7 @@ #include "checker/types/type.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsUnionType.h" +#include "checker/types/gradualType.h" #include "ir/statements/blockStatement.h" #include "ir/ets/etsModule.h" #include "parser/program/program.h" @@ -50,18 +51,17 @@ bool IsBooleanType(const ir::AstNode *ast) } auto typedAst = static_cast(ast); - if (typedAst->TsType() == nullptr) { return false; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); + auto type = + typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); + if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { + return type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); } - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BOOLEAN_LIKE); + return type->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) || type->HasTypeFlag(checker::TypeFlag::BOOLEAN_LIKE); } bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) @@ -75,30 +75,29 @@ bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) } auto typedAst = static_cast(ast); - if (typedAst->TsType() == nullptr) { return false; } + auto type = + typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); if (IsBooleanType(ast)) { return isBitwise; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BIGINT)) { + if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BIGINT)) { return true; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE) && - !typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); + if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { + return type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE) && + !type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); } - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::NUMBER_LITERAL) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT) || - typedAst->TsType()->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL); + return type->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || + type->HasTypeFlag(checker::TypeFlag::NUMBER_LITERAL) || type->HasTypeFlag(checker::TypeFlag::BIGINT) || + type->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL); } bool IsStringType(const ir::AstNode *ast) @@ -112,17 +111,18 @@ bool IsStringType(const ir::AstNode *ast) } auto typedAst = static_cast(ast); - if (typedAst->TsType() == nullptr) { return false; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { - return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::STRING) || - typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_STRING); + auto type = + typedAst->TsType()->IsGradualType() ? typedAst->TsType()->AsGradualType()->GetBaseType() : typedAst->TsType(); + if (type->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { + return type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::STRING) || + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_STRING); } - return typedAst->TsType()->HasTypeFlag(checker::TypeFlag::STRING_LIKE); + return type->HasTypeFlag(checker::TypeFlag::STRING_LIKE); } bool IsVisibleInternalNode(const ir::AstNode *ast, const ir::AstNode *objTypeDeclNode) @@ -156,7 +156,8 @@ const checker::Type *GetClassDefinitionType(const ir::AstNode *ast) return nullptr; } auto *classDefinition = tmpNode->AsClassDefinition(); - return classDefinition->TsType(); + return classDefinition->TsType()->IsGradualType() ? classDefinition->TsType()->AsGradualType()->GetBaseType() + : classDefinition->TsType(); } const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) @@ -169,7 +170,9 @@ const checker::Type *GetTSInterfaceDeclarationType(const ir::AstNode *ast) return nullptr; } auto *tsInterfaceDeclaration = tmpNode->AsTSInterfaceDeclaration(); - return tsInterfaceDeclaration->TsType(); + return tsInterfaceDeclaration->TsType()->IsGradualType() + ? tsInterfaceDeclaration->TsType()->AsGradualType()->GetBaseType() + : tsInterfaceDeclaration->TsType(); } bool ValidateMethodAccessForClass(const ir::AstNode *ast, const ir::AstNode *ownerSignDeclNode, @@ -325,8 +328,8 @@ bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir } if (memberObjType->HasObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER) && memberObjType->SuperType() != nullptr && - memberObjType->SuperType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | - checker::ETSObjectFlags::GLOBAL)) { + memberObjType->SuperType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE | + checker::ETSObjectFlags::GLOBAL)) { return true; } const auto *memberObjTypeDeclNode = memberObjType->GetDeclNode(); diff --git a/ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp b/ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp index 7761dc5a5e0f5a427bff91e95fcbe23bf8b46089..468ba99a4ca3665e723dda4ea9e3bcbba7ebc96f 100644 --- a/ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp +++ b/ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp @@ -32,7 +32,7 @@ CheckResult EveryChildHasValidParent::operator()(const ir::AstNode *ast) auto overloads = maybeBaseOverloadMethod->Overloads(); auto res = std::find_if(overloads.begin(), overloads.end(), [node](ir::MethodDefinition *m) { return m == node; }); - return res != overloads.end(); + return res != overloads.end() || maybeBaseOverloadMethod->AsyncPairMethod() == node; } return false; }; diff --git a/ets2panda/ast_verifier/invariants/identifierHasVariable.cpp b/ets2panda/ast_verifier/invariants/identifierHasVariable.cpp index 930ac3249abec15f18214163607aa72b5c6a036b..10042ab5850ec5998e00bb0a90ea580d5ba03d09 100644 --- a/ets2panda/ast_verifier/invariants/identifierHasVariable.cpp +++ b/ets2panda/ast_verifier/invariants/identifierHasVariable.cpp @@ -17,6 +17,7 @@ #include "ir/base/scriptFunction.h" #include "ir/expressions/memberExpression.h" #include "ir/ts/tsEnumDeclaration.h" +#include "checker/types/ets/etsAnyType.h" namespace ark::es2panda::compiler::ast_verifier { @@ -25,8 +26,8 @@ public: ExceptionsMatcher(const IdentifierHasVariable *inv, const ir::Identifier *ast) : inv_(inv), ast_(ast) {} bool Match() { - auto res = IsLengthProp() || IsEmptyName() || IsInObjectExpr() || IsInPackageDecl() || IsUtilityType() || - IsUnionMemberAccess() || IsFixedArrayType(); + auto res = IsLengthProp() || IsAnyProp() || IsEmptyName() || IsInObjectExpr() || IsInPackageDecl() || + IsBuiltinType() || IsUnionMemberAccess(); return res; } @@ -36,6 +37,13 @@ private: return ast_->Parent() != nullptr && ast_->Parent()->IsMemberExpression() && ast_->Name().Is("length"); } + bool IsAnyProp() + { + return ast_->Parent() != nullptr && ast_->Parent()->IsMemberExpression() && + ast_->Parent()->AsMemberExpression()->Object()->TsType()->IsETSAnyType() && + ast_->Parent()->AsMemberExpression()->Object()->TsType()->AsETSAnyType()->IsRelaxed(); + } + bool IsEmptyName() { // NOTE(kkonkuznetsov): some identifiers have empty names @@ -69,16 +77,14 @@ private: return false; } - bool IsUtilityType() + bool IsBuiltinType() { + auto name = ast_->Name(); // NOTE(mmartin): find a better solution to handle utility type resolution - return ast_->Name().Is(Signatures::PARTIAL_TYPE_NAME) || ast_->Name().Is(Signatures::REQUIRED_TYPE_NAME) || - ast_->Name().Is(Signatures::READONLY_TYPE_NAME); - } - - bool IsFixedArrayType() - { - return ast_->Name().Is(Signatures::FIXED_ARRAY_TYPE_NAME); + return name.Is(Signatures::PARTIAL_TYPE_NAME) || name.Is(Signatures::REQUIRED_TYPE_NAME) || + name.Is(Signatures::READONLY_TYPE_NAME) || name.Is(Signatures::FIXED_ARRAY_TYPE_NAME) || + name.Is(compiler::Signatures::ANY_TYPE_NAME) || name.Is(Signatures::ANY) || + name.Is(compiler::Signatures::AWAITED_TYPE_NAME); } bool IsUnionMemberAccess() diff --git a/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp b/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp index 035796aacc0dc71c58a79f2413b8091a14a5231d..4832d10fb7b4853f971cc7314a5d4132f76e1953 100644 --- a/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp +++ b/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp @@ -70,7 +70,7 @@ bool ImportExportAccessValid::ValidateExport(const varbinder::Variable *var) if (node == nullptr) { return false; } - return node->IsExported() || node->IsExportedType(); + return node->IsExported() || node->HasExportAlias(); } bool ImportExportAccessValid::InvariantImportExportMethod(const std::unordered_set &importedVariables, @@ -78,13 +78,6 @@ bool ImportExportAccessValid::InvariantImportExportMethod(const std::unordered_s const ir::AstNode *callExpr, util::StringView name) { auto *signature = callExpr->AsCallExpression()->Signature(); - if (signature == nullptr || signature->Owner() == nullptr) { - // NOTE(vpukhov): Add a synthetic owner for dynamic signatures - ES2PANDA_ASSERT( - callExpr->AsCallExpression()->Callee()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG)); - return true; - } - if (signature != nullptr && varCallee->Declaration() != nullptr && varCallee->Declaration()->Node() != nullptr && !IsContainedIn(varCallee->Declaration()->Node(), signature->Owner()->GetDeclNode()) && varCallee->Declaration()->Node() != signature->Owner()->GetDeclNode()) { diff --git a/ets2panda/ast_verifier/invariants/nodeHasType.cpp b/ets2panda/ast_verifier/invariants/nodeHasType.cpp index 4a57eda031014279d77fb35958bb4df766e93824..a269292f9f5a330eba313720803c4c29fe209b32 100644 --- a/ets2panda/ast_verifier/invariants/nodeHasType.cpp +++ b/ets2panda/ast_verifier/invariants/nodeHasType.cpp @@ -38,7 +38,8 @@ public: { return nulltypeNode_->IsIdentifier() || MatchFunctionExpression() || nulltypeNode_->IsTSClassImplements() || nulltypeNode_->IsSpreadElement() || nulltypeNode_->IsTSThisType() || nulltypeNode_->IsETSNullType() || - nulltypeNode_->IsStringLiteral() || AnyChildStringLiteral(); + nulltypeNode_->IsStringLiteral() || AnyChildStringLiteral() || nulltypeNode_->IsOverloadDeclaration() || + nulltypeNode_->IsProperty(); } auto ShouldSkipSubtree() const diff --git a/ets2panda/ast_verifier/invariants/nodeHasType.h b/ets2panda/ast_verifier/invariants/nodeHasType.h index 12e7eaf4e6b12063468326eba03f866100c717ab..c48d97ce8095479c72c9335c9ee02d918353aac1 100644 --- a/ets2panda/ast_verifier/invariants/nodeHasType.h +++ b/ets2panda/ast_verifier/invariants/nodeHasType.h @@ -49,7 +49,8 @@ public: if (type == nullptr) { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - if (!numberLoweringOccurred_ && type->IsETSPrimitiveType()) { + // NOTE(dkofanov): Broken extension functions. + if (!numberLoweringOccurred_ && !type->IsETSExtensionFuncHelperType() && type->IsETSPrimitiveType()) { AddCheckMessage("PRIMITIVE_BEFORE_LOWERING", *ast); return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; } diff --git a/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp index f5ab1a349bd5e344270b7177c0e5dddc76234b01..3b82e3e138bba29c4e11b0e3ebd3587a7b810a76 100644 --- a/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp +++ b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp @@ -32,7 +32,7 @@ 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() || + if (variableNode->IsExported() || variableNode->IsDefaultExported() || variableNode->HasExportAlias() || id->Name().Utf8().find("field") == 0 || variable->Name().Utf8().find("field") == 0) { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } diff --git a/ets2panda/bindings/.prettierignore b/ets2panda/bindings/.prettierignore index 2f3613c27765c7087fcd45acc3d317ba0611d214..518efe7433cc5e17dcbee89e3c68635376e48411 100644 --- a/ets2panda/bindings/.prettierignore +++ b/ets2panda/bindings/.prettierignore @@ -17,7 +17,9 @@ native/ dist/** dist-test/** node_modules/** -**.json +test/ets/** +tsconfig.json +**.json5 **.js **.md **.ets diff --git a/ets2panda/bindings/BUILD.gn b/ets2panda/bindings/BUILD.gn index e6dbc5c5f4c3b2c6b686a994dcb23a4d4493a693..79e0c7eddf0965caefa92343a1ead8b17c3f3c2a 100644 --- a/ets2panda/bindings/BUILD.gn +++ b/ets2panda/bindings/BUILD.gn @@ -11,7 +11,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/runtime_core/static_core/ark_config.gni") +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + import("//arkcompiler/runtime_core/static_core/ark_config.gni") +} else { + import( + "//build/config/components/runtime_core/static_core/ark_common_config.gni") +} + if (ark_standalone_build) { import("$build_root/ark.gni") } else { @@ -22,25 +29,27 @@ npm_path = "//prebuilts/build-tools/common/nodejs/current/bin/npm" shared_library("ts_bindings") { sources = [ - "./native/src/callback-resource.cpp", "./native/src/common-interop.cpp", "./native/src/convertors-napi.cpp", "./native/src/lsp.cpp", ] + if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + configs += [ "$ark_root:ark_config" ] + } else { + configs += [ + "//build/config/components/runtime_core/static_core:ark_common_config", + ] + } configs += [ "$ark_root/assembler:arkassembler_public_config", - "$ark_root:ark_config", "../:libes2panda_public_config", "../:libes2panda_config", "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", + "$ark_root/libarkfile:arkfile_public_config", ] - deps = [ - "../:libes2panda_frontend_static", - "../:libes2panda_public_frontend_static", - "../lsp:libes2panda_lsp_static", - ] + deps = [ "../lsp:libes2panda_lsp_static" ] include_dirs = [ "./native/include", @@ -51,7 +60,8 @@ shared_library("ts_bindings") { if (ark_standalone_build) { deps += [ - "$ark_root/bytecode_optimizer:libarktsbytecodeopt_package", + "$ark_root/bytecode_optimizer:libarktsbytecodeopt_frontend_static", + "$ark_root/abc2program:arkts_abc2program_static", "$ark_third_party_root/bounds_checking_function:libsec_shared", ] include_dirs += [ "//third_party/node/src" ] @@ -184,7 +194,6 @@ shared_library("ts_bindings") { 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", @@ -195,7 +204,7 @@ shared_library("public") { "../:libes2panda_public_config", "../:libes2panda_config", "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", + "$ark_root/libarkfile:arkfile_public_config", ] include_dirs = [ @@ -339,24 +348,33 @@ action("build_bindings") { ":ts_bindings", ] sources = [ - "./src/Es2pandaNativeModule.ts", - "./src/InteropNativeModule.ts", - "./src/InteropTypes.ts", - "./src/Platform.ts", - "./src/Wrapper.ts", - "./src/arrays.ts", - "./src/generated/Es2pandaEnums.ts", - "./src/generated/Es2pandaNativeModule.ts", - "./src/global.ts", - "./src/index.ts", - "./src/loadLibraries.ts", - "./src/lspNode.ts", - "./src/mainWrapper.ts", - "./src/private.ts", - "./src/strings.ts", - "./src/ts-reflection.ts", - "./src/types.ts", - "./src/utils.ts", + "src/common/Es2pandaNativeModule.ts", + "src/common/InteropNativeModule.ts", + "src/common/InteropTypes.ts", + "src/common/Platform.ts", + "src/common/Wrapper.ts", + "src/common/arrays.ts", + "src/common/driver_helper.ts", + "src/common/global.ts", + "src/common/loadLibraries.ts", + "src/common/mainWrapper.ts", + "src/common/preDefine.ts", + "src/common/private.ts", + "src/common/strings.ts", + "src/common/ts-reflection.ts", + "src/common/types.ts", + "src/common/ui_plugins_driver.ts", + "src/common/utils.ts", + "src/common/arkTSConfigGenerator.ts", + "src/generated/Es2pandaEnums.ts", + "src/generated/Es2pandaNativeModule.ts", + "src/index.ts", + "src/lsp/compile_thread_worker.ts", + "src/lsp/generateArkTSConfig.ts", + "src/lsp/generateBuildConfig.ts", + "src/lsp/index.ts", + "src/lsp/lspNode.ts", + "src/lsp/lsp_helper.ts", ] script = "build_bindings.py" diff --git a/ets2panda/bindings/native/CMakeLists.txt b/ets2panda/bindings/native/CMakeLists.txt index 60dcbb51deb07e07eb70997d893412ccc8075766..f16a26ba64d8ea4285b6f9232b7b9fe4ab909ec9 100644 --- a/ets2panda/bindings/native/CMakeLists.txt +++ b/ets2panda/bindings/native/CMakeLists.txt @@ -27,7 +27,7 @@ function(panda_add_node_library TARGET) set(ARG_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/bindings) endif() - panda_add_library(${TARGET} SHARED ${ARG_SOURCES}) + panda_frontend_add_library(${TARGET} SHARED ${ARG_SOURCES}) panda_target_link_libraries(${TARGET} ${ARG_LIBRARIES}) if(PANDA_TARGET_OHOS) @@ -67,15 +67,12 @@ set(NAPI_BINDINGS_LIB "ts_bindings") set(BINDINGS_NAPI_SRC ./src/common-interop.cpp ./src/convertors-napi.cpp - ./src/callback-resource.cpp ./src/lsp.cpp ) # PUBLIC arkbase es2panda-lib es2panda-public # PRIVATE arkbytecodeopt set(ES2PANDA_LIBS - es2panda-lib - es2panda-public es2panda_lsp ) @@ -99,6 +96,8 @@ panda_add_node_library(${NAPI_BINDINGS_LIB} OUTPUT_SUFFIX ".node" ) +add_dependencies(frontend_bins ${NAPI_BINDINGS_LIB}) + panda_target_include_directories(${NAPI_BINDINGS_LIB} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include SYSTEM PRIVATE ${NAPI_HEADERS_PATH} diff --git a/ets2panda/bindings/native/include/common-interop.h b/ets2panda/bindings/native/include/common-interop.h index 6f6ed61b60fb6cec9c527b86a7144e1d63500873..62509078e1a936431907983838e9222ecd2d3b65 100644 --- a/ets2panda/bindings/native/include/common-interop.h +++ b/ets2panda/bindings/native/include/common-interop.h @@ -20,11 +20,15 @@ #include "panda_types.h" -// NOLINTBEGIN +// NOLINTBEGIN(cppcoreguidelines-macro-usage) +// CC-OFFNXT(G.PRE.02) code gen #define TS_INTEROP_PROFILER 0 +// CC-OFFNXT(G.PRE.02) code gen #define TS_INTEROP_TRACER 0 +// NOLINTEND(cppcoreguidelines-macro-usage) + #if TS_INTEROP_PROFILER #include "profiler.h" // CC-OFFNXT(G.PRE.09) code gen @@ -45,8 +49,8 @@ #define TS_MAYBE_LOG(name) #endif -typedef void (*CallbackCallert)(KInt callbackKind, KByte *argsData, KInt argsLength); -typedef void (*CallbackCallerSynct)(KVMContext vmContext, KInt callbackKind, KByte *argsData, KInt argsLength); +using CallbackCallert = void (*)(KInt callbackKind, KByte *argsData, KInt argsLength); +using CallbackCallerSynct = void (*)(KVMContext vmContext, KInt callbackKind, KByte *argsData, KInt argsLength); void SetCallbackCaller(CallbackCallert caller); void SetCallbackCallerSync(CallbackCallerSynct callerSync); @@ -55,10 +59,8 @@ KVMDeferred *CreateDeferred(KVMContext context, KVMObjectHandle *promise); // CC-OFFNXT(G.NAM.01) false positive std::vector MakeStringVector(KStringArray strArray); // CC-OFFNXT(G.NAM.01) false positive -std::vector MakeStringVector(KNativePointerArray arr, KInt size); +std::vector MakeStringVector(KNativePointerArray arr, KInt length); #include "convertors-napi.h" -// NOLINTEND - #endif // COMMON_INTEROP_BASE_H diff --git a/ets2panda/bindings/native/include/convertors-napi.h b/ets2panda/bindings/native/include/convertors-napi.h index 053f2d9834bfabf785daad6b5994cfc5e4b81798..73e2f8682a6faf693ec543475393ddfcf60b6771 100644 --- a/ets2panda/bindings/native/include/convertors-napi.h +++ b/ets2panda/bindings/native/include/convertors-napi.h @@ -16,9 +16,12 @@ #ifndef CONVERTORS_NAPI_H_ #define CONVERTORS_NAPI_H_ +#include #include #include #include +#include +#include #ifndef TS_NAPI_OHOS #include @@ -28,69 +31,69 @@ #endif #include "panda_types.h" -// NOLINTBEGIN template struct InteropTypeConverter { using InteropType = T; - static T convertFrom([[maybe_unused]] napi_env env, InteropType value) + static T ConvertFrom([[maybe_unused]] napi_env env, InteropType value) { return value; } - static InteropType convertTo([[maybe_unused]] napi_env env, T value) + static InteropType ConvertTo([[maybe_unused]] napi_env env, T value) { return value; } - static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] T converted) + static void Release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] T converted) { } }; template -inline typename InteropTypeConverter::InteropType makeResult(napi_env env, Type value) +inline typename InteropTypeConverter::InteropType MakeResult(napi_env env, Type value) { - return InteropTypeConverter::convertTo(env, value); + return InteropTypeConverter::ConvertTo(env, value); } template -inline Type getArgument(napi_env env, typename InteropTypeConverter::InteropType arg) +inline Type GetArgument(napi_env env, typename InteropTypeConverter::InteropType arg) { - return InteropTypeConverter::convertFrom(env, arg); + return InteropTypeConverter::ConvertFrom(env, arg); } template -inline void releaseArgument(napi_env env, typename InteropTypeConverter::InteropType arg, Type data) +inline void ReleaseArgument(napi_env env, typename InteropTypeConverter::InteropType arg, Type data) { - InteropTypeConverter::release(env, arg, data); + InteropTypeConverter::Release(env, arg, data); } template <> struct InteropTypeConverter { using InteropType = napi_value; - static KInteropBuffer convertFrom(napi_env env, InteropType value) + static KInteropBuffer ConvertFrom(napi_env env, InteropType value) { auto placeholder = 0; KInteropBuffer result = {placeholder, nullptr, 0, nullptr}; bool isArrayBuffer = false; napi_is_arraybuffer(env, value, &isArrayBuffer); if (isArrayBuffer) { - napi_get_arraybuffer_info(env, value, &result.data, (size_t *)&result.length); + napi_get_arraybuffer_info(env, value, &result.data, reinterpret_cast(&result.length)); } else { bool isDataView = false; napi_is_dataview(env, value, &isDataView); if (isDataView) { - napi_get_dataview_info(env, value, (size_t *)&result.length, &result.data, nullptr, nullptr); + napi_get_dataview_info(env, value, reinterpret_cast(&result.length), &result.data, nullptr, + nullptr); } } return result; } - static InteropType convertTo(napi_env env, KInteropBuffer value) + static InteropType ConvertTo(napi_env env, KInteropBuffer value) { - KInteropBuffer *copy = new KInteropBuffer(value); + auto *copy = new KInteropBuffer(value); napi_value result; napi_status status = napi_create_external_arraybuffer( env, value.data, value.length, - []([[maybe_unused]] napi_env env_, [[maybe_unused]] void *finalize_data, void *finalize_hint) { - KInteropBuffer *buffer = reinterpret_cast(finalize_hint); + []([[maybe_unused]] napi_env envArg, [[maybe_unused]] void *finalizeData, void *finalizeHint) { + auto *buffer = reinterpret_cast(finalizeHint); buffer->dispose(buffer->resourceId); delete buffer; }, @@ -100,7 +103,7 @@ struct InteropTypeConverter { } return result; }; - static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, + static void Release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] KInteropBuffer converted) { } @@ -109,26 +112,28 @@ struct InteropTypeConverter { template <> struct InteropTypeConverter { using InteropType = napi_value; - static KStringPtr convertFrom(napi_env env, InteropType value) + static KStringPtr ConvertFrom(napi_env env, InteropType value) { - if (value == nullptr) + if (value == nullptr) { return KStringPtr(); + } KStringPtr result; size_t length = 0; napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &length); - if (status != 0) + if (status != 0) { return result; - result.resize(length); - napi_get_value_string_utf8(env, value, result.data(), length + 1, nullptr); + } + result.Resize(length); + napi_get_value_string_utf8(env, value, result.Data(), length + 1, nullptr); return result; } - static InteropType convertTo(napi_env env, const KStringPtr &value) + static InteropType ConvertTo(napi_env env, const KStringPtr &value) { napi_value result; - napi_create_string_utf8(env, value.c_str(), value.length(), &result); + napi_create_string_utf8(env, value.CStr(), value.Length(), &result); return result; } - static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, + static void Release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] const KStringPtr &converted) { } @@ -137,19 +142,19 @@ struct InteropTypeConverter { template <> struct InteropTypeConverter { using InteropType = napi_value; - static KInteropNumber convertFrom(napi_env env, InteropType interopValue) + static KInteropNumber ConvertFrom(napi_env env, InteropType interopValue) { double value = 0.0; napi_get_value_double(env, interopValue, &value); - return KInteropNumber::fromDouble(value); + return KInteropNumber::FromDouble(value); } - static InteropType convertTo(napi_env env, KInteropNumber value) + static InteropType ConvertTo(napi_env env, KInteropNumber value) { napi_value result; - napi_create_double(env, value.asDouble(), &result); + napi_create_double(env, value.AsDouble(), &result); return result; } - static void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, + static void Release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] KInteropNumber converted) { } @@ -158,15 +163,15 @@ struct InteropTypeConverter { template <> struct InteropTypeConverter { using InteropType = napi_value; - static inline KVMObjectHandle convertFrom([[maybe_unused]] napi_env env, InteropType value) + static inline KVMObjectHandle ConvertFrom([[maybe_unused]] napi_env env, InteropType value) { return reinterpret_cast(value); } - static InteropType convertTo([[maybe_unused]] napi_env env, KVMObjectHandle value) + static InteropType ConvertTo([[maybe_unused]] napi_env env, KVMObjectHandle value) { return reinterpret_cast(value); } - static inline void release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, + static inline void Release([[maybe_unused]] napi_env env, [[maybe_unused]] InteropType value, [[maybe_unused]] KVMObjectHandle converted) { } @@ -175,26 +180,28 @@ struct InteropTypeConverter { template <> struct InteropTypeConverter { using InteropType = napi_value; - static inline KInteropReturnBuffer convertFrom(napi_env env, InteropType value) = delete; - static void disposer([[maybe_unused]] napi_env env, [[maybe_unused]] void *data, void *hint) + static inline KInteropReturnBuffer ConvertFrom(napi_env env, InteropType value) = delete; + static void Disposer([[maybe_unused]] napi_env env, [[maybe_unused]] void *data, void *hint) { - KInteropReturnBuffer *bufferCopy = (KInteropReturnBuffer *)hint; + auto *bufferCopy = static_cast(hint); bufferCopy->dispose(bufferCopy->data, bufferCopy->length); delete bufferCopy; } - static InteropType convertTo(napi_env env, KInteropReturnBuffer value) + static InteropType ConvertTo(napi_env env, KInteropReturnBuffer value) { napi_value result = nullptr; napi_value arrayBuffer = nullptr; auto clone = new KInteropReturnBuffer(); *clone = value; - napi_create_external_arraybuffer(env, value.data, value.length, disposer, clone, &arrayBuffer); + napi_create_external_arraybuffer(env, value.data, value.length, Disposer, clone, &arrayBuffer); napi_create_typedarray(env, napi_uint8_array, value.length, arrayBuffer, 0, &result); return result; } - static inline void release(napi_env env, InteropType value, const KInteropReturnBuffer &converted) = delete; + static inline void Release(napi_env env, InteropType value, const KInteropReturnBuffer &converted) = delete; }; +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + #define TS_INTEROP_THROW(vmcontext, object, ...) \ do { \ napi_env env = (napi_env)vmcontext; \ @@ -214,15 +221,15 @@ struct InteropTypeConverter { } while (0) // CC-OFFNXT(G.PRE.02-CPP) code generation -#define NAPI_ASSERT_INDEX(info, index, result) \ - do { \ - /* CC-OFFNXT(G.PRE.02) name part*/ \ - if (static_cast(index) >= info.Length()) { \ - /* CC-OFFNXT(G.PRE.02) name part*/ \ - napi_throw_error(info.Env(), nullptr, "No such element"); \ - /* CC-OFFNXT(G.PRE.05) function gen */ \ - return result; \ - } \ +#define NAPI_ASSERT_INDEX(info, index, result) \ + do { \ + /* CC-OFFNXT(G.PRE.02) name part*/ \ + if ((static_cast(index)) >= (info).Length()) { \ + /* CC-OFFNXT(G.PRE.02) name part*/ \ + napi_throw_error((info).Env(), nullptr, "No such element"); \ + /* CC-OFFNXT(G.PRE.05) function gen */ \ + return result; \ + } \ } while (0) // Helpers from node-addon-api @@ -245,16 +252,19 @@ struct InteropTypeConverter { return; \ } +// NOLINTEND(cppcoreguidelines-macro-usage) + class CallbackInfo { public: - CallbackInfo(napi_env env, napi_callback_info info) : _env(env) + CallbackInfo(napi_env env, napi_callback_info info) : env_(env) { size_t size = 0; napi_status status = napi_get_cb_info(env, info, &size, nullptr, nullptr, nullptr); TS_NAPI_THROW_IF_FAILED_VOID(env, status); if (size > 0) { - args.resize(size); // NOTE(khil): statically allocate small array for common case with few arguments passed - status = napi_get_cb_info(env, info, &size, args.data(), nullptr, nullptr); + args_.resize( + size); // NOTE(khil): statically allocate small array for common case with few arguments passed + status = napi_get_cb_info(env, info, &size, args_.data(), nullptr, nullptr); TS_NAPI_THROW_IF_FAILED_VOID(env, status); } } @@ -263,91 +273,91 @@ public: { if (idx >= Length()) { napi_value result; - napi_get_undefined(_env, &result); + napi_get_undefined(env_, &result); return result; } - return args[idx]; + return args_[idx]; } napi_env Env() const { - return _env; + return env_; } size_t Length() const { - return args.size(); + return args_.size(); } private: - napi_env _env; + napi_env env_; // napi_callback_info _info; - std::vector args; + std::vector args_; }; template -inline napi_typedarray_type getNapiType() = delete; +inline napi_typedarray_type GetNapiType() = delete; template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_float32_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_int8_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_uint8_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_int16_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_uint16_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_int32_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_uint32_array; } template <> -inline napi_typedarray_type getNapiType() +inline napi_typedarray_type GetNapiType() { return napi_biguint64_array; } -napi_valuetype getValueTypeChecked(napi_env env, napi_value value); -bool isTypedArray(napi_env env, napi_value value); +napi_valuetype GetValueTypeChecked(napi_env env, napi_value value); +bool IsTypedArray(napi_env env, napi_value value); template // CC-OFFNXT(G.FUD.06) solid logic, ODR -inline ElemType *getTypedElements(napi_env env, napi_value value) +inline ElemType *GetTypedElements(napi_env env, napi_value value) { - napi_valuetype valueType = getValueTypeChecked(env, value); + napi_valuetype valueType = GetValueTypeChecked(env, value); if (valueType == napi_null) { return nullptr; } - if (!isTypedArray(env, value)) { + if (!IsTypedArray(env, value)) { napi_throw_error(env, nullptr, "Expected TypedArray"); return nullptr; } @@ -358,8 +368,8 @@ inline ElemType *getTypedElements(napi_env env, napi_value value) napi_typedarray_type type; napi_status status = napi_get_typedarray_info(env, value, &type, &byteLength, &data, &arrayBuffer, &byteOffset); TS_NAPI_THROW_IF_FAILED(env, status, nullptr); - if (type != getNapiType()) { - printf("Array type mismatch. Expected %d got %d\n", getNapiType(), type); + if (type != GetNapiType()) { + std::cout << "Array type mismatch. Expected " << GetNapiType() << " got " << type << std::endl; napi_throw_error(env, nullptr, "Array type mismatch"); return nullptr; } @@ -367,155 +377,156 @@ inline ElemType *getTypedElements(napi_env env, napi_value value) } template -inline ElemType *getTypedElements(const CallbackInfo &info, int index) +inline ElemType *GetTypedElements(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, nullptr); - return getTypedElements(info.Env(), info[index]); + return GetTypedElements(info.Env(), info[index]); } -inline uint8_t *getUInt8Elements(const CallbackInfo &info, int index) +inline uint8_t *GetUInt8Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline int8_t *getInt8Elements(const CallbackInfo &info, int index) +inline int8_t *GetInt8Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline uint16_t *getUInt16Elements(const CallbackInfo &info, int index) +inline uint16_t *GetUInt16Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline int16_t *getInt16Elements(const CallbackInfo &info, int index) +inline int16_t *GetInt16Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline uint32_t *getUInt32Elements(const CallbackInfo &info, int index) +inline uint32_t *GetUInt32Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline uint32_t *getUInt32Elements(napi_env env, napi_value value) +inline uint32_t *GetUInt32Elements(napi_env env, napi_value value) { - return getTypedElements(env, value); + return GetTypedElements(env, value); } -inline int32_t *getInt32Elements(const CallbackInfo &info, int index) +inline int32_t *GetInt32Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline float *getFloat32Elements(const CallbackInfo &info, int index) +inline float *GetFloat32Elements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -inline KNativePointer *getPointerElements(const CallbackInfo &info, int index) +inline KNativePointer *GetPointerElements(const CallbackInfo &info, int index) { - return getTypedElements(info, index); + return GetTypedElements(info, index); } -KInt getInt32(napi_env env, napi_value value); -inline int32_t getInt32(const CallbackInfo &info, int index) +KInt GetInt32(napi_env env, napi_value value); +inline int32_t GetInt32(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, 0); - return getInt32(info.Env(), info[index]); + return GetInt32(info.Env(), info[index]); } -KUInt getUInt32(napi_env env, napi_value value); -inline uint32_t getUInt32(const CallbackInfo &info, int index) +KUInt GetUInt32(napi_env env, napi_value value); +inline uint32_t GetUInt32(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, 0); - return getUInt32(info.Env(), info[index]); + return GetUInt32(info.Env(), info[index]); } -KFloat getFloat32(napi_env env, napi_value value); -inline float getFloat32(const CallbackInfo &info, int index) +KFloat GetFloat32(napi_env env, napi_value value); +inline float GetFloat32(const CallbackInfo &info, int index) { - NAPI_ASSERT_INDEX(info, index, 0.0f); - return getFloat32(info.Env(), info[index]); + NAPI_ASSERT_INDEX(info, index, 0.0F); + return GetFloat32(info.Env(), info[index]); } -KDouble getFloat64(napi_env env, napi_value value); -inline KDouble getFloat64(const CallbackInfo &info, int index) +KDouble GetFloat64(napi_env env, napi_value value); +inline KDouble GetFloat64(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, 0.0); - return getFloat64(info.Env(), info[index]); + return GetFloat64(info.Env(), info[index]); } -KStringPtr getString(napi_env env, napi_value value); -inline KStringPtr getString(const CallbackInfo &info, int index) +KStringPtr GetString(napi_env env, napi_value value); +inline KStringPtr GetString(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, KStringPtr()); - return getString(info.Env(), info[index]); + return GetString(info.Env(), info[index]); } -void *getPointer(napi_env env, napi_value value); -inline void *getPointer(const CallbackInfo &info, int index) +void *GetPointer(napi_env env, napi_value value); +inline void *GetPointer(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, nullptr); - return getPointer(info.Env(), info[index]); + return GetPointer(info.Env(), info[index]); } -KLong getInt64(napi_env env, napi_value value); -inline KLong getInt64(const CallbackInfo &info, int index) +KLong GetInt64(napi_env env, napi_value value); +inline KLong GetInt64(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, 0); - return getInt64(info.Env(), info[index]); + return GetInt64(info.Env(), info[index]); } -KBoolean getBoolean(napi_env env, napi_value value); -inline KBoolean getBoolean(const CallbackInfo &info, int index) +KBoolean GetBoolean(napi_env env, napi_value value); +inline KBoolean GetBoolean(const CallbackInfo &info, int index) { NAPI_ASSERT_INDEX(info, index, false); - return getBoolean(info.Env(), info[index]); + return GetBoolean(info.Env(), info[index]); } template -inline Type getArgument(const CallbackInfo &info, int index) = delete; +inline Type GetArgument(const CallbackInfo &info, int index) = delete; template <> -inline KBoolean getArgument(const CallbackInfo &info, int index) +inline KBoolean GetArgument(const CallbackInfo &info, int index) { - return getBoolean(info, index); + return GetBoolean(info, index); } template <> -inline KUInt getArgument(const CallbackInfo &info, int index) +inline KUInt GetArgument(const CallbackInfo &info, int index) { - return getUInt32(info, index); + return GetUInt32(info, index); } template <> -inline KInt getArgument(const CallbackInfo &info, int index) +inline KInt GetArgument(const CallbackInfo &info, int index) { - return getInt32(info, index); + return GetInt32(info, index); } template <> -inline KInteropNumber getArgument(const CallbackInfo &info, int index) +inline KInteropNumber GetArgument(const CallbackInfo &info, int index) { - KInteropNumber res = {0, {0}}; + KInteropNumber res {}; NAPI_ASSERT_INDEX(info, index, res); - return getArgument(info.Env(), info[index]); + return GetArgument(info.Env(), info[index]); } template <> // CC-OFFNXT(G.FUD.06) solid logic, ODR -inline KLength getArgument(const CallbackInfo &info, int index) +inline KLength GetArgument(const CallbackInfo &info, int index) { - KLength result = {0, 0.0f, 0, 0}; + KLength result = {0, 0.0F, 0, 0}; NAPI_ASSERT_INDEX(info, index, result); auto value = info[index]; napi_valuetype type; - auto type_status = napi_typeof(info.Env(), value, &type); - if (type_status != 0) + auto typeStatus = napi_typeof(info.Env(), value, &type); + if (typeStatus != 0) { return result; + } switch (type) { case napi_number: { - result.value = getFloat32(info.Env(), value); + result.value = GetFloat32(info.Env(), value); result.unit = 1; result.type = 0; break; } case napi_string: { - KStringPtr string = getString(info.Env(), value); + KStringPtr string = GetString(info.Env(), value); ParseKLength(string, &result); result.type = 1; result.resource = 0; @@ -529,201 +540,204 @@ inline KLength getArgument(const CallbackInfo &info, int index) napi_status status = napi_get_named_property(info.Env(), value, "id", &field); if (status == 0) { status = napi_get_value_int32(info.Env(), field, &result.resource); - if (status != 0) + if (status != 0) { result.resource = 0; + } } else { result.resource = 0; } break; } default: - throw "Error, unexpected KLength type"; + throw std::runtime_error("Error, unexpected KLength type"); } return result; } template <> -inline KInteropBuffer getArgument(const CallbackInfo &info, int index) +inline KInteropBuffer GetArgument(const CallbackInfo &info, int index) { KInteropBuffer res = {0, nullptr, 0, nullptr}; NAPI_ASSERT_INDEX(info, index, res); - return getArgument((napi_env)info.Env(), (napi_value)info[index]); + return GetArgument((napi_env)info.Env(), (napi_value)info[index]); } template <> -inline KFloat getArgument(const CallbackInfo &info, int index) +inline KFloat GetArgument(const CallbackInfo &info, int index) { - return getFloat32(info, index); + return GetFloat32(info, index); } template <> -inline KDouble getArgument(const CallbackInfo &info, int index) +inline KDouble GetArgument(const CallbackInfo &info, int index) { - return getFloat64(info, index); + return GetFloat64(info, index); } template <> -inline KNativePointer getArgument(const CallbackInfo &info, int index) +inline KNativePointer GetArgument(const CallbackInfo &info, int index) { - return getPointer(info, index); + return GetPointer(info, index); } template <> -inline KLong getArgument(const CallbackInfo &info, int index) +inline KLong GetArgument(const CallbackInfo &info, int index) { - return getInt64(info, index); + return GetInt64(info, index); } template <> -inline KNativePointerArray getArgument(const CallbackInfo &info, int index) +inline KNativePointerArray GetArgument(const CallbackInfo &info, int index) { - return getPointerElements(info, index); + return GetPointerElements(info, index); } template <> -inline uint8_t *getArgument(const CallbackInfo &info, int index) +inline uint8_t *GetArgument(const CallbackInfo &info, int index) { - return getUInt8Elements(info, index); + return GetUInt8Elements(info, index); } template <> -inline const uint8_t *getArgument(const CallbackInfo &info, int index) +inline const uint8_t *GetArgument(const CallbackInfo &info, int index) { - return getUInt8Elements(info, index); + return GetUInt8Elements(info, index); } template <> -inline int8_t *getArgument(const CallbackInfo &info, int index) +inline int8_t *GetArgument(const CallbackInfo &info, int index) { - return getInt8Elements(info, index); + return GetInt8Elements(info, index); } template <> -inline int16_t *getArgument(const CallbackInfo &info, int index) +inline int16_t *GetArgument(const CallbackInfo &info, int index) { - return getInt16Elements(info, index); + return GetInt16Elements(info, index); } template <> -inline uint16_t *getArgument(const CallbackInfo &info, int index) +inline uint16_t *GetArgument(const CallbackInfo &info, int index) { - return getUInt16Elements(info, index); + return GetUInt16Elements(info, index); } template <> -inline int32_t *getArgument(const CallbackInfo &info, int index) +inline int32_t *GetArgument(const CallbackInfo &info, int index) { - return getInt32Elements(info, index); + return GetInt32Elements(info, index); } template <> -inline uint32_t *getArgument(const CallbackInfo &info, int index) +inline uint32_t *GetArgument(const CallbackInfo &info, int index) { - return getUInt32Elements(info, index); + return GetUInt32Elements(info, index); } template <> -inline float *getArgument(const CallbackInfo &info, int index) +inline float *GetArgument(const CallbackInfo &info, int index) { - return getFloat32Elements(info, index); + return GetFloat32Elements(info, index); } template <> -inline KStringPtr getArgument(const CallbackInfo &info, int index) +inline KStringPtr GetArgument(const CallbackInfo &info, int index) { - return getString(info, index); + return GetString(info, index); } -napi_value makeString(napi_env env, KStringPtr value); -napi_value makeString(napi_env env, const std::string &value); -napi_value makeBoolean(napi_env env, KBoolean value); -napi_value makeInt32(napi_env env, int32_t value); -napi_value makeUInt32(napi_env env, uint32_t value); -napi_value makeFloat32(napi_env env, float value); -napi_value makePointer(napi_env env, void *value); -napi_value makeVoid(napi_env env); +napi_value MakeString(napi_env env, KStringPtr value); +napi_value MakeString(napi_env env, const std::string &value); +napi_value MakeBoolean(napi_env env, KBoolean value); +napi_value MakeInt32(napi_env env, int32_t value); +napi_value MakeUInt32(napi_env env, uint32_t value); +napi_value MakeFloat32(napi_env env, float value); +napi_value MakePointer(napi_env env, void *value); +napi_value MakeVoid(napi_env env); -inline napi_value makeVoid(const CallbackInfo &info) +inline napi_value MakeVoid(const CallbackInfo &info) { - return makeVoid(info.Env()); + return MakeVoid(info.Env()); } template -inline napi_value makeResult(const CallbackInfo &info, Type value) = delete; +inline napi_value MakeResult(const CallbackInfo &info, Type value) = delete; template <> -inline napi_value makeResult(const CallbackInfo &info, KBoolean value) +inline napi_value MakeResult(const CallbackInfo &info, KBoolean value) { - return makeBoolean(info.Env(), value); + return MakeBoolean(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, int32_t value) +inline napi_value MakeResult(const CallbackInfo &info, int32_t value) { - return makeInt32(info.Env(), value); + return MakeInt32(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, uint32_t value) +inline napi_value MakeResult(const CallbackInfo &info, uint32_t value) { - return makeUInt32(info.Env(), value); + return MakeUInt32(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, float value) +inline napi_value MakeResult(const CallbackInfo &info, float value) { - return makeFloat32(info.Env(), value); + return MakeFloat32(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KNativePointer value) +inline napi_value MakeResult(const CallbackInfo &info, KNativePointer value) { - return makePointer(info.Env(), value); + return MakePointer(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KVMObjectHandle value) +inline napi_value MakeResult(const CallbackInfo &info, KVMObjectHandle value) { - return InteropTypeConverter::convertTo(info.Env(), value); + return InteropTypeConverter::ConvertTo(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KStringPtr value) +inline napi_value MakeResult(const CallbackInfo &info, KStringPtr value) { - return InteropTypeConverter::convertTo(info.Env(), value); + return InteropTypeConverter::ConvertTo(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KInteropBuffer value) +inline napi_value MakeResult(const CallbackInfo &info, KInteropBuffer value) { - return InteropTypeConverter::convertTo(info.Env(), value); + return InteropTypeConverter::ConvertTo(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KInteropReturnBuffer value) +inline napi_value MakeResult(const CallbackInfo &info, KInteropReturnBuffer value) { - return InteropTypeConverter::convertTo(info.Env(), value); + return InteropTypeConverter::ConvertTo(info.Env(), value); } template <> -inline napi_value makeResult(const CallbackInfo &info, KInteropNumber value) +inline napi_value MakeResult(const CallbackInfo &info, KInteropNumber value) { - return InteropTypeConverter::convertTo(info.Env(), value); + return InteropTypeConverter::ConvertTo(info.Env(), value); } -typedef napi_value (*napi_type_t)(napi_env, napi_callback_info); +using NapiTypeT = napi_value (*)(napi_env, napi_callback_info); class Exports { - std::unordered_map>> implementations; + std::unordered_map>> implementations_; public: - static Exports *getInstance(); + static Exports *GetInstance(); - std::vector getModules(); - void addMethod(const char *module, const char *name, napi_type_t impl); - const std::vector> &getMethods(const std::string &module); + std::vector GetModules(); + void addMethod(const char *module, const char *name, NapiTypeT impl); + const std::vector> &GetMethods(const std::string &module); }; +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + // CC-OFFNXT(G.DCL.01) false positive // CC-OFFNXT(G.NAM.01) false positive #define __QUOTE(x) #x @@ -732,13 +746,17 @@ public: #define MAKE_NODE_EXPORT(module, name) \ __attribute__((constructor)) static void __init_##name() \ { \ - Exports::getInstance()->addMethod(QUOTE(module), "_" #name, Node_##name); \ + Exports::GetInstance()->addMethod(QUOTE(module), "_" #name, Node_##name); \ } +// NOLINTEND(cppcoreguidelines-macro-usage) + #ifndef TS_INTEROP_MODULE #error TS_INTEROP_MODULE is undefined #endif +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + #define MAKE_INTEROP_NODE_EXPORT(name) MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) #define TS_INTEROP_0(name, Ret) \ @@ -747,7 +765,7 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name()); \ + return MakeResult(info, impl_##name()); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -756,9 +774,9 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ + P0 p0 = GetArgument(info, 0); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0)); \ + return MakeResult(info, impl_##name(p0)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -767,10 +785,10 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1)); \ + return MakeResult(info, impl_##name(p0, p1)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -780,11 +798,11 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2)); \ + return MakeResult(info, impl_##name(p0, p1, p2)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -794,12 +812,12 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -809,13 +827,13 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -825,14 +843,14 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -842,15 +860,15 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -860,16 +878,16 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -879,17 +897,17 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -899,18 +917,18 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -920,19 +938,19 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -942,20 +960,20 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -965,21 +983,21 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ - P12 p12 = getArgument(info, 12); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ + P12 p12 = GetArgument(info, 12); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -989,22 +1007,22 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ - P12 p12 = getArgument(info, 12); \ - P13 p13 = getArgument(info, 13); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ + P12 p12 = GetArgument(info, 12); \ + P13 p13 = GetArgument(info, 13); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ + return MakeResult(info, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1015,7 +1033,7 @@ public: CallbackInfo info(env, cbinfo); \ impl_##name(); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1024,10 +1042,10 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ + P0 p0 = GetArgument(info, 0); \ impl_##name(p0); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1037,11 +1055,11 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ impl_##name(p0, p1); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1051,12 +1069,12 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ impl_##name(p0, p1, p2); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1066,13 +1084,13 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ impl_##name(p0, p1, p2, p3); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1082,14 +1100,14 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ impl_##name(p0, p1, p2, p3, p4); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1099,15 +1117,15 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ impl_##name(p0, p1, p2, p3, p4, p5); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1117,16 +1135,16 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ impl_##name(p0, p1, p2, p3, p4, p5, p6); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1136,17 +1154,17 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1156,18 +1174,18 @@ public: { \ TS_MAYBE_LOG(impl_##name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1177,19 +1195,19 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1199,20 +1217,20 @@ public: { \ TS_MAYBE_LOG(impl_##name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1222,21 +1240,21 @@ public: { \ TS_MAYBE_LOG(impl_##name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1246,22 +1264,22 @@ public: { \ TS_MAYBE_LOG(impl_##name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ - P12 p12 = getArgument(info, 12); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ + P12 p12 = GetArgument(info, 12); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1271,23 +1289,23 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ - P12 p12 = getArgument(info, 12); \ - P13 p13 = getArgument(info, 13); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ + P12 p12 = GetArgument(info, 12); \ + P13 p13 = GetArgument(info, 13); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1297,24 +1315,24 @@ public: { \ TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ - P4 p4 = getArgument(info, 4); \ - P5 p5 = getArgument(info, 5); \ - P6 p6 = getArgument(info, 6); \ - P7 p7 = getArgument(info, 7); \ - P8 p8 = getArgument(info, 8); \ - P9 p9 = getArgument(info, 9); \ - P10 p10 = getArgument(info, 10); \ - P11 p11 = getArgument(info, 11); \ - P12 p12 = getArgument(info, 12); \ - P13 p13 = getArgument(info, 13); \ - P14 p14 = getArgument(info, 14); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ + P4 p4 = GetArgument(info, 4); \ + P5 p5 = GetArgument(info, 5); \ + P6 p6 = GetArgument(info, 6); \ + P7 p7 = GetArgument(info, 7); \ + P8 p8 = GetArgument(info, 8); \ + P9 p9 = GetArgument(info, 9); \ + P10 p10 = GetArgument(info, 10); \ + P11 p11 = GetArgument(info, 11); \ + P12 p12 = GetArgument(info, 12); \ + P13 p13 = GetArgument(info, 13); \ + P14 p14 = GetArgument(info, 14); \ impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1326,7 +1344,7 @@ public: CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(ctx)); \ + return MakeResult(info, impl_##name(ctx)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1337,9 +1355,9 @@ public: TS_MAYBE_LOG(impl_##name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ + P0 p0 = GetArgument(info, 0); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(ctx, p0)); \ + return MakeResult(info, impl_##name(ctx, p0)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1350,10 +1368,10 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(ctx, p0, p1)); \ + return MakeResult(info, impl_##name(ctx, p0, p1)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1364,11 +1382,11 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(ctx, p0, p1, p2)); \ + return MakeResult(info, impl_##name(ctx, p0, p1, p2)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1379,12 +1397,12 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ - P3 p3 = getArgument(info, 3); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ + P3 p3 = GetArgument(info, 3); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeResult(info, impl_##name(ctx, p0, p1, p2, p3)); \ + return MakeResult(info, impl_##name(ctx, p0, p1, p2, p3)); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1397,7 +1415,7 @@ public: KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ impl_##name(ctx); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1408,10 +1426,10 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ + P0 p0 = GetArgument(info, 0); \ impl_##name(ctx, p0); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1422,11 +1440,11 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ impl_##name(ctx, p0, p1); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1437,12 +1455,12 @@ public: TS_MAYBE_LOG(name) \ CallbackInfo info(env, cbinfo); \ KVMContext ctx = reinterpret_cast((napi_env)info.Env()); \ - P0 p0 = getArgument(info, 0); \ - P1 p1 = getArgument(info, 1); \ - P2 p2 = getArgument(info, 2); \ + P0 p0 = GetArgument(info, 0); \ + P1 p1 = GetArgument(info, 1); \ + P2 p2 = GetArgument(info, 2); \ impl_##name(ctx, p0, p1, p2); \ /* CC-OFFNXT(G.PRE.05) function gen */ \ - return makeVoid(info); \ + return MakeVoid(info); \ } \ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, name) @@ -1461,26 +1479,27 @@ public: } \ } while (0) -napi_value getKoalaNapiCallbackDispatcher(napi_env env); +napi_value GetKoalaNapiCallbackDispatcher(napi_env env); // CC-OFFNXT(G.PRE.06) solid logic #define TS_INTEROP_CALL_VOID(venv, id, length, args) \ { \ napi_env env = reinterpret_cast(venv); \ - napi_value bridge = getKoalaNapiCallbackDispatcher(env), global = nullptr, return_val = nullptr; \ + napi_value bridge = GetKoalaNapiCallbackDispatcher(env), global = nullptr, return_val = nullptr; \ napi_handle_scope scope = nullptr; \ napi_open_handle_scope(env, &scope); \ napi_status status = napi_get_global(env, &global); \ - napi_value node_args[3]; \ + std::array node_args; \ napi_create_int32(env, id, &node_args[0]); \ napi_value buffer = nullptr; \ napi_create_external_arraybuffer( \ env, args, length, [](napi_env, void *data, void *hint) {}, nullptr, &buffer); \ napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &node_args[1]); \ napi_create_int32(env, length, &node_args[2]); \ - status = napi_call_function(env, global, bridge, 3, node_args, &return_val); \ - if (status != napi_ok) \ + status = napi_call_function(env, global, bridge, 3, node_args.data(), &return_val); \ + if (status != napi_ok) { \ NODEJS_GET_AND_THROW_LAST_ERROR((env)); \ + } \ napi_close_handle_scope(env, scope); \ } @@ -1488,11 +1507,13 @@ napi_value getKoalaNapiCallbackDispatcher(napi_env env); #define TS_INTEROP_CALL_INT(venv, id, length, args) \ { \ napi_env env = reinterpret_cast(venv); \ - napi_value bridge = getKoalaNapiCallbackDispatcher(env), global = nullptr, return_val = nullptr; \ + napi_value bridge = GetKoalaNapiCallbackDispatcher(env); \ + napi_value global = nullptr; \ + napi_value return_val = nullptr; \ napi_handle_scope scope = nullptr; \ napi_open_handle_scope(env, &scope); \ napi_status status = napi_get_global(env, &global); \ - napi_value node_args[3]; \ + std::array node_args {}; \ napi_create_int32(env, id, &node_args[0]); \ napi_value buffer = nullptr; \ napi_create_external_arraybuffer( \ @@ -1500,9 +1521,10 @@ napi_value getKoalaNapiCallbackDispatcher(napi_env env); &buffer); \ napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &node_args[1]); \ napi_create_int32(env, length, &node_args[2]); \ - status = napi_call_function(env, global, bridge, 3, node_args, &return_val); \ - if (status != napi_ok) \ + status = napi_call_function(env, global, bridge, 3, node_args.data(), &return_val); \ + if (status != napi_ok) { \ NODEJS_GET_AND_THROW_LAST_ERROR((env)); \ + } \ int result; \ status = napi_get_value_int32(env, return_val, &result); \ napi_close_handle_scope(env, scope); \ @@ -1513,6 +1535,6 @@ napi_value getKoalaNapiCallbackDispatcher(napi_env env); #define TS_INTEROP_CALL_VOID_INTS32(venv, id, argc, args) TS_INTEROP_CALL_VOID(venv, id, (argc) * sizeof(int32_t), args) #define TS_INTEROP_CALL_INT_INTS32(venv, id, argc, args) TS_INTEROP_CALL_INT(venv, id, (argc) * sizeof(int32_t), args) -// NOLINTEND +// NOLINTEND(cppcoreguidelines-macro-usage) #endif // CONVERTORS_NAPI_H_ diff --git a/ets2panda/bindings/native/include/interop-logging.h b/ets2panda/bindings/native/include/interop-logging.h index b95a79146b2ff9a9b485fdd0e9dca3a793b6e32c..c31c90bdae2d62fde5b003f2ae24b8f1f62b0ca5 100644 --- a/ets2panda/bindings/native/include/interop-logging.h +++ b/ets2panda/bindings/native/include/interop-logging.h @@ -15,19 +15,29 @@ #ifndef INTEROP_LOGGING_H #define INTEROP_LOGGING_H -#include +#include #include -// NOLINTBEGIN +inline void Log(const char *msg) +{ + std::cout << msg << "\n"; +} -// CC-OFFNXT(G.PRE.09) code generation -#define LOG(msg) fprintf(stdout, msg "\n"); -// CC-OFFNXT(G.PRE.09) code generation -#define LOGI(msg, ...) fprintf(stdout, msg "\n", __VA_ARGS__); -// CC-OFFNXT(G.PRE.09) code generation -#define LOGE(msg, ...) fprintf(stderr, msg "\n", __VA_ARGS__); -// CC-OFFNXT(G.PRE.09) code generation -#define LOGE0(msg) fprintf(stderr, msg "\n"); +template +void LogI(Args &&...args) +{ + (std::cout << ... << args); + std::cout << "\n"; +} + +template +void LogE(Args &&...args) +{ + (std::cerr << ... << args); + std::cerr << "\n"; +} + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define LOG_PUBLIC "" #if defined(PANDA_TARGET_WINDOWS) @@ -36,6 +46,4 @@ #define INTEROP_API_EXPORT __attribute__((visibility("default"))) #endif -// NOLINTEND - #endif // INTEROP_LOGGING_H diff --git a/ets2panda/bindings/native/include/interop-types.h b/ets2panda/bindings/native/include/interop-types.h index 2f43a9af110d274c6c14e84dd126ffc8be76ce76..4a84e8e10873ffe67654d214624c1eccc512dac3 100644 --- a/ets2panda/bindings/native/include/interop-types.h +++ b/ets2panda/bindings/native/include/interop-types.h @@ -17,10 +17,9 @@ #define INTEROP_TYPES_H_ #include +#include -// NOLINTBEGIN - -typedef enum InteropTag { +enum InteropTag { INTEROP_TAG_UNDEFINED = 101, INTEROP_TAG_INT32 = 102, INTEROP_TAG_FLOAT32 = 103, @@ -28,9 +27,9 @@ typedef enum InteropTag { INTEROP_TAG_LENGTH = 105, INTEROP_TAG_RESOURCE = 106, INTEROP_TAG_OBJECT = 107, -} InteropTag; +}; -typedef enum InteropRuntimeType { +enum InteropRuntimeType { INTEROP_RUNTIME_UNEXPECTED = -1, INTEROP_RUNTIME_NUMBER = 1, INTEROP_RUNTIME_STRING = 2, @@ -41,103 +40,103 @@ typedef enum InteropRuntimeType { INTEROP_RUNTIME_FUNCTION = 7, INTEROP_RUNTIME_SYMBOL = 8, INTEROP_RUNTIME_MATERIALIZED = 9, -} InteropRuntimeType; - -typedef float InteropFloat32; -typedef double InteropFloat64; -typedef int32_t InteropInt32; -typedef unsigned int InteropUInt32; -typedef int64_t InteropInt64; -typedef int8_t InteropInt8; -typedef uint8_t InteropUInt8; -typedef int64_t InteropDate; -typedef int8_t InteropBoolean; -typedef const char *InteropCharPtr; -typedef void *InteropNativePointer; +}; + +using InteropFloat32 = float; +using InteropFloat64 = double; +using InteropInt32 = int32_t; +using InteropUInt32 = unsigned int; +using InteropInt64 = int64_t; +using InteropInt8 = int8_t; +using InteropUInt8 = uint8_t; +using InteropDate = int64_t; +using InteropBoolean = int8_t; +using InteropCharPtr = const char *; +using InteropNativePointer = void *; struct InteropVMContextRaw; -typedef struct InteropVMContextRaw *InteropVMContext; +using InteropVMContext = InteropVMContextRaw *; struct InteropPipelineContextRaw; -typedef struct InteropPipelineContextRaw *InteropPipelineContext; +using InteropPipelineContext = InteropPipelineContextRaw *; struct InteropVMObjectRaw; -typedef struct InteropVMObjectRaw *InteropVMObject; +using InteropVMObject = InteropVMObjectRaw *; struct InteropNode; -typedef struct InteropNode *InteropNodeHandle; -typedef struct InteropDeferred { +using InteropNodeHandle = InteropNode *; +struct InteropDeferred { void *handler; void *context; void (*resolve)(struct InteropDeferred *thiz, uint8_t *data, int32_t length); void (*reject)(struct InteropDeferred *thiz, const char *message); -} InteropDeferred; +}; // Binary layout of InteropString must match that of KStringPtrImpl. -typedef struct InteropString { +struct InteropString { const char *chars; InteropInt32 length; -} InteropString; +}; -typedef struct InteropEmpty { +struct InteropEmpty { InteropInt32 dummy; // Empty structs are forbidden in C. -} InteropEmpty; +}; -typedef struct InteropNumber { +struct InteropNumber { InteropInt8 tag; union { InteropFloat32 f32; InteropInt32 i32; }; -} InteropNumber; +}; // Binary layout of InteropLength must match that of KLength. -typedef struct InteropLength { +struct InteropLength { InteropInt8 type; InteropFloat32 value; InteropInt32 unit; InteropInt32 resource; -} InteropLength; +}; -typedef struct InteropCustomObject { - char kind[20]; +const int G_INTEROP_CUSTOM_OBJECT_KIND_SIZE = 20; +const int G_UNION_CAPACITY32 = 4; +struct InteropCustomObject { + std::array kind; InteropInt32 id; // Data of custom object. union { - InteropInt32 ints[4]; - InteropFloat32 floats[4]; - void *pointers[4]; + std::array ints; + std::array floats; + std::array pointers; InteropString string; }; -} InteropCustomObject; +}; -typedef struct InteropUndefined { +struct InteropUndefined { InteropInt32 dummy; // Empty structs are forbidden in C. -} InteropUndefined; +}; -typedef struct InteropVoid { +struct InteropVoid { InteropInt32 dummy; // Empty structs are forbidden in C. -} InteropVoid; +}; -typedef struct InteropFunction { +struct InteropFunction { InteropInt32 id; -} InteropFunction; -typedef InteropFunction InteropCallback; -typedef InteropFunction InteropErrorCallback; +}; +using InteropCallback = InteropFunction; +using InteropErrorCallback = InteropFunction; -typedef struct InteropMaterialized { +struct InteropMaterialized { InteropNativePointer ptr; -} InteropMaterialized; +}; -typedef struct InteropCallbackResource { +struct InteropCallbackResource { InteropInt32 resourceId; void (*hold)(InteropInt32 resourceId); void (*release)(InteropInt32 resourceId); -} InteropCallbackResource; +}; -typedef struct InteropBuffer { +struct InteropBuffer { InteropCallbackResource resource; InteropNativePointer data; InteropInt64 length; -} InteropBuffer; - -// NOLINTEND +}; #endif // INTEROP_TYPES_H_ diff --git a/ets2panda/bindings/native/include/panda_types.h b/ets2panda/bindings/native/include/panda_types.h index cc9c3e7579985d8e445495f60d66456c436bb383..d29f51c232b1a2f311df23449f378d9a876ff151 100644 --- a/ets2panda/bindings/native/include/panda_types.h +++ b/ets2panda/bindings/native/include/panda_types.h @@ -20,155 +20,178 @@ #include #include #include +#include #include "securec.h" -// NOLINTBEGIN +const unsigned int ARK_TAG_INT32 = 102U; +const unsigned int ARK_TAG_FLOAT32 = 103U; struct KStringPtrImpl { - KStringPtrImpl(const char *str) : value(nullptr), owned(true) + explicit KStringPtrImpl(const char *str) : value_(nullptr), lengthStr_(0), owned_(true) { - int len = str ? strlen(str) : 0; - assign(str, len); + int len = str != nullptr ? strlen(str) : 0; + Assign(str, len); } - KStringPtrImpl(const char *str, int len, bool isOwned) : value(nullptr), owned(isOwned) + KStringPtrImpl(const char *str, int len, bool isowned) : value_(nullptr), lengthStr_(0), owned_(isowned) { - assign(str, len); + Assign(str, len); } - KStringPtrImpl() : value(nullptr), lengthStr(0), owned(true) {} + KStringPtrImpl() : value_(nullptr), lengthStr_(0), owned_(true) {} KStringPtrImpl(const KStringPtrImpl &other) = delete; KStringPtrImpl &operator=(const KStringPtrImpl &other) = delete; KStringPtrImpl(KStringPtrImpl &&other) { - this->value = other.release(); - this->owned = other.owned; - other.owned = false; - this->lengthStr = other.lengthStr; + this->value_ = other.Release(); + this->owned_ = other.owned_; + other.owned_ = false; + this->lengthStr_ = other.lengthStr_; + } + KStringPtrImpl &operator=(KStringPtrImpl &&other) + { + this->value_ = other.Release(); + this->owned_ = other.owned_; + other.owned_ = false; + this->lengthStr_ = other.lengthStr_; + return *this; } ~KStringPtrImpl() { - if (value && owned) - free(value); + if (value_ != nullptr && owned_) { + delete[] value_; + } } - bool isNull() const + bool IsNull() const { - return value == nullptr; + return value_ == nullptr; } - const char *c_str() const + const char *CStr() const { - return value; + return value_; } - char *data() const + char *Data() const { - return value; + return value_; } - int length() const + int Length() const { - return lengthStr; + return lengthStr_; } - void resize(unsigned int size) + void Resize(unsigned int size) { - lengthStr = size; - if (!owned) + lengthStr_ = size; + if (!owned_) { return; + } // Ignore old content. - if (value && owned) - free(value); - value = reinterpret_cast(std::malloc(size + 1)); - if (value == nullptr) { + if (value_ != nullptr && owned_) { + delete[] value_; + } + value_ = new char[size + 1] {}; + if (value_ == nullptr) { // NOTE(khil): should be refactored to proper malloc return; } - value[size] = 0; } - void assign(const char *data) + void Assign(const char *data) { - assign(data, data ? strlen(data) : 0); + Assign(data, data != nullptr ? strlen(data) : 0); } - void assign(const char *data, unsigned int len) + void Assign(const char *data, unsigned int len) { - if (value && owned) - free(value); - if (data) { - if (owned) { - value = reinterpret_cast(std::malloc(len + 1)); - if (!value) { + if (value_ != nullptr && owned_) { + delete[] value_; + } + if (data != nullptr) { + if (owned_) { + value_ = new char[len + 1] {}; + if (value_ == nullptr) { return; } - memcpy_s(value, len, data, len); - value[len] = 0; + memcpy_s(value_, len, data, len); } else { - value = const_cast(data); + value_ = const_cast(data); } } else { - value = nullptr; + value_ = nullptr; } - lengthStr = len; + lengthStr_ = len; } protected: - char *release() + char *Release() { - char *result = this->value; - this->value = nullptr; + char *result = this->value_; + this->value_ = nullptr; return result; } private: - char *value; - int lengthStr; - bool owned; + char *value_; + // CC-OFFNXT(G.NAM.01) project code style + int lengthStr_; + bool owned_; }; struct KInteropNumber { - int8_t tag; - union { - int32_t i32; - float f32; - }; - static inline KInteropNumber fromDouble(double value) + KInteropNumber() : value_(0) {} + static inline KInteropNumber FromDouble(double value) { - KInteropNumber result = {0, {0}}; + KInteropNumber result {}; // NOTE(khil): boundary check if (value == std::floor(value)) { - result.tag = 102U; // ARK_TAG_INT32 - result.i32 = (int)value; + result.SetTag(ARK_TAG_INT32); + result.SetValue(static_cast(value)); } else { - result.tag = 103U; // ARK_TAG_FLOAT32 - result.f32 = (float)value; + result.SetTag(ARK_TAG_FLOAT32); + result.SetValue(static_cast(value)); } return result; } - inline double asDouble() + inline double AsDouble() { - if (tag == 102U) // ARK_TAG_INT32 - return (double)i32; - else - return (double)f32; + if (tag_ == ARK_TAG_INT32) { + return static_cast(std::get(value_)); + } + return static_cast(std::get(value_)); } + inline void SetTag(int8_t tag) + { + tag_ = tag; + } + template + void SetValue(T value) + { + value_ = value; + } + +private: + std::variant value_; + // CC-OFFNXT(G.NAM.01) project code style + int8_t tag_ {0}; }; -typedef int8_t KBoolean; -typedef uint8_t KByte; -typedef int16_t KChar; -typedef int16_t KShort; -typedef uint16_t KUShort; -typedef int32_t KInt; -typedef uint32_t KUInt; -typedef float KFloat; -typedef int64_t KLong; -typedef double KDouble; -typedef void *KNativePointer; -typedef KStringPtrImpl KStringPtr; -typedef float *KFloatArray; -typedef const uint8_t *KStringArray; -typedef void **KNativePointerArray; +using KBoolean = int8_t; +using KByte = uint8_t; +using KChar = int16_t; +using KShort = int16_t; +using KUShort = uint16_t; +using KInt = int32_t; +using KUInt = uint32_t; +using KFloat = float; +using KLong = int64_t; +using KDouble = double; +using KNativePointer = void *; +using KStringPtr = KStringPtrImpl; +using KFloatArray = float *; +using KStringArray = const uint8_t *; +using KNativePointerArray = void **; struct KInteropBuffer { KLong length; @@ -196,23 +219,26 @@ inline void ParseKLength(const KStringPtrImpl &string, KLength *result) { char *suffixPtr = nullptr; - float value = std::strtof(string.c_str(), &suffixPtr); + float value = std::strtof(string.CStr(), &suffixPtr); - if (!suffixPtr || suffixPtr == string.c_str()) { + if (suffixPtr == nullptr || suffixPtr == string.CStr()) { // not a numeric value result->unit = -1; return; } result->value = value; - if (suffixPtr[0] == '\0' || (suffixPtr[0] == 'v' && suffixPtr[1] == 'p')) { + const size_t cmpOneByte = 1; + const size_t cmpTwoByte = 2; + const size_t cmpThreeByte = 3; + if (std::strncmp(suffixPtr, "\0", 1) == 0 || std::strncmp(suffixPtr, "vp", cmpTwoByte) == 0) { result->unit = 1; - } else if (suffixPtr[0] == '%') { + } else if (std::strncmp(suffixPtr, "%", cmpOneByte) == 0) { result->unit = 3U; - } else if (suffixPtr[0] == 'p' && suffixPtr[1] == 'x') { + } else if (std::strncmp(suffixPtr, "px", cmpTwoByte) == 0) { result->unit = 0; - } else if (suffixPtr[0] == 'l' && suffixPtr[1] == 'p' && suffixPtr[2U] == 'x') { + } else if (std::strncmp(suffixPtr, "lpx", cmpThreeByte) == 0) { result->unit = 4U; - } else if (suffixPtr[0] == 'f' && suffixPtr[1] == 'p') { + } else if (std::strncmp(suffixPtr, "fp", cmpTwoByte) == 0) { result->unit = 2U; } else { result->unit = -1; @@ -220,27 +246,27 @@ inline void ParseKLength(const KStringPtrImpl &string, KLength *result) } struct KVMContextRaw; -typedef KVMContextRaw *KVMContext; +using KVMContext = KVMContextRaw *; // BEWARE: this MUST never be used in user code, only in very rare service code. struct KVMObjectRaw; -typedef KVMObjectRaw *KVMObjectHandle; +using KVMObjectHandle = KVMObjectRaw *; -typedef struct KVMDeferred { +struct KVMDeferred { void *handler; void *context; void (*resolve)(KVMDeferred *thiz, uint8_t *data, int32_t length); void (*reject)(KVMDeferred *thiz, const char *message); -} KVMDeferred; +}; template -T *ptr(KNativePointer ptr) +T *Ptr(KNativePointer ptr) { return reinterpret_cast(ptr); } template -T &ref(KNativePointer ptr) +T &Ref(KNativePointer ptr) { return *reinterpret_cast(ptr); } @@ -251,11 +277,9 @@ inline KNativePointer NativePtr(void *pointer) } template -KNativePointer fnPtr(void (*pointer)(T *)) +KNativePointer FnPtr(void (*pointer)(T *)) { return reinterpret_cast(pointer); } -// NOLINTEND - #endif /* TS_TYPES_H */ diff --git a/ets2panda/bindings/native/src/bridges.cpp b/ets2panda/bindings/native/src/bridges.cpp index 2757d4b9efc5081982efaa7c6d2959a303405bd9..e34e2dbb39086eaa6a4c61981b0c4a72263ba461 100644 --- a/ets2panda/bindings/native/src/bridges.cpp +++ b/ets2panda/bindings/native/src/bridges.cpp @@ -32,18 +32,27 @@ TS_INTEROP_1(ContextProgram, KNativePointer, KNativePointer) KNativePointer impl_CreateContextFromString(KNativePointer configPtr, KStringPtr &sourcePtr, KStringPtr &filenamePtr) { auto config = reinterpret_cast(configPtr); - return GetPublicImpl()->CreateContextFromString(config, sourcePtr.data(), filenamePtr.data()); + return GetPublicImpl()->CreateContextFromString(config, sourcePtr.Data(), filenamePtr.Data()); } TS_INTEROP_3(CreateContextFromString, KNativePointer, KNativePointer, KStringPtr, KStringPtr) +KNativePointer impl_CreateContextFromStringWithHistory(KNativePointer configPtr, KStringPtr &sourcePtr, + KStringPtr &filenamePtr) +{ + auto config = reinterpret_cast(configPtr); + return GetPublicImpl()->CreateContextFromStringWithHistory(config, sourcePtr.Data(), filenamePtr.Data()); +} +TS_INTEROP_3(CreateContextFromStringWithHistory, KNativePointer, KNativePointer, KStringPtr, KStringPtr) + KInt impl_GenerateTsDeclarationsFromContext(KNativePointer contextPtr, KStringPtr &outputDeclEts, KStringPtr &outputEts, - KBoolean exportAll) + KBoolean exportAll, KBoolean isolated, KStringPtr &recordFile) { auto context = reinterpret_cast(contextPtr); - return static_cast(GetPublicImpl()->GenerateTsDeclarationsFromContext(context, outputDeclEts.data(), - outputEts.data(), exportAll != 0)); + return static_cast(GetPublicImpl()->GenerateTsDeclarationsFromContext( + context, outputDeclEts.Data(), outputEts.Data(), exportAll != 0, isolated != 0, recordFile.Data())); } -TS_INTEROP_4(GenerateTsDeclarationsFromContext, KInt, KNativePointer, KStringPtr, KStringPtr, KBoolean) +TS_INTEROP_6(GenerateTsDeclarationsFromContext, KInt, KNativePointer, KStringPtr, KStringPtr, KBoolean, KBoolean, + KStringPtr) KNativePointer impl_CreateContextFromFile(KNativePointer configPtr, KStringPtr &filenamePtr) { @@ -66,3 +75,10 @@ KNativePointer impl_ContextErrorMessage(KNativePointer contextPtr) return new std::string(GetPublicImpl()->ContextErrorMessage(context)); } TS_INTEROP_1(ContextErrorMessage, KNativePointer, KNativePointer) + +KNativePointer impl_GetAllErrorMessages(KNativePointer contextPtr) +{ + auto context = reinterpret_cast(contextPtr); + return new std::string(GetPublicImpl()->GetAllErrorMessages(context)); +} +TS_INTEROP_1(GetAllErrorMessages, KNativePointer, KNativePointer) diff --git a/ets2panda/bindings/native/src/callback-resource.cpp b/ets2panda/bindings/native/src/callback-resource.cpp deleted file mode 100644 index d2664f17740563d0ab4b7a97309eeaca8bc9309a..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/native/src/callback-resource.cpp +++ /dev/null @@ -1,101 +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 "common-interop.h" -#include "callback-resource.h" -#include -#include -#include -#include - -// NOLINTBEGIN - -static bool needReleaseFront = false; -static std::deque callbackEventsQueue; -static std::deque callbackCallSubqueue; -static std::deque callbackResourceSubqueue; - -void EnqueueCallback(const CallbackBuffer *event) -{ - callbackEventsQueue.push_back(EVENT_CALL_CALLBACK); - callbackCallSubqueue.push_back(*event); -} - -void HoldManagedCallbackResource(InteropInt32 resourceId) -{ - callbackEventsQueue.push_back(EVENT_HOLD_MANAGED_RESOURCE); - callbackResourceSubqueue.push_back(resourceId); -} - -void ReleaseManagedCallbackResource(InteropInt32 resourceId) -{ - callbackEventsQueue.push_back(EVENT_RELEASE_MANAGED_RESOURCE); - callbackResourceSubqueue.push_back(resourceId); -} - -KInt impl_CheckCallbackEvent(KByte *result, [[maybe_unused]] KInt size) -{ - if (needReleaseFront) { - switch (callbackEventsQueue.front()) { - case EVENT_CALL_CALLBACK: - callbackCallSubqueue.front().resourceHolder.release(); - callbackCallSubqueue.pop_front(); - break; - case EVENT_HOLD_MANAGED_RESOURCE: - case EVENT_RELEASE_MANAGED_RESOURCE: - callbackResourceSubqueue.pop_front(); - break; - default: - throw std::runtime_error("Unknown event kind"); - } - callbackEventsQueue.pop_front(); - needReleaseFront = false; - } - if (callbackEventsQueue.empty()) { - return 0; - } - const CallbackEventKind frontEventKind = callbackEventsQueue.front(); - std::copy_n(&frontEventKind, 4U, result); - switch (frontEventKind) { - case EVENT_CALL_CALLBACK: - std::copy_n(callbackCallSubqueue.front().buffer, sizeof(CallbackBuffer::buffer), result + 4U); - break; - case EVENT_HOLD_MANAGED_RESOURCE: - case EVENT_RELEASE_MANAGED_RESOURCE: { - const InteropInt32 resourceId = callbackResourceSubqueue.front(); - std::copy_n(&resourceId, 4U, result + 4U); - break; - } - default: - throw std::runtime_error("Unknown event kind"); - } - needReleaseFront = true; - return 1; -} -TS_INTEROP_2(CheckCallbackEvent, KInt, KByte *, KInt) - -void impl_ReleaseCallbackResource(InteropInt32 resourceId) -{ - ReleaseManagedCallbackResource(resourceId); -} -TS_INTEROP_V1(ReleaseCallbackResource, KInt) - -void impl_HoldCallbackResource(InteropInt32 resourceId) -{ - HoldManagedCallbackResource(resourceId); -} -TS_INTEROP_V1(HoldCallbackResource, KInt) - -// NOLINTEND diff --git a/ets2panda/bindings/native/src/common-interop.cpp b/ets2panda/bindings/native/src/common-interop.cpp index fd418bbc797ebd3a5f428120598d26b59bccdd28..ad310140d77f40023f6af731582f5e8a62dfa95c 100644 --- a/ets2panda/bindings/native/src/common-interop.cpp +++ b/ets2panda/bindings/native/src/common-interop.cpp @@ -20,8 +20,6 @@ #include #include -// NOLINTBEGIN - #ifdef TS_INTEROP_MODULE #undef TS_INTEROP_MODULE #endif @@ -31,6 +29,7 @@ #include "convertors-napi.h" #include "common-interop.h" +// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) #if TS_INTEROP_PROFILER #include "profiler.h" @@ -43,34 +42,33 @@ using std::string; // Callback dispatcher MOVED to convertors-napi.cc. // Let's keep platform-specific parts of the code together -typedef void (*HoldT)(KInt); +using HoldT = void (*)(KInt); KInt impl_getTypeOfVariant(KNativePointer varPtr) { auto *var = reinterpret_cast *>(varPtr); if (std::get_if(var) != nullptr) { return 0; - } else { - return 1; } + return 1; } TS_INTEROP_1(getTypeOfVariant, KInt, KNativePointer) -KNativePointer impl_getStringFromVariant(KNativePointer varPtr) +KNativePointer impl_GetStringFromVariant(KNativePointer varPtr) { auto *var = reinterpret_cast *>(varPtr); auto *res = new std::string(*std::get_if(var)); return res; } -TS_INTEROP_1(getStringFromVariant, KNativePointer, KNativePointer) +TS_INTEROP_1(GetStringFromVariant, KNativePointer, KNativePointer) -KInt impl_getIntFromVariant(KNativePointer varPtr) +KInt impl_GetIntFromVariant(KNativePointer varPtr) { auto *var = reinterpret_cast *>(varPtr); auto res = *std::get_if(var); return res; } -TS_INTEROP_1(getIntFromVariant, KInt, KNativePointer) +TS_INTEROP_1(GetIntFromVariant, KInt, KNativePointer) KInteropBuffer impl_MaterializeBuffer(KNativePointer data, KLong length, KInt resourceId, KNativePointer holdPtr, KNativePointer releasePtr) @@ -106,25 +104,25 @@ TS_INTEROP_V3(StringData, KNativePointer, KByte *, KUInt) KNativePointer impl_StringMake(const KStringPtr &str) { - return new string(str.c_str()); + return new string(str.CStr()); } TS_INTEROP_1(StringMake, KNativePointer, KStringPtr) // For slow runtimes w/o fast encoders. KInt impl_ManagedStringWrite(const KStringPtr &str, KByte *buffer, KInt offset) { - memcpy_s(buffer + offset, str.length() + 1, str.c_str(), str.length() + 1); - return str.length() + 1; + memcpy_s(buffer + offset, str.Length() + 1, str.CStr(), str.Length() + 1); + return str.Length() + 1; } TS_INTEROP_3(ManagedStringWrite, KInt, KStringPtr, KByte *, KInt) -void stringFinalizer(string *ptr) +void StringFinalizer(string *ptr) { delete ptr; } KNativePointer impl_GetStringFinalizer() { - return fnPtr(stringFinalizer); + return FnPtr(StringFinalizer); } TS_INTEROP_0(GetStringFinalizer, KNativePointer) @@ -152,7 +150,11 @@ TS_INTEROP_2(GetPtrVectorElement, KNativePointer, KNativePointer, KInt) inline KUInt UnpackUInt(const KByte *bytes) { - return (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24)); + const KUInt oneByte = 8U; + const KUInt twoByte = 16U; + const KUInt threeByte = 24U; + return (static_cast(bytes[0]) | (static_cast(bytes[1]) << oneByte) | + (static_cast(bytes[2]) << twoByte) | (static_cast(bytes[3]) << threeByte)); } std::vector MakeStringVector(KStringArray strArray) @@ -165,7 +167,7 @@ std::vector MakeStringVector(KStringArray strArray) size_t offset = sizeof(KUInt); for (KUInt i = 0; i < arraySize; ++i) { int len = UnpackUInt(strArray + offset); - res[i].assign((const char *)(strArray + offset + sizeof(KUInt)), len); + res[i].Assign(reinterpret_cast(strArray + offset + sizeof(KUInt)), len); offset += len + sizeof(KUInt); } return res; @@ -175,25 +177,24 @@ std::vector MakeStringVector(KNativePointerArray arr, KInt length) { if (arr == nullptr) { return std::vector(0); - } else { - std::vector res(length); - char **strings = reinterpret_cast(arr); - for (KInt i = 0; i < length; ++i) { - const char *str = reinterpret_cast(strings[i]); - res[i].assign(str); - } - return res; } + std::vector res(length); + char **strings = reinterpret_cast(arr); + for (KInt i = 0; i < length; ++i) { + const char *str = reinterpret_cast(strings[i]); + res[i].Assign(str); + } + return res; } -typedef KInt (*LoadVirtualMachine_t)(KInt vmKind, const char *classPath, const char *libraryPath, +using LoadVirtualMachineT = KInt (*)(KInt vmKind, const char *classPath, const char *libraryPath, void *currentVMContext); -typedef KNativePointer (*StartApplication_t)(const char *appUrl, const char *appParams); -typedef KBoolean (*RunApplication_t)(const KInt arg0, const KInt arg1); -typedef void (*EmitEventT)(const KInt type, const KInt target, const KInt arg0, const KInt arg1); +using StartApplicationT = KNativePointer (*)(const char *appUrl, const char *appParams); +using RunApplicationT = KBoolean (*)(const KInt arg0, const KInt arg1); +using EmitEventT = void (*)(const KInt type, const KInt target, const KInt arg0, const KInt arg1); static CallbackCallert g_callbackCaller = nullptr; -void setCallbackCaller(CallbackCallert callbackCaller) +void SetCallbackCaller(CallbackCallert callbackCaller) { g_callbackCaller = callbackCaller; } @@ -207,14 +208,14 @@ void impl_CallCallback(KInt callbackKind, KByte *args, KInt argsSize) TS_INTEROP_V3(CallCallback, KInt, KByte *, KInt) static CallbackCallerSynct g_callbackCallerSync = nullptr; -void setCallbackCallerSync(CallbackCallerSynct callbackCallerSync) +void SetCallbackCallerSync(CallbackCallerSynct callbackCallerSync) { g_callbackCallerSync = callbackCallerSync; } void impl_CallCallbackSync(KVMContext vmContext, KInt callbackKind, KByte *args, KInt argsSize) { - if (g_callbackCallerSync) { + if (g_callbackCallerSync != nullptr) { g_callbackCallerSync(vmContext, callbackKind, args, argsSize); } } @@ -232,86 +233,93 @@ void impl_CallCallbackResourceReleaser(KNativePointer releaser, KInt resourceId) } TS_INTEROP_V2(CallCallbackResourceReleaser, KNativePointer, KInt) +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + // CC-OFFNXT(G.EXP.01) false positive #define __QUOTE(x) #x #define QUOTE(x) __QUOTE(x) +// NOLINTEND(cppcoreguidelines-macro-usage) + #ifndef INTEROP_LIBRARY_NAME #error "INTEROP_LIBRARY_NAME must be defined" #endif void impl_NativeLog(const KStringPtr &str) { - fprintf(stdout, "%s: %s\n", QUOTE(INTEROP_LIBRARY_NAME), str.c_str()); - fflush(stdout); + std::cout << QUOTE(INTEROP_LIBRARY_NAME) << ": " << str.CStr() << std::endl; } TS_INTEROP_V1(NativeLog, KStringPtr) -int32_t callCallback(KVMContext context, int32_t methodId, uint8_t *argsData, int32_t argsLength) +int32_t CallCallback(KVMContext context, int32_t methodId, uint8_t *argsData, int32_t argsLength) { TS_INTEROP_CALL_INT(context, methodId, argsLength, argsData); return 0; } -void resolveDeferred(KVMDeferred *deferred, [[maybe_unused]] uint8_t *argsData, [[maybe_unused]] int32_t argsLength) +void ResolveDeferred(KVMDeferred *deferred, [[maybe_unused]] uint8_t *argsData, [[maybe_unused]] int32_t argsLength) { - napi_acquire_threadsafe_function((napi_threadsafe_function)deferred->handler); - auto status = - napi_call_threadsafe_function((napi_threadsafe_function)deferred->handler, deferred, napi_tsfn_nonblocking); - if (status != napi_ok) - LOGE("cannot call thread-safe function; status=%d", status); - napi_release_threadsafe_function((napi_threadsafe_function)deferred->handler, napi_tsfn_release); + napi_acquire_threadsafe_function(static_cast(deferred->handler)); + auto status = napi_call_threadsafe_function(static_cast(deferred->handler), deferred, + napi_tsfn_nonblocking); + if (status != napi_ok) { + LogE("cannot call thread-safe function; status=", status); + } + napi_release_threadsafe_function(static_cast(deferred->handler), napi_tsfn_release); } -void rejectDeferred(KVMDeferred *deferred, [[maybe_unused]] const char *message) +void RejectDeferred(KVMDeferred *deferred, [[maybe_unused]] const char *message) { - napi_release_threadsafe_function((napi_threadsafe_function)deferred->handler, napi_tsfn_release); + napi_release_threadsafe_function(static_cast(deferred->handler), napi_tsfn_release); delete deferred; } -void resolveDeferredImpl(napi_env env, [[maybe_unused]] napi_value js_callback, KVMDeferred *deferred, +void ResolveDeferredImpl(napi_env env, [[maybe_unused]] napi_value jsCallback, KVMDeferred *deferred, [[maybe_unused]] void *data) { napi_value undefined = nullptr; napi_get_undefined(env, &undefined); - auto status = napi_resolve_deferred(env, (napi_deferred)deferred->context, undefined); - if (status != napi_ok) - LOGE("cannot resolve deferred; status=%d", status); + auto status = napi_resolve_deferred(env, reinterpret_cast(deferred->context), undefined); + if (status != napi_ok) { + LogE("cannot resolve deferred; status=", status); + } delete deferred; } -[[maybe_unused]] static void releaseDeferred(KVMDeferred *deferred) +[[maybe_unused]] static void ReleaseDeferred(KVMDeferred *deferred) { delete deferred; } KVMDeferred *CreateDeferred(KVMContext vmContext, KVMObjectHandle *promiseHandle) { - KVMDeferred *deferred = new KVMDeferred(); - deferred->resolve = resolveDeferred; - deferred->reject = rejectDeferred; + auto *deferred = new KVMDeferred(); + deferred->resolve = ResolveDeferred; + deferred->reject = RejectDeferred; // NOTE(khil): mb move\remove to interop! - napi_env env = (napi_env)vmContext; + auto env = reinterpret_cast(vmContext); napi_value promise; napi_value resourceName; size_t napiStrLen = 5; napi_create_string_utf8(env, "Async", napiStrLen, &resourceName); - auto status = napi_create_promise(env, (napi_deferred *)&deferred->context, &promise); - if (status != napi_ok) - LOGE("cannot make a promise; status=%d", status); + auto status = napi_create_promise(env, reinterpret_cast(&deferred->context), &promise); + if (status != napi_ok) { + LogE("cannot make a promise; status=", status); + } status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName, 0, 1, nullptr, nullptr, deferred, - (napi_threadsafe_function_call_js)resolveDeferredImpl, - (napi_threadsafe_function *)&deferred->handler); - if (status != napi_ok) - LOGE("cannot make threadsafe function; status=%d", status); - *promiseHandle = (KVMObjectHandle)promise; + reinterpret_cast(ResolveDeferredImpl), + reinterpret_cast(&deferred->handler)); + if (status != napi_ok) { + LogE("cannot make threadsafe function; status=", status); + } + *promiseHandle = reinterpret_cast(promise); return deferred; } // Allocate, so CTX versions. KStringPtr impl_Utf8ToString([[maybe_unused]] KVMContext vmContext, KByte *data, KInt offset, KInt length) { - KStringPtr result((const char *)(data + offset), length, false); + KStringPtr result(reinterpret_cast(data + offset), length, false); return result; } TS_INTEROP_CTX_3(Utf8ToString, KStringPtr, KByte *, KInt, KInt) @@ -328,9 +336,9 @@ KInteropReturnBuffer impl_RawReturnData([[maybe_unused]] KVMContext vmContext, K { void *data = new int8_t[v1]; memset_s(data, v2, v1, v2); - KInteropReturnBuffer buffer = {v1, data, [](KNativePointer ptr, KInt) { delete[](int8_t *) ptr; }}; + KInteropReturnBuffer buffer = {v1, data, + [](KNativePointer ptr, KInt) { delete[] reinterpret_cast(ptr); }}; return buffer; } TS_INTEROP_CTX_2(RawReturnData, KInteropReturnBuffer, KInt, KInt) - -// NOLINTEND +// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) diff --git a/ets2panda/bindings/native/src/common.cpp b/ets2panda/bindings/native/src/common.cpp index 78f051246e1ae3d1ab4313b6e2f5dc18a2581b35..7bb6087aba778164028dda4a82632651384f2e5a 100644 --- a/ets2panda/bindings/native/src/common.cpp +++ b/ets2panda/bindings/native/src/common.cpp @@ -19,11 +19,9 @@ #include "public/es2panda_lib.h" #include "dynamic-loader.h" -// NOLINTBEGIN - using std::string, std::cout, std::endl, std::vector; -static es2panda_Impl const *impl = nullptr; +static es2panda_Impl const *g_impl = nullptr; #ifdef _WIN32 #include @@ -43,19 +41,19 @@ static es2panda_Impl const *impl = nullptr; #define LIB_SUFFIX ".so" #endif -const char *LIB_ES2PANDA_PUBLIC = LIB_PREFIX "es2panda_public" LIB_SUFFIX; +const char *g_libES2PandaPublic = LIB_PREFIX "es2panda_public" LIB_SUFFIX; void *FindLibrary() { std::string libraryName; char *envValue = getenv("PANDA_SDK_PATH"); if (envValue) { - libraryName = string(envValue) + ("/" PLUGIN_DIR "/lib/") + LIB_ES2PANDA_PUBLIC; + libraryName = string(envValue) + ("/" PLUGIN_DIR "/lib/") + g_libES2PandaPublic; } else { - if (g_pandaLibPath == "") { - libraryName = LIB_ES2PANDA_PUBLIC; + if (g_pandaLibPath.empty()) { + libraryName = g_libES2PandaPublic; } else { - libraryName = g_pandaLibPath + "/" + LIB_ES2PANDA_PUBLIC; + libraryName = g_pandaLibPath + "/" + g_libES2PandaPublic; } } return LoadLibrary(libraryName); @@ -63,51 +61,57 @@ void *FindLibrary() const es2panda_Impl *GetPublicImpl() { - if (impl) { - return impl; + if (g_impl != nullptr) { + return g_impl; } auto library = FindLibrary(); - if (!library) { - std::cout << "Cannot find " << LIB_ES2PANDA_PUBLIC << endl; + if (library == nullptr) { + std::cout << "Cannot find " << g_libES2PandaPublic << endl; } auto symbol = FindSymbol(library, "es2panda_GetImpl"); - if (!symbol) { + if (symbol == nullptr) { std::cout << "Cannot find Impl Entry point" << endl; } - impl = reinterpret_cast(symbol)(ES2PANDA_LIB_VERSION); - return impl; + g_impl = reinterpret_cast(symbol)(ES2PANDA_LIB_VERSION); + return g_impl; } std::string GetString(KStringPtr ptr) { - return ptr.data(); + return ptr.Data(); } char *GetStringCopy(KStringPtr &ptr) { - return strdup(ptr.c_str()); + return strdup(ptr.CStr()); } inline KUInt UnpackUInt(const KByte *bytes) { - return (bytes[0] | (bytes[1] << 8U) | (bytes[2U] << 16U) | (bytes[3U] << 24U)); + const KUInt oneByte = 8U; + const KUInt twoByte = 16U; + const KUInt threeByte = 24U; + return (static_cast(bytes[0]) | (static_cast(bytes[1]) << oneByte) | + (static_cast(bytes[twoByte / oneByte]) << twoByte) | + (static_cast(bytes[threeByte / oneByte]) << threeByte)); } inline std::string_view GetStringView(KStringPtr &ptr) { - return std::string_view(ptr.c_str(), static_cast(ptr.length())); + return std::string_view(ptr.CStr(), static_cast(ptr.Length())); } KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr, KStringPtr &pandaLibPath) { - const std::size_t HEADER_LEN = 4; + const std::size_t headerLen = 4; g_pandaLibPath = GetStringView(pandaLibPath); + const char **argv = new const char *[static_cast(argc)]; - std::size_t position = HEADER_LEN; + std::size_t position = headerLen; std::size_t strLen; for (std::size_t i = 0; i < static_cast(argc); ++i) { strLen = UnpackUInt(argvPtr + position); - position += HEADER_LEN; + position += headerLen; argv[i] = strdup(std::string(reinterpret_cast(argvPtr + position), strLen).c_str()); position += strLen; } @@ -131,4 +135,78 @@ KNativePointer impl_DestroyContext(KNativePointer contextPtr) } TS_INTEROP_1(DestroyContext, KNativePointer, KNativePointer) -// NOLINTEND +void impl_MemInitialize(KStringPtr &pandaLibPath) +{ + g_pandaLibPath = GetStringView(pandaLibPath); + GetPublicImpl()->MemInitialize(); +} +TS_INTEROP_V1(MemInitialize, KStringPtr) + +void impl_MemFinalize() +{ + GetPublicImpl()->MemFinalize(); +} +TS_INTEROP_V0(MemFinalize) + +KNativePointer impl_CreateGlobalContext(KNativePointer configPtr, KStringArray externalFileListPtr, KInt fileNum) +{ + auto config = reinterpret_cast(configPtr); + + const std::size_t headerLen = 4; + if (fileNum <= 0) { + return nullptr; + } + const char **externalFileList = new const char *[fileNum]; + std::size_t position = headerLen; + std::size_t strLen; + for (std::size_t i = 0; i < static_cast(fileNum); ++i) { + strLen = UnpackUInt(externalFileListPtr + position); + position += headerLen; + externalFileList[i] = + strdup(std::string(reinterpret_cast(externalFileListPtr + position), strLen).c_str()); + position += strLen; + } + + return GetPublicImpl()->CreateGlobalContext(config, externalFileList, fileNum, true); +} +TS_INTEROP_3(CreateGlobalContext, KNativePointer, KNativePointer, KStringArray, KInt) + +void impl_DestroyGlobalContext(KNativePointer globalContextPtr) +{ + auto context = reinterpret_cast(globalContextPtr); + GetPublicImpl()->DestroyGlobalContext(context); +} +TS_INTEROP_V1(DestroyGlobalContext, KNativePointer) + +KNativePointer impl_CreateCacheContextFromString(KNativePointer configPtr, KStringPtr &sourcePtr, + KStringPtr &filenamePtr, KNativePointer globalContext, + KBoolean isExternal) +{ + auto config = reinterpret_cast(configPtr); + auto context = reinterpret_cast(globalContext); + return GetPublicImpl()->CreateCacheContextFromString(config, sourcePtr.Data(), filenamePtr.Data(), context, + isExternal); +} +TS_INTEROP_5(CreateCacheContextFromString, KNativePointer, KNativePointer, KStringPtr, KStringPtr, KNativePointer, + KBoolean) + +void impl_RemoveFileCache(KNativePointer globalContextPtr, KStringPtr &filenamePtr) +{ + auto context = reinterpret_cast(globalContextPtr); + return GetPublicImpl()->RemoveFileCache(context, filenamePtr.Data()); +} +TS_INTEROP_V2(RemoveFileCache, KNativePointer, KStringPtr) + +void impl_AddFileCache(KNativePointer globalContextPtr, KStringPtr &filenamePtr) +{ + auto context = reinterpret_cast(globalContextPtr); + return GetPublicImpl()->AddFileCache(context, filenamePtr.Data()); +} +TS_INTEROP_V2(AddFileCache, KNativePointer, KStringPtr) + +void impl_InvalidateFileCache(KNativePointer globalContextPtr, KStringPtr &filenamePtr) +{ + auto context = reinterpret_cast(globalContextPtr); + return GetPublicImpl()->InvalidateFileCache(context, filenamePtr.Data()); +} +TS_INTEROP_V2(InvalidateFileCache, KNativePointer, KStringPtr) diff --git a/ets2panda/bindings/native/src/convertors-napi.cpp b/ets2panda/bindings/native/src/convertors-napi.cpp index d2b553e787deb0f500e3612cb88e7a48331326cc..4a44de21d1088d1eb075665b90fa3f023e13ff1d 100644 --- a/ets2panda/bindings/native/src/convertors-napi.cpp +++ b/ets2panda/bindings/native/src/convertors-napi.cpp @@ -20,7 +20,7 @@ #include "interop-logging.h" #include "convertors-napi.h" -// NOLINTBEGIN +// NOLINTBEGIN(cppcoreguidelines-macro-usage) // Adapter for NAPI_MODULE #define NODE_API_MODULE_ADAPTER(modname, regfunc) \ @@ -31,7 +31,9 @@ } \ NAPI_MODULE(modname, __napi_##regfunc) -napi_valuetype getValueTypeChecked(napi_env env, napi_value value) +// NOLINTEND(cppcoreguidelines-macro-usage) + +napi_valuetype GetValueTypeChecked(napi_env env, napi_value value) { napi_valuetype type; napi_status status = napi_typeof(env, value, &type); @@ -39,7 +41,7 @@ napi_valuetype getValueTypeChecked(napi_env env, napi_value value) return type; } -bool isTypedArray(napi_env env, napi_value value) +bool IsTypedArray(napi_env env, napi_value value) { bool result = false; napi_status status = napi_is_typedarray(env, value, &result); @@ -47,19 +49,19 @@ bool isTypedArray(napi_env env, napi_value value) return result; } -KBoolean getBoolean(napi_env env, napi_value value) +KBoolean GetBoolean(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) == napi_valuetype::napi_boolean) { + if (GetValueTypeChecked(env, value) == napi_valuetype::napi_boolean) { bool result = false; napi_get_value_bool(env, value, &result); return static_cast(result); } - return static_cast(getInt32(env, value) != 0); + return static_cast(GetInt32(env, value) != 0); } -KInt getInt32(napi_env env, napi_value value) +KInt GetInt32(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) != napi_valuetype::napi_number) { + if (GetValueTypeChecked(env, value) != napi_valuetype::napi_number) { napi_throw_error(env, nullptr, "Expected Number"); return 0; } @@ -68,9 +70,9 @@ KInt getInt32(napi_env env, napi_value value) return static_cast(result); } -KUInt getUInt32(napi_env env, napi_value value) +KUInt GetUInt32(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) != napi_valuetype::napi_number) { + if (GetValueTypeChecked(env, value) != napi_valuetype::napi_number) { napi_throw_error(env, nullptr, "Expected Number"); return 0; } @@ -79,9 +81,9 @@ KUInt getUInt32(napi_env env, napi_value value) return static_cast(result); } -KFloat getFloat32(napi_env env, napi_value value) +KFloat GetFloat32(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) != napi_valuetype::napi_number) { + if (GetValueTypeChecked(env, value) != napi_valuetype::napi_number) { napi_throw_error(env, nullptr, "Expected Number"); return 0.0F; } @@ -90,9 +92,9 @@ KFloat getFloat32(napi_env env, napi_value value) return static_cast(static_cast(result)); } -KDouble getFloat64(napi_env env, napi_value value) +KDouble GetFloat64(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) != napi_valuetype::napi_number) { + if (GetValueTypeChecked(env, value) != napi_valuetype::napi_number) { napi_throw_error(env, nullptr, "Expected Number"); return 0.0; } @@ -101,10 +103,10 @@ KDouble getFloat64(napi_env env, napi_value value) return static_cast(result); } -KStringPtr getString(napi_env env, napi_value value) +KStringPtr GetString(napi_env env, napi_value value) { KStringPtr result {}; - napi_valuetype valueType = getValueTypeChecked(env, value); + napi_valuetype valueType = GetValueTypeChecked(env, value); if (valueType == napi_valuetype::napi_null || valueType == napi_valuetype::napi_undefined) { return result; } @@ -119,15 +121,16 @@ KStringPtr getString(napi_env env, napi_value value) if (status != 0) { return result; } - result.resize(length); - status = napi_get_value_string_utf8(env, value, result.data(), length + 1, nullptr); - TS_NAPI_THROW_IF_FAILED(env, status, nullptr); + result.Resize(length); + status = napi_get_value_string_utf8(env, value, result.Data(), length + 1, nullptr); + TS_NAPI_THROW_IF_FAILED(env, status, KStringPtr(nullptr)); + return result; } -KNativePointer getPointer(napi_env env, napi_value value) +KNativePointer GetPointer(napi_env env, napi_value value) { - napi_valuetype valueType = getValueTypeChecked(env, value); + napi_valuetype valueType = GetValueTypeChecked(env, value); if (valueType == napi_valuetype::napi_external) { KNativePointer result = nullptr; napi_status status = napi_get_value_external(env, value, &result); @@ -151,9 +154,9 @@ KNativePointer getPointer(napi_env env, napi_value value) return reinterpret_cast(ptrU64); } -KLong getInt64(napi_env env, napi_value value) +KLong GetInt64(napi_env env, napi_value value) { - if (getValueTypeChecked(env, value) != napi_valuetype::napi_bigint) { + if (GetValueTypeChecked(env, value) != napi_valuetype::napi_bigint) { napi_throw_error(env, nullptr, "cannot be coerced to int64"); return -1; } @@ -168,15 +171,15 @@ KLong getInt64(napi_env env, napi_value value) return static_cast(ptr64); } -napi_value makeString(napi_env env, const KStringPtr &value) +napi_value MakeString(napi_env env, const KStringPtr &value) { napi_value result; - napi_status status = napi_create_string_utf8(env, value.isNull() ? "" : value.data(), value.length(), &result); + napi_status status = napi_create_string_utf8(env, value.IsNull() ? "" : value.Data(), value.Length(), &result); TS_NAPI_THROW_IF_FAILED(env, status, result); return result; } -napi_value makeString(napi_env env, const std::string &value) +napi_value MakeString(napi_env env, const std::string &value) { napi_value result; napi_status status = napi_create_string_utf8(env, value.c_str(), value.length(), &result); @@ -184,7 +187,7 @@ napi_value makeString(napi_env env, const std::string &value) return result; } -napi_value makeBoolean(napi_env env, int8_t value) +napi_value MakeBoolean(napi_env env, int8_t value) { napi_value result; napi_status status = napi_get_boolean(env, value != 0, &result); @@ -192,7 +195,7 @@ napi_value makeBoolean(napi_env env, int8_t value) return result; } -napi_value makeInt32(napi_env env, int32_t value) +napi_value MakeInt32(napi_env env, int32_t value) { napi_value result; napi_status status = napi_create_int32(env, value, &result); @@ -200,7 +203,7 @@ napi_value makeInt32(napi_env env, int32_t value) return result; } -napi_value makeUInt32(napi_env env, uint32_t value) +napi_value MakeUInt32(napi_env env, uint32_t value) { napi_value result; napi_status status = napi_create_uint32(env, value, &result); @@ -208,7 +211,7 @@ napi_value makeUInt32(napi_env env, uint32_t value) return result; } -napi_value makeFloat32(napi_env env, float value) +napi_value MakeFloat32(napi_env env, float value) { napi_value result; napi_status status = napi_create_double(env, value, &result); @@ -216,7 +219,7 @@ napi_value makeFloat32(napi_env env, float value) return result; } -napi_value makePointer(napi_env env, void *value) +napi_value MakePointer(napi_env env, void *value) { napi_value result; napi_status status = @@ -225,7 +228,7 @@ napi_value makePointer(napi_env env, void *value) return result; } -napi_value makeVoid(napi_env env) +napi_value MakeVoid(napi_env env) { napi_value result; napi_status status = napi_get_undefined(env, &result); @@ -233,7 +236,7 @@ napi_value makeVoid(napi_env env) return result; } -napi_value makeObject(napi_env env, [[maybe_unused]] napi_value object) +napi_value MakeObject(napi_env env, [[maybe_unused]] napi_value object) { napi_value result; napi_status status = napi_create_object(env, &result); @@ -246,7 +249,7 @@ napi_value makeObject(napi_env env, [[maybe_unused]] napi_value object) #pragma comment(linker, "/alternatename:__imp___std_init_once_begin_initialize=__imp_InitOnceBeginInitialize") #endif -Exports *Exports::getInstance() +Exports *Exports::GetInstance() { static Exports *instance = nullptr; if (instance == nullptr) { @@ -255,30 +258,30 @@ Exports *Exports::getInstance() return instance; } -std::vector Exports::getModules() +std::vector Exports::GetModules() { std::vector result; - for (auto it = implementations.begin(); it != implementations.end(); ++it) { - result.push_back(it->first); + for (auto &it : implementations_) { + result.push_back(it.first); } return result; } -void Exports::addMethod(const char *module, const char *name, napi_type_t impl) +void Exports::addMethod(const char *module, const char *name, NapiTypeT impl) { - auto it = implementations.find(module); - if (it == implementations.end()) { - it = implementations.insert(std::make_pair(module, std::vector>())).first; + auto it = implementations_.find(module); + if (it == implementations_.end()) { + it = implementations_.insert(std::make_pair(module, std::vector>())).first; } - it->second.push_back(std::make_pair(name, impl)); + it->second.emplace_back(std::make_pair(name, impl)); } -const std::vector> &Exports::getMethods(const std::string &module) +const std::vector> &Exports::GetMethods(const std::string &module) { - auto it = implementations.find(module); - if (it == implementations.end()) { - LOGE("Module %s is not registered", module.c_str()); - throw "Fatal error"; + auto it = implementations_.find(module); + if (it == implementations_.end()) { + LogE("Module", module.c_str(), "is not registered"); + throw std::runtime_error("Fatal error"); } return it->second; } @@ -296,7 +299,7 @@ napi_value Node_SetCallbackDispatcher(napi_env env, napi_callback_info cbinfo) { CallbackInfo info(env, cbinfo); napi_value dispatcher = info[0]; - napi_value result = makeVoid(env); + napi_value result = MakeVoid(env); napi_status status = napi_create_reference(env, dispatcher, 1, &g_koalaNapiCallbackDispatcher); TS_NAPI_THROW_IF_FAILED(env, status, result); @@ -306,8 +309,8 @@ MAKE_NODE_EXPORT(TS_INTEROP_MODULE, SetCallbackDispatcher) napi_value Node_CleanCallbackDispatcher(napi_env env, [[maybe_unused]] napi_callback_info cbinfo) { - napi_value result = makeVoid(env); - if (g_koalaNapiCallbackDispatcher) { + napi_value result = MakeVoid(env); + if (g_koalaNapiCallbackDispatcher != nullptr) { napi_status status = napi_delete_reference(env, g_koalaNapiCallbackDispatcher); g_koalaNapiCallbackDispatcher = nullptr; TS_NAPI_THROW_IF_FAILED(env, status, result); @@ -316,14 +319,14 @@ napi_value Node_CleanCallbackDispatcher(napi_env env, [[maybe_unused]] napi_call } MAKE_NODE_EXPORT(TS_INTEROP_MODULE, CleanCallbackDispatcher) -napi_value getKoalaNapiCallbackDispatcher(napi_env env) +napi_value GetKoalaNapiCallbackDispatcher(napi_env env) { - if (!g_koalaNapiCallbackDispatcher) { + if (g_koalaNapiCallbackDispatcher == nullptr) { abort(); } napi_value value; napi_status status = napi_get_reference_value(env, g_koalaNapiCallbackDispatcher, &value); - TS_NAPI_THROW_IF_FAILED(env, status, makeVoid(env)); + TS_NAPI_THROW_IF_FAILED(env, status, MakeVoid(env)); return value; } @@ -349,10 +352,10 @@ static constexpr bool SPLIT_MODULES = true; static napi_value InitModule(napi_env env, napi_value exports) { - Exports *inst = Exports::getInstance(); + Exports *inst = Exports::GetInstance(); napi_status status; napi_value target = exports; - for (const auto &module : inst->getModules()) { + for (const auto &module : inst->GetModules()) { if (SPLIT_MODULES) { status = napi_create_object(env, &target); TS_NAPI_THROW_IF_FAILED(env, status, exports); @@ -360,7 +363,7 @@ static napi_value InitModule(napi_env env, napi_value exports) TS_NAPI_THROW_IF_FAILED(env, status, exports); } - for (const auto &impl : inst->getMethods(module)) { + for (const auto &impl : inst->GetMethods(module)) { napi_value implFunc; status = napi_create_function(env, impl.first.c_str(), 0, impl.second, nullptr, &implFunc); TS_NAPI_THROW_IF_FAILED(env, status, exports); @@ -372,5 +375,3 @@ static napi_value InitModule(napi_env env, napi_value exports) } NAPI_MODULE(INTEROP_LIBRARY_NAME, InitModule) - -// NOLINTEND diff --git a/ets2panda/bindings/native/src/generated/bridges.cpp b/ets2panda/bindings/native/src/generated/bridges.cpp index 5484e3dcefda93fec3a6d6139fa799004b09a421..cdd977e8c70472ce3e2a48ce8028f747a6f1357c 100644 --- a/ets2panda/bindings/native/src/generated/bridges.cpp +++ b/ets2panda/bindings/native/src/generated/bridges.cpp @@ -16,8 +16,6 @@ #include #include "public/es2panda_lib.h" -// NOLINTBEGIN - // CC-OFFNXT(G.FUN.01-CPP) solid logic KNativePointer impl_CreateMemberExpression(KNativePointer context, KNativePointer objectArg, KNativePointer property, KInt kind, KBoolean computed, KBoolean optionalArg) @@ -39,15 +37,15 @@ TS_INTEROP_6(CreateMemberExpression, KNativePointer, KNativePointer, KNativePoin KNativePointer impl_UpdateMemberExpression(KNativePointer context, KNativePointer original, KNativePointer object_arg, KNativePointer property, KInt kind, KBoolean computed, KBoolean optional_arg) { - const auto _context = reinterpret_cast(context); - const auto _original = reinterpret_cast(original); - const auto _object_arg = reinterpret_cast(object_arg); - const auto _property = reinterpret_cast(property); - const auto _kind = static_cast(kind); - const auto _computed = static_cast(computed); - const auto _optional_arg = static_cast(optional_arg); - const auto result = GetPublicImpl()->UpdateMemberExpression(_context, _original, _object_arg, _property, _kind, - _computed, _optional_arg); + const auto newContext = reinterpret_cast(context); + const auto newOriginal = reinterpret_cast(original); + const auto newObjectArg = reinterpret_cast(object_arg); + const auto newProperty = reinterpret_cast(property); + const auto newKind = static_cast(kind); + const auto newComputed = static_cast(computed); + const auto newOptionalArg = static_cast(optional_arg); + const auto result = GetPublicImpl()->UpdateMemberExpression(newContext, newOriginal, newObjectArg, newProperty, + newKind, newComputed, newOptionalArg); return result; } // CC-OFFNXT(G.FUN.01-CPP) solid logic @@ -56,29 +54,27 @@ TS_INTEROP_7(UpdateMemberExpression, KNativePointer, KNativePointer, KNativePoin KNativePointer impl_MemberExpressionObject(KNativePointer context, KNativePointer receiver) { - const auto _context = reinterpret_cast(context); - const auto _receiver = reinterpret_cast(receiver); - const auto result = GetPublicImpl()->MemberExpressionObject(_context, _receiver); + const auto newContext = reinterpret_cast(context); + const auto newReceiver = reinterpret_cast(receiver); + const auto result = GetPublicImpl()->MemberExpressionObject(newContext, newReceiver); return result; } TS_INTEROP_2(MemberExpressionObject, KNativePointer, KNativePointer, KNativePointer) KNativePointer impl_MemberExpressionProperty(KNativePointer context, KNativePointer receiver) { - const auto _context = reinterpret_cast(context); - const auto _receiver = reinterpret_cast(receiver); - const auto result = GetPublicImpl()->MemberExpressionProperty(_context, _receiver); + const auto newContext = reinterpret_cast(context); + const auto newReceiver = reinterpret_cast(receiver); + const auto result = GetPublicImpl()->MemberExpressionProperty(newContext, newReceiver); return result; } TS_INTEROP_2(MemberExpressionProperty, KNativePointer, KNativePointer, KNativePointer) KInt impl_MemberExpressionKindConst(KNativePointer context, KNativePointer receiver) { - const auto _context = reinterpret_cast(context); - const auto _receiver = reinterpret_cast(receiver); - const auto result = GetPublicImpl()->MemberExpressionKindConst(_context, _receiver); + const auto newContext = reinterpret_cast(context); + const auto newReceiver = reinterpret_cast(receiver); + const auto result = GetPublicImpl()->MemberExpressionKindConst(newContext, newReceiver); return result; } TS_INTEROP_2(MemberExpressionKindConst, KInt, KNativePointer, KNativePointer) - -// NOLINTEND diff --git a/ets2panda/bindings/native/src/lsp.cpp b/ets2panda/bindings/native/src/lsp.cpp index 7f9c2e23efebfda639118366662a03fae5aa3dbb..9bca9f5a2c476787a40d201f822d4c97e99c0c9a 100644 --- a/ets2panda/bindings/native/src/lsp.cpp +++ b/ets2panda/bindings/native/src/lsp.cpp @@ -14,20 +14,26 @@ */ #include "convertors-napi.h" +#include "ir/astNode.h" #include "lsp/include/api.h" -#include "lsp/include/completions.h" #include "common.h" #include "panda_types.h" #include "public/es2panda_lib.h" - +#include "lsp/include/refactors/refactor_types.h" #include -#include #include -#include + +namespace { +using ark::es2panda::lsp::ClassHierarchy; +using ark::es2panda::lsp::ClassHierarchyInfo; +using ark::es2panda::lsp::ClassHierarchyItem; +using ark::es2panda::lsp::ClassMethodItem; +using ark::es2panda::lsp::ClassPropertyItem; +} // namespace char *GetStringCopy(KStringPtr &ptr) { - return strdup(ptr.c_str()); + return strdup(ptr.CStr()); } KNativePointer impl_getCurrentTokenValue(KNativePointer context, KInt position) @@ -48,6 +54,311 @@ 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_getRenameLocationFileName(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return new std::string(renameLocationRef->fileName); +} +TS_INTEROP_1(getRenameLocationFileName, KNativePointer, KNativePointer) + +KBoolean impl_renameLocationHasPrefixText(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return renameLocationRef->prefixText.has_value() ? 1 : 0; +} +TS_INTEROP_1(renameLocationHasPrefixText, KBoolean, KNativePointer) + +KNativePointer impl_getRenameLocationPrefixText(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return new std::string(renameLocationRef->prefixText.has_value() ? renameLocationRef->prefixText.value() : ""); +} +TS_INTEROP_1(getRenameLocationPrefixText, KNativePointer, KNativePointer) + +KBoolean impl_renameLocationHasSuffixText(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return renameLocationRef->suffixText.has_value() ? 1 : 0; +} +TS_INTEROP_1(renameLocationHasSuffixText, KBoolean, KNativePointer) + +KNativePointer impl_getRenameLocationSuffixText(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return new std::string(renameLocationRef->suffixText.has_value() ? renameLocationRef->suffixText.value() : ""); +} +TS_INTEROP_1(getRenameLocationSuffixText, KNativePointer, KNativePointer) + +KInt impl_getRenameLocationStart(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return renameLocationRef->start; +} +TS_INTEROP_1(getRenameLocationStart, KInt, KNativePointer) + +KInt impl_getRenameLocationEnd(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return renameLocationRef->end; +} +TS_INTEROP_1(getRenameLocationEnd, KInt, KNativePointer) + +KInt impl_getRenameLocationLine(KNativePointer renameLocationPtr) +{ + auto *renameLocationRef = reinterpret_cast(renameLocationPtr); + return renameLocationRef->line; +} +TS_INTEROP_1(getRenameLocationLine, KInt, KNativePointer) + +// NOLINTBEGIN +inline KUInt UnpackUInt(const KByte *bytes) +{ + return (bytes[0] | (bytes[1] << 8U) | (bytes[2U] << 16U) | (bytes[3U] << 24U)); +} +// NOLINTEND + +/* + * Parses an array of pointers from a KStringArray. + * format: + * | header(4 bytes) | strLen(4 bytes) | strData(strLen bytes) | strLen(4 bytes) | strData(strLen bytes) | ... + */ +static std::vector ParsePointerArray(KInt argc, KStringArray pointerArrayPtr) +{ + const std::size_t headerLen = 4; + auto bigintPtrs = std::vector(); + bigintPtrs.reserve(static_cast(argc)); + std::size_t offset = headerLen; + std::size_t strLen = 0; + + for (std::size_t i = 0; i < static_cast(argc); ++i) { + strLen = UnpackUInt(pointerArrayPtr + offset); + offset += headerLen; + std::string bigintStr(reinterpret_cast(pointerArrayPtr + offset), strLen); + offset += strLen; + + uintptr_t ptrValue = 0; + const size_t prefixLen = 2; + const size_t hex = 16; + const size_t decimal = 10; + if (bigintStr.substr(0, prefixLen) == "0x" || bigintStr.substr(0, prefixLen) == "0X") { + ptrValue = std::stoull(bigintStr, nullptr, hex); + } else { + ptrValue = std::stoull(bigintStr, nullptr, decimal); + } + bigintPtrs.push_back(reinterpret_cast(ptrValue)); + } + + return bigintPtrs; +} + +KNativePointer impl_findRenameLocations(KInt argc, KStringArray pointerArrayPtr, KNativePointer context, KInt position) +{ + auto pointerArray = ParsePointerArray(argc, pointerArrayPtr); + auto fileContexts = std::vector {}; + fileContexts.reserve(argc); + for (std::size_t i = 0; i < static_cast(argc); ++i) { + auto contextPtr = reinterpret_cast(pointerArray[i]); + if (contextPtr != nullptr) { + fileContexts.push_back(contextPtr); + } + } + LSPAPI const *ctx = GetImpl(); + auto result = ctx->findRenameLocations(fileContexts, reinterpret_cast(context), + static_cast(position)); + auto ptrs = std::make_unique>(); + ptrs->reserve(result.size()); + for (auto &el : result) { + ptrs->push_back(new ark::es2panda::lsp::RenameLocation(std::move(el))); + } + return ptrs.release(); +} +TS_INTEROP_4(findRenameLocations, KNativePointer, KInt, KStringArray, KNativePointer, KInt) + +KNativePointer impl_findRenameLocationsInCurrentFile(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto result = ctx->findRenameLocationsInCurrentFile(reinterpret_cast(context), + static_cast(position)); + auto ptrs = std::make_unique>(); + ptrs->reserve(result.size()); + for (auto &el : result) { + ptrs->push_back(new ark::es2panda::lsp::RenameLocation(el)); + } + return ptrs.release(); +} +TS_INTEROP_2(findRenameLocationsInCurrentFile, KNativePointer, KNativePointer, KInt) + +KBoolean impl_needsCrossFileRename(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto res = ctx->needsCrossFileRename(reinterpret_cast(context), position); + return res ? 1 : 0; +} +TS_INTEROP_2(needsCrossFileRename, KBoolean, KNativePointer, KInt) + +KNativePointer impl_getRenameSuccessFileName(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new std::string(successInfo->GetFileToRename()); +} +TS_INTEROP_1(getRenameSuccessFileName, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameSuccessKind(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new std::string(successInfo->GetKind()); +} +TS_INTEROP_1(getRenameSuccessKind, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameSuccessDisplayName(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new std::string(successInfo->GetDisplayName()); +} +TS_INTEROP_1(getRenameSuccessDisplayName, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameSuccessFullDisplayName(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new std::string(successInfo->GetFullDisplayName()); +} +TS_INTEROP_1(getRenameSuccessFullDisplayName, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameSuccessKindModifiers(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new std::string(successInfo->GetKindModifiers()); +} +TS_INTEROP_1(getRenameSuccessKindModifiers, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameSuccessTriggerSpan(KNativePointer successPtr) +{ + auto successInfo = reinterpret_cast(successPtr); + return new TextSpan(successInfo->GetTriggerSpan()); +} +TS_INTEROP_1(getRenameSuccessTriggerSpan, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameFailureLocalizedErrorMessage(KNativePointer failurePtr) +{ + auto failureInfo = reinterpret_cast(failurePtr); + return new std::string(failureInfo->GetLocalizedErrorMessage()); +} +TS_INTEROP_1(getRenameFailureLocalizedErrorMessage, KNativePointer, KNativePointer) + +KBoolean impl_getRenameInfoIsSuccess(KNativePointer renameInfoPtr) +{ + auto renameInfo = reinterpret_cast *>(renameInfoPtr); + return std::get<0>(*renameInfo) ? 1 : 0; +} +TS_INTEROP_1(getRenameInfoIsSuccess, KBoolean, KNativePointer) + +KNativePointer impl_getRenameInfoSuccess(KNativePointer renameInfoPtr) +{ + auto renameInfo = reinterpret_cast *>(renameInfoPtr); + auto [flag, successInfo] = *renameInfo; + return flag ? successInfo : nullptr; +} +TS_INTEROP_1(getRenameInfoSuccess, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameInfoFailure(KNativePointer renameInfoPtr) +{ + auto renameInfo = reinterpret_cast *>(renameInfoPtr); + auto [flag, failureInfo] = *renameInfo; + return flag ? nullptr : failureInfo; +} +TS_INTEROP_1(getRenameInfoFailure, KNativePointer, KNativePointer) + +KNativePointer impl_getRenameInfo(KNativePointer context, KInt position, KStringPtr &pandaLibPath) +{ + LSPAPI const *ctx = GetImpl(); + auto result = ctx->getRenameInfo(reinterpret_cast(context), static_cast(position), + GetStringCopy(pandaLibPath)); + if (std::holds_alternative(result)) { + auto &successInfo = std::get(result); + return new std::tuple(true, new ark::es2panda::lsp::RenameInfoSuccess(std::move(successInfo))); + } + auto &failureInfo = std::get(result); + return new std::tuple(false, new ark::es2panda::lsp::RenameInfoFailure(std::move(failureInfo))); +} +TS_INTEROP_3(getRenameInfo, KNativePointer, KNativePointer, KInt, KStringPtr) + +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) + +KInt impl_getStartFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return info->start; +} +TS_INTEROP_1(getStartFromPropertyInfo, KInt, KNativePointer) + +KInt impl_getEndFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return info->end; +} +TS_INTEROP_1(getEndFromPropertyInfo, KInt, KNativePointer) + KNativePointer impl_getSyntacticDiagnostics(KNativePointer context) { LSPAPI const *ctx = GetImpl(); @@ -171,7 +482,7 @@ TS_INTEROP_1(getDiagRelatedInfo, KNativePointer, KNativePointer) KNativePointer impl_getRelatedInfoMsg(KNativePointer relatedInfoPtr) { auto *relatedInfoRef = reinterpret_cast(relatedInfoPtr); - return &relatedInfoRef->message_; + return new std::string(relatedInfoRef->message_); } TS_INTEROP_1(getRelatedInfoMsg, KNativePointer, KNativePointer) @@ -185,7 +496,7 @@ TS_INTEROP_1(getRelatedInfoLoc, KNativePointer, KNativePointer) KNativePointer impl_getLocUri(KNativePointer locPtr) { auto *locRef = reinterpret_cast(locPtr); - return &locRef->uri_; + return new std::string(locRef->uri_); } TS_INTEROP_1(getLocUri, KNativePointer, KNativePointer) @@ -228,6 +539,143 @@ 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 ark::es2panda::lsp::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_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(); @@ -301,6 +749,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(); @@ -319,19 +829,19 @@ KNativePointer impl_getDefinitionAtPosition(KNativePointer context, KInt positio } TS_INTEROP_2(getDefinitionAtPosition, KNativePointer, KNativePointer, KInt) -KNativePointer impl_getFileNameFromDef(KNativePointer defPtr) +KNativePointer impl_GetFileNameFromDef(KNativePointer defPtr) { auto *defInfo = reinterpret_cast(defPtr); return new std::string(defInfo->fileName); } -TS_INTEROP_1(getFileNameFromDef, KNativePointer, KNativePointer) +TS_INTEROP_1(GetFileNameFromDef, KNativePointer, KNativePointer) -KInt impl_getStartFromDef(KNativePointer defPtr) +KInt impl_GetStartFromDef(KNativePointer defPtr) { auto *defInfo = reinterpret_cast(defPtr); return defInfo->start; } -TS_INTEROP_1(getStartFromDef, KInt, KNativePointer) +TS_INTEROP_1(GetStartFromDef, KInt, KNativePointer) KInt impl_getLengthFromDef(KNativePointer defPtr) { @@ -404,46 +914,363 @@ KNativePointer impl_getQuickInfoFileName(KNativePointer ref) } TS_INTEROP_1(getQuickInfoFileName, KNativePointer, KNativePointer) -KNativePointer impl_getSymbolDisplayPart(KNativePointer quickInfoPtr) +KNativePointer impl_getClassHierarchyInfo(KNativePointer context, KInt position) { - auto *quickInfo = reinterpret_cast(quickInfoPtr); + 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 (auto &el : quickInfo->GetDisplayParts()) { - ptrs.push_back(new SymbolDisplayPart(el)); + for (const auto &element : *infosPtr) { + ptrs.push_back(new ClassHierarchyInfo(element)); } return new std::vector(ptrs); } -TS_INTEROP_1(getSymbolDisplayPart, KNativePointer, KNativePointer) +TS_INTEROP_1(castToClassHierarchyInfos, KNativePointer, KNativePointer) -KInt impl_getTextSpanStart(KNativePointer textSpanPtr) +KNativePointer impl_getClassNameFromClassHierarchyInfo(KNativePointer info) { - auto *textSpan = reinterpret_cast(textSpanPtr); - return textSpan->start; + auto *infoPtr = reinterpret_cast(info); + if (infoPtr == nullptr) { + return nullptr; + } + return new std::string(infoPtr->GetClassName()); } -TS_INTEROP_1(getTextSpanStart, KInt, KNativePointer) +TS_INTEROP_1(getClassNameFromClassHierarchyInfo, KNativePointer, KNativePointer) -KInt impl_getTextSpanLength(KNativePointer textSpanPtr) +KNativePointer impl_getMethodItemsFromClassHierarchyInfo(KNativePointer info) { - auto *textSpan = reinterpret_cast(textSpanPtr); - return textSpan->length; + auto *infoPtr = reinterpret_cast(info); + if (infoPtr == nullptr) { + return nullptr; + } + std::vector ptrs; + for (const auto &element : infoPtr->GetMethodItemList()) { + if (element.second == nullptr) { + continue; + } + ptrs.push_back(new ClassMethodItem(*(element.second))); + } + return new std::vector(ptrs); } -TS_INTEROP_1(getTextSpanLength, KInt, KNativePointer) +TS_INTEROP_1(getMethodItemsFromClassHierarchyInfo, KNativePointer, KNativePointer) -KNativePointer impl_getTextSpan(KNativePointer quickInfoPtr) +KNativePointer impl_getPropertyItemsFromClassHierarchyInfo(KNativePointer info) { - auto *quickInfo = reinterpret_cast(quickInfoPtr); - return new TextSpan(quickInfo->GetTextSpan()); + auto *infoPtr = reinterpret_cast(info); + if (infoPtr == nullptr) { + return nullptr; + } + std::vector ptrs; + for (const auto &element : infoPtr->GetPropertyItemList()) { + if (element.second == nullptr) { + continue; + } + ptrs.push_back(new ClassPropertyItem(*(element.second))); + } + return new std::vector(ptrs); } -TS_INTEROP_1(getTextSpan, KNativePointer, KNativePointer) +TS_INTEROP_1(getPropertyItemsFromClassHierarchyInfo, KNativePointer, KNativePointer) -KNativePointer impl_getHighlightTextSpan(KNativePointer highlightPtr) +KNativePointer impl_getDetailFromClassHierarchyItem(KNativePointer item) { - auto *highlight = reinterpret_cast(highlightPtr); - return new TextSpan(highlight->textSpan_); + auto *itemPtr = reinterpret_cast(item); + if (itemPtr == nullptr) { + return nullptr; + } + return new std::string(itemPtr->GetDetail()); } -TS_INTEROP_1(getHighlightTextSpan, KNativePointer, KNativePointer) +TS_INTEROP_1(getDetailFromClassHierarchyItem, KNativePointer, KNativePointer) -KNativePointer impl_getHighlightContextSpan(KNativePointer highlightPtr) +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_getAccessModifierStyleFromClassHierarchyItem(KNativePointer item) +{ + auto *itemPtr = reinterpret_cast(item); + if (itemPtr == nullptr) { + return 0; + } + return static_cast(itemPtr->GetAccessModifierStyle()); +} +TS_INTEROP_1(getAccessModifierStyleFromClassHierarchyItem, 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_pushBackToNativeContextVector(KNativePointer context, KNativePointer contextList, KBoolean isNew) +{ + auto contextPtr = reinterpret_cast(context); + if (isNew != 0) { + auto *newVector = new std::vector(); + newVector->push_back(contextPtr); + return newVector; + } + auto contextVector = reinterpret_cast *>(contextList); + contextVector->push_back(contextPtr); + return contextVector; +} +TS_INTEROP_3(pushBackToNativeContextVector, KNativePointer, KNativePointer, KNativePointer, KBoolean) + +KNativePointer impl_getClassHierarchies(KNativePointer context, KStringPtr &fileNamePtr, KInt pos) +{ + LSPAPI const *ctx = GetImpl(); + if (ctx == nullptr) { + return nullptr; + } + auto *contextlist = reinterpret_cast *>(context); + auto infos = ctx->getClassHierarchiesImpl(contextlist, 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_getApplicableRefactors(KNativePointer context, KStringPtr &kindPtr, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto *result = new std::vector(ctx->getApplicableRefactors( + reinterpret_cast(context), GetStringCopy(kindPtr), static_cast(position))); + return result; +} +TS_INTEROP_3(getApplicableRefactors, KNativePointer, KNativePointer, KStringPtr, KInt) + +KNativePointer impl_getApplicableRefactorInfoList(KNativePointer infosPtr) +{ + auto *infos = reinterpret_cast *>(infosPtr); + std::vector ptrs; + for (auto &info : *infos) { + ptrs.push_back(new ark::es2panda::lsp::ApplicableRefactorInfo(info)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getApplicableRefactorInfoList, 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_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_getApplicableRefactorAction(KNativePointer applRefsPtr) +{ + auto *applRefsInfo = reinterpret_cast(applRefsPtr); + return new ark::es2panda::lsp::RefactorAction(applRefsInfo->action); +} +TS_INTEROP_1(getApplicableRefactorAction, KNativePointer, KNativePointer) + +KNativePointer impl_getClassHierarchyList(KNativePointer infosPtr) +{ + auto *infos = reinterpret_cast *>(infosPtr); + std::vector infoPtrList; + for (auto &info : *infos) { + infoPtrList.push_back(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()); + for (auto &details : overridden) { + overriddenPtrList.push_back(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()); + for (auto &details : overriding) { + overridingPtrList.push_back(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()); + for (auto &details : implemented) { + implementedPtrList.push_back(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()); + for (auto &details : implementing) { + implementingPtrList.push_back(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); + std::vector ptrs; + for (auto &el : quickInfo->GetDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSymbolDisplayPart, KNativePointer, KNativePointer) + +KInt impl_getTextSpanStart(KNativePointer textSpanPtr) +{ + auto *textSpan = reinterpret_cast(textSpanPtr); + return textSpan->start; +} +TS_INTEROP_1(getTextSpanStart, KInt, KNativePointer) + +KInt impl_getTextSpanLength(KNativePointer textSpanPtr) +{ + auto *textSpan = reinterpret_cast(textSpanPtr); + return textSpan->length; +} +TS_INTEROP_1(getTextSpanLength, KInt, KNativePointer) + +KNativePointer impl_getTextSpan(KNativePointer quickInfoPtr) +{ + auto *quickInfo = reinterpret_cast(quickInfoPtr); + return new TextSpan(quickInfo->GetTextSpan()); +} +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_); @@ -626,6 +1453,13 @@ KNativePointer impl_getLocationFromList(KNativePointer listPtr) } TS_INTEROP_1(getLocationFromList, KNativePointer, KNativePointer) +KBoolean impl_getSafeDeleteInfo(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + return static_cast(ctx->getSafeDeleteInfo(reinterpret_cast(context), position)); +} +TS_INTEROP_2(getSafeDeleteInfo, KBoolean, KNativePointer, KInt) + KNativePointer impl_toLineColumnOffset(KNativePointer context, KInt position) { LSPAPI const *ctx = GetImpl(); @@ -647,4 +1481,460 @@ 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_getCodeFixesAtPosition(KNativePointer context, KInt startPosition, KInt endPosition, + KInt *errorCodesPtr, KInt codeLength) +{ + CodeFixOptions emptyOptions; + std::vector errorCodesInt; + if (errorCodesPtr != nullptr && codeLength > 0) { + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic,-warnings-as-errors) + errorCodesInt = std::vector(reinterpret_cast(errorCodesPtr), + reinterpret_cast(errorCodesPtr) + codeLength); + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic,-warnings-as-errors) + } + LSPAPI const *ctx = GetImpl(); + auto autofix = ctx->getCodeFixesAtPosition(reinterpret_cast(context), startPosition, + endPosition, errorCodesInt, emptyOptions); + return new std::vector(autofix); +} +TS_INTEROP_5(getCodeFixesAtPosition, KNativePointer, KNativePointer, KInt, KInt, KInt *, KInt) + +KNativePointer impl_getCodeFixActionInfos(KNativePointer codeFixActionInfoListPtr) +{ + auto *getCodeFixActionInfoList = reinterpret_cast(codeFixActionInfoListPtr); + std::vector ptrs; + for (auto &el : getCodeFixActionInfoList->infos_) { + ptrs.push_back(new CodeFixActionInfo(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getCodeFixActionInfos, KNativePointer, KNativePointer) + +KNativePointer impl_getFileTextChangesFromCodeActionInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->changes_) { + ptrs.push_back(new FileTextChanges(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getFileTextChangesFromCodeActionInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getDescriptionFromCodeActionInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->description_); +} +TS_INTEROP_1(getDescriptionFromCodeActionInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFixNameFromCodeFixActionInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fixName_); +} +TS_INTEROP_1(getFixNameFromCodeFixActionInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFixIdFromCodeFixActionInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fixId_); +} +TS_INTEROP_1(getFixIdFromCodeFixActionInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFixAllDescriptionFromCodeFixActionInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fixAllDescription_); +} +TS_INTEROP_1(getFixAllDescriptionFromCodeFixActionInfo, KNativePointer, 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 new std::string(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 new std::string(parameterRef->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) + +KInt impl_getOffsetByColAndLine(KStringPtr &sourceCodePtr, KInt line, KInt column) +{ + LSPAPI const *impl = GetImpl(); + return impl->getOffsetByColAndLine(sourceCodePtr.Data(), line, column); +} +TS_INTEROP_3(getOffsetByColAndLine, KInt, KStringPtr, KInt, KInt) + +KNativePointer impl_getClassDefinition(KNativePointer astNodePtr, KStringPtr &nodeNamePtr) +{ + auto ast = reinterpret_cast(astNodePtr); + LSPAPI const *impl = GetImpl(); + return impl->getClassDefinition(ast, nodeNamePtr.Data()); +} +TS_INTEROP_2(getClassDefinition, KNativePointer, KNativePointer, KStringPtr) + +KNativePointer impl_getIdentifier(KNativePointer astNodePtr, KStringPtr &nodeNamePtr) +{ + auto ast = reinterpret_cast(astNodePtr); + LSPAPI const *impl = GetImpl(); + return impl->getIdentifier(ast, nodeNamePtr.Data()); +} +TS_INTEROP_2(getIdentifier, KNativePointer, KNativePointer, KStringPtr) + +KNativePointer impl_getProgramAst(KNativePointer contextPtr) +{ + auto context = reinterpret_cast(contextPtr); + LSPAPI const *impl = GetImpl(); + return impl->getProgramAst(context); +} +TS_INTEROP_1(getProgramAst, KNativePointer, KNativePointer) + +KNativePointer impl_getNodeInfosByDefinitionData(KNativePointer context, KInt position) +{ + auto ctx = reinterpret_cast(context); + LSPAPI const *impl = GetImpl(); + std::vector ptrs; + for (auto &item : impl->getNodeInfosByDefinitionData(ctx, position)) { + ptrs.push_back(new NodeInfo(item)); + } + return new std::vector(ptrs); +} +TS_INTEROP_2(getNodeInfosByDefinitionData, KNativePointer, KNativePointer, KInt) + +KNativePointer impl_getNameByNodeInfo(KNativePointer nodeInfo) +{ + auto *info = reinterpret_cast(nodeInfo); + return new std::string(info->name); +} +TS_INTEROP_1(getNameByNodeInfo, KNativePointer, KNativePointer) + +KNativePointer impl_CreateNodeInfoPtr(KStringPtr &nodeName, KInt nodeKind) +{ + return new NodeInfo(nodeName.Data(), ark::es2panda::ir::AstNodeType(nodeKind)); +} +TS_INTEROP_2(CreateNodeInfoPtr, KNativePointer, KStringPtr, KInt) + +KNativePointer impl_getKindByNodeInfo(KNativePointer nodeInfo) +{ + auto *info = reinterpret_cast(nodeInfo); + return new std::string(ark::es2panda::ir::ToString(info->kind)); +} +TS_INTEROP_1(getKindByNodeInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getDefinitionDataFromNode(KNativePointer context, KStringArray pointerArrayPtr, KInt arraySize) +{ + auto pointerArray = ParsePointerArray(arraySize, pointerArrayPtr); + auto nodeInfos = std::vector {}; + nodeInfos.reserve(arraySize); + for (std::size_t i = 0; i < static_cast(arraySize); ++i) { + auto contextPtr = reinterpret_cast(pointerArray[i]); + if (contextPtr != nullptr) { + nodeInfos.push_back(contextPtr); + } + } + auto ctx = reinterpret_cast(context); + LSPAPI const *impl = GetImpl(); + return new DefinitionInfo(impl->getDefinitionDataFromNode(ctx, nodeInfos)); +} +TS_INTEROP_3(getDefinitionDataFromNode, KNativePointer, KNativePointer, KStringArray, KInt) + +KInt impl_getSourceLocationLine(KNativePointer locationPtr) +{ + auto *location = reinterpret_cast *>(locationPtr); + return location->first; +} +TS_INTEROP_1(getSourceLocationLine, KInt, KNativePointer) + +KInt impl_getSourceLocationColumn(KNativePointer locationPtr) +{ + auto *location = reinterpret_cast *>(locationPtr); + return location->second; +} +TS_INTEROP_1(getSourceLocationColumn, KInt, KNativePointer) + +KNativePointer impl_getColAndLineByOffset(KStringPtr &sourceCodePtr, KInt offset) +{ + LSPAPI const *impl = GetImpl(); + return new std::pair(impl->getColAndLineByOffset(sourceCodePtr.Data(), offset)); +} +TS_INTEROP_2(getColAndLineByOffset, KNativePointer, KStringPtr, KInt) diff --git a/ets2panda/bindings/native/src/win-dynamic-node.cpp b/ets2panda/bindings/native/src/win-dynamic-node.cpp index 85bb3cb4da61e7cde2ee782aefb8d404b7c9bb18..5e484955b7e31d4a05d326a2f08d69e3195673de 100644 --- a/ets2panda/bindings/native/src/win-dynamic-node.cpp +++ b/ets2panda/bindings/native/src/win-dynamic-node.cpp @@ -149,11 +149,11 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_is_typedarray(napi_env env, napi_value v } // CC-OFFNXT(G.FUN.01, huge_method) solid logic -NAPI_EXTERN napi_status NAPI_CDECL napi_add_finalizer(napi_env env, napi_value js_object, void *finalize_data, - napi_finalize finalize_cb, void *finalize_hint, napi_ref *result) +NAPI_EXTERN napi_status NAPI_CDECL napi_add_finalizer(napi_env env, napi_value js_object, void *FinalizeData, + napi_finalize finalize_cb, void *FinalizeHint, napi_ref *result) { LoadNapiFunctions(); - return p_napi_add_finalizer(env, js_object, finalize_data, finalize_cb, finalize_hint, result); + return p_napi_add_finalizer(env, js_object, FinalizeData, finalize_cb, FinalizeHint, result); } // CC-OFFNXT(G.FUN.01, huge_method) solid logic @@ -403,10 +403,10 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_int32(napi_env env, int32_t value // CC-OFFNXT(G.FUN.01, huge_method) solid logic NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_arraybuffer(napi_env env, void *external_data, size_t byte_length, napi_finalize finalize_cb, - void *finalize_hint, napi_value *result) + void *FinalizeHint, napi_value *result) { LoadNapiFunctions(); - return p_napi_create_external_arraybuffer(env, external_data, byte_length, finalize_cb, finalize_hint, result); + return p_napi_create_external_arraybuffer(env, external_data, byte_length, finalize_cb, FinalizeHint, result); } // CC-OFFNXT(G.FUN.01, huge_method) solid logic @@ -469,12 +469,12 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_reject_deferred(napi_env env, napi_defer // CC-OFFNXT(G.FUN.01, huge_method) solid logic NAPI_EXTERN napi_status NAPI_CDECL napi_create_threadsafe_function( napi_env env, napi_value func, napi_value async_resource, napi_value async_resource_name, size_t max_queue_size, - size_t initial_thread_count, void *thread_finalize_data, napi_finalize thread_finalize_cb, void *context, + size_t initial_thread_count, void *thread_FinalizeData, napi_finalize thread_finalize_cb, void *context, napi_threadsafe_function_call_js call_js_cb, napi_threadsafe_function *result) { LoadNapiFunctions(); return p_napi_create_threadsafe_function(env, func, async_resource, async_resource_name, max_queue_size, - initial_thread_count, thread_finalize_data, thread_finalize_cb, context, + initial_thread_count, thread_FinalizeData, thread_finalize_cb, context, call_js_cb, result); } diff --git a/ets2panda/bindings/package.json b/ets2panda/bindings/package.json index 92d680af8d08a135101997e4752810d95b16fca5..586b823c5bad393cd9b8569a72fce9f948a3561c 100644 --- a/ets2panda/bindings/package.json +++ b/ets2panda/bindings/package.json @@ -8,7 +8,7 @@ "prettier": "latest", "rimraf": "^6.0.1", "typescript": "4.9.5", - "node-api-headers": "^1.4.0" + "jest-diff": "latest" }, "main": "dist/index.js", "scripts": { @@ -16,6 +16,7 @@ "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", + "test:update": "npm run test:build && node dist-test/test/run_tests.js ./test --update", "compile": "tsc --build --verbose tsconfig.json", "clean": "rimraf dist tsconfig.tsbuildinfo package-lock.json", "run": "npm run clean && npm run compile", diff --git a/ets2panda/bindings/src/arktsConfigGenerate.ts b/ets2panda/bindings/src/arktsConfigGenerate.ts deleted file mode 100644 index 56f00052edfbf3e3b8fa7090facefb977730077b..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/src/arktsConfigGenerate.ts +++ /dev/null @@ -1,58 +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. - */ - -import { BuildMode } from './build/buildMode'; -import { BuildConfig } from './types'; -import { ModuleDescriptor, generateBuildConfigs } from './buildConfigGenerate'; -import { PANDA_SDK_PATH_FROM_SDK } from './preDefine'; - -import * as fs from 'fs'; -import * as path from 'path'; -import { PluginDriver } from './ui_plugins_driver'; - -function processBuildConfig(projectConfig: BuildConfig): BuildConfig { - let buildConfig: BuildConfig = { ...projectConfig }; - let buildSdkPath: string = buildConfig.buildSdkPath as string; - buildConfig.pandaSdkPath = buildConfig.pandaSdkPath ?? path.resolve(buildSdkPath, PANDA_SDK_PATH_FROM_SDK); - PluginDriver.getInstance().initPlugins(buildConfig); - return buildConfig; -} - -export function generateArkTsConfigByModules( - buildSdkPath: string, - projectRoot: string, - modules?: ModuleDescriptor[] -): void { - const allBuildConfig = generateBuildConfigs(buildSdkPath, projectRoot, modules); - let compileFileInfos: Record = {}; - 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); - - const buildMode = new BuildMode(processedConfig); - buildMode.generateArkTSConfig(compileFileInfos); - }); - 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/build/buildMode.ts b/ets2panda/bindings/src/build/buildMode.ts deleted file mode 100644 index d1be834b99fda47c40eb4787f8670bfa76be6268..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/src/build/buildMode.ts +++ /dev/null @@ -1,188 +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. - */ - -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 { ArkTSConfigGenerator } from './generateArkTSConfig'; - -export class BuildMode { - buildConfig: BuildConfig; - entryFiles: Set; - compileFiles: Map; - cacheDir: string; - pandaSdkPath: string; - buildSdkPath: string; - packageName: string; - sourceRoots: string[]; - moduleRootPath: string; - moduleType: string; - dependentModuleList: DependentModuleConfig[]; - moduleInfos: Map; - declgenV1OutPath: string | undefined; - declgenBridgeCodePath: string | undefined; - hasMainModule: boolean; - - constructor(buildConfig: BuildConfig) { - this.buildConfig = buildConfig; - this.entryFiles = new Set(buildConfig.compileFiles as string[]); - this.cacheDir = buildConfig.cachePath as string; - this.pandaSdkPath = buildConfig.pandaSdkPath as string; - this.buildSdkPath = buildConfig.buildSdkPath as string; - this.packageName = buildConfig.packageName as string; - this.sourceRoots = buildConfig.sourceRoots as string[]; - this.moduleRootPath = buildConfig.moduleRootPath as string; - this.moduleType = buildConfig.moduleType as string; - this.dependentModuleList = buildConfig.dependentModuleList; - this.hasMainModule = buildConfig.hasMainModule; - - this.declgenV1OutPath = buildConfig.declgenV1OutPath as string | undefined; - this.declgenBridgeCodePath = buildConfig.declgenBridgeCodePath as string | undefined; - - this.moduleInfos = new Map(); - this.compileFiles = new Map(); - } - - private getDependentModules(moduleInfo: ModuleInfo): Map[] { - let dynamicDepModules: Map = new Map(); - let staticDepModules: Map = new Map(); - - if (moduleInfo.isMainModule) { - this.moduleInfos.forEach((module: ModuleInfo, packageName: string) => { - if (module.isMainModule) { - return; - } - module.language === LANGUAGE_VERSION.ARKTS_1_2 - ? staticDepModules.set(packageName, module) - : dynamicDepModules.set(packageName, module); - }); - return [dynamicDepModules, staticDepModules]; - } - - if (moduleInfo.dependencies) { - moduleInfo.dependencies.forEach((packageName: string) => { - let depModuleInfo: ModuleInfo | undefined = this.moduleInfos.get(packageName); - 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); - } - }); - } - return [dynamicDepModules, staticDepModules]; - } - - private generateArkTSConfigForModules(compileFileInfos: Record): void { - let generator = ArkTSConfigGenerator.getGenerator(this.buildConfig, this.moduleInfos); - this.moduleInfos.forEach((moduleInfo: ModuleInfo, moduleRootPath: string) => { - for (const fileInfo of moduleInfo.compileFileInfos) { - compileFileInfos[fileInfo.filePath] = fileInfo.arktsConfigFile; - } - generator.writeArkTSConfigFile(moduleInfo); - }); - } - - private collectDepModuleInfos(): void { - this.moduleInfos.forEach((moduleInfo) => { - let [dynamicDepModules, staticDepModules] = this.getDependentModules(moduleInfo); - moduleInfo.dynamicDepModuleInfos = dynamicDepModules; - moduleInfo.staticDepModuleInfos = staticDepModules; - }); - } - - private collectModuleInfos(): void { - if (this.hasMainModule && (!this.packageName || !this.moduleRootPath || !this.sourceRoots)) { - console.error('Main module info from hvigor is not correct.'); - } - let mainModuleInfo: ModuleInfo = { - isMainModule: this.hasMainModule, - packageName: this.packageName, - moduleRootPath: this.moduleRootPath, - moduleType: this.moduleType, - sourceRoots: this.sourceRoots, - entryFile: '', - arktsConfigFile: path.resolve(this.cacheDir, this.packageName, ARKTSCONFIG_JSON_FILE), - dynamicDepModuleInfos: new Map(), - staticDepModuleInfos: new Map(), - 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) { - console.error('Dependent module info from hvigor is not correct.'); - } - let moduleInfo: ModuleInfo = { - isMainModule: false, - packageName: module.packageName, - moduleRootPath: module.modulePath, - moduleType: module.moduleType, - sourceRoots: module.sourceRoots, - entryFile: module.entryFile, - arktsConfigFile: path.resolve(this.cacheDir, module.packageName, ARKTSCONFIG_JSON_FILE), - compileFileInfos: [], - dynamicDepModuleInfos: new Map(), - staticDepModuleInfos: new Map(), - declgenV1OutPath: undefined, - declgenBridgeCodePath: undefined, - language: module.language, - declFilesPath: module.declFilesPath, - dependencies: module.dependencies - }; - this.moduleInfos.set(module.packageName, moduleInfo); - }); - this.collectDepModuleInfos(); - } - - private collectCompileFiles(): void { - this.entryFiles.forEach((file: string) => { - for (const [packageName, moduleInfo] of this.moduleInfos) { - if (!file.startsWith(moduleInfo.moduleRootPath)) { - continue; - } - let filePathFromModuleRoot: string = path.relative(moduleInfo.moduleRootPath, file); - let filePathInCache: string = path.join(this.cacheDir, moduleInfo.packageName, filePathFromModuleRoot); - let abcFilePath: string = path.resolve(changeFileExtension(filePathInCache, ABC_SUFFIX)); - - let fileInfo: CompileFileInfo = { - filePath: file, - dependentFiles: [], - abcFilePath: abcFilePath, - arktsConfigFile: moduleInfo.arktsConfigFile, - packageName: moduleInfo.packageName - }; - moduleInfo.compileFileInfos.push(fileInfo); - this.compileFiles.set(file, fileInfo); - return; - } - console.error('File does not belong to any module in moduleInfos.'); - }); - } - - public generateModuleInfos(): void { - this.collectModuleInfos(); - this.collectCompileFiles(); - } - - public async generateArkTSConfig(compileFileInfos: Record): Promise { - this.generateModuleInfos(); - this.generateArkTSConfigForModules(compileFileInfos); - } -} diff --git a/ets2panda/bindings/src/Es2pandaNativeModule.ts b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts similarity index 43% rename from ets2panda/bindings/src/Es2pandaNativeModule.ts rename to ets2panda/bindings/src/common/Es2pandaNativeModule.ts index 643cb0b3d474542a4150ba62d7038f7e3f61bb07..8695fd8e07401a08cbe41b7a7b62a47b95bba102 100644 --- a/ets2panda/bindings/src/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts @@ -14,8 +14,17 @@ import * as fs from 'fs'; 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 { + KNativePointer as KPtr, + KInt, + KBoolean, + KNativePointer, + KDouble, + KUInt, + KStringPtr, + KInt32ArrayPtr +} from './InteropTypes'; +import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from '../generated/Es2pandaNativeModule'; import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from './loadLibraries'; import { throwError } from './utils'; @@ -45,6 +54,10 @@ export class Es2pandaNativeModule { throw new Error('Not implemented'); } + _GetAllErrorMessages(context: KPtr): KPtr { + throw new Error('Not implemented'); + } + _AstNodeDumpModifiers(context: KPtr, node: KPtr): KPtr { throw new Error('Not implemented'); } @@ -61,11 +74,16 @@ export class Es2pandaNativeModule { _CreateContextFromString(config: KPtr, source: String, filename: String): KPtr { throw new Error('Not implemented'); } + _CreateContextFromStringWithHistory(config: KPtr, source: String, filename: String): KPtr { + throw new Error('Not implemented'); + } _GenerateTsDeclarationsFromContext( config: KPtr, outputDeclEts: String, outputEts: String, - exportAll: KBoolean + exportAll: KBoolean, + isolated: KBoolean, + recordFile: String ): KPtr { throw new Error('Not implemented'); } @@ -145,11 +163,307 @@ export class Es2pandaNativeModule { throw new Error('Not implemented'); } - _getFileNameFromDef(ptr: KNativePointer): KPtr { + _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'); + } + + _getMethodItemsFromClassHierarchyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getPropertyItemsFromClassHierarchyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getDetailFromClassHierarchyItem(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getAccessModifierStyleFromClassHierarchyItem(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getSetterStyleFromClassMethodItem(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'); + } + + _getApplicableRefactorAction(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactorName(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactorDescription(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactors(context: KNativePointer, kind: String, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactorInfoList(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'); + } + + _pushBackToNativeContextVector(context: KNativePointer, contextList: KNativePointer, isNew: KBoolean): 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'); } - _getStartFromDef(ptr: KPtr): KInt { + _GetStartFromDef(ptr: KPtr): KInt { throw new Error('Not implemented'); } @@ -268,7 +582,7 @@ export class Es2pandaNativeModule { throw new Error('Not implemented'); } - _getSpanOfEnclosingComment(filename: String, position: KInt): KPtr { + _getSpanOfEnclosingComment(context: KNativePointer, position: KInt, onlyMultiLine: boolean): KPtr { throw new Error('Not implemented'); } @@ -316,6 +630,14 @@ export class Es2pandaNativeModule { throw new Error('Not implemented'); } + _getSourceLocationLine(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getSourceLocationColumn(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + _getHighlightTextSpan(ptr: KNativePointer): KPtr { throw new Error('Not implemented'); } @@ -431,12 +753,304 @@ export class Es2pandaNativeModule { _toLineColumnOffset(context: KNativePointer, position: KInt): KPtr { throw new Error('Not implemented'); } + + _getSafeDeleteInfo(context: KNativePointer, position: KInt): boolean { + throw new Error('Not implemented'); + } + + _getCodeFixesAtPosition( + context: KNativePointer, + startPosition: KInt, + endPosition: KInt, + errorCodesPtr: KInt32ArrayPtr, + codeLength: KInt + ): KPtr { + throw new Error('Not implemented'); + } + + _getCodeFixActionInfos(infoPtr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFileTextChangesFromCodeActionInfo(infoPtr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getDescriptionFromCodeActionInfo(infoPtr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFixNameFromCodeFixActionInfo(infoPtr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFixIdFromCodeFixActionInfo(infoPtr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFixAllDescriptionFromCodeFixActionInfo(infoPtr: KNativePointer): KPtr { + 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'); + } + + _getRenameLocationFileName(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameLocationStart(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getRenameLocationEnd(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getRenameLocationLine(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _renameLocationHasPrefixText(ptr: KPtr): KBoolean { + throw new Error('Not implemented'); + } + + _getRenameLocationPrefixText(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _renameLocationHasSuffixText(ptr: KPtr): KBoolean { + throw new Error('Not implemented'); + } + + _getRenameLocationSuffixText(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _findRenameLocations(argc: KInt, fileContexts: Uint8Array, context: KNativePointer, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _findRenameLocationsInCurrentFile(context: KNativePointer, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _needsCrossFileRename(context: KNativePointer, position: KInt): KBoolean { + throw new Error('Not implemented'); + } + + _getRenameSuccessFileName(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameSuccessKind(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getRenameSuccessDisplayName(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameSuccessFullDisplayName(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameSuccessKindModifiers(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameSuccessTriggerSpan(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameFailureLocalizedErrorMessage(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameInfoIsSuccess(ptr: KPtr): KBoolean { + throw new Error('Not implemented'); + } + + _getRenameInfoSuccess(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameInfoFailure(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getRenameInfo(context: KNativePointer, position: KInt, pandaLibPath: String): 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'); + } + + _getOffsetByColAndLine(sourceCode: String, line: KInt, column: KInt): KInt { + throw new Error('Not implemented'); + } + + _getColAndLineByOffset(sourceCode: String, offset: KInt): KInt { + throw new Error('Not implemented'); + } + + _MemInitialize(pandaLibPath: KStringPtr): void { + throw new Error('Not implemented'); + } + + _MemFinalize(): void { + throw new Error('Not implemented'); + } + + _CreateGlobalContext(configPtr: KNativePointer, externalFileList: string[] | Uint8Array, fileNum: KInt): KPtr { + throw new Error('Not implemented'); + } + + _DestroyGlobalContext(contextPtr: KPtr): void { + throw new Error('Not implemented'); + } + + _CreateCacheContextFromString( + config: KPtr, + source: String, + filename: String, + globalContext: KPtr, + isExternal: boolean + ): KPtr { + throw new Error('Not implemented'); + } + + _RemoveFileCache(globalContextPtr: KPtr, filename: String): void { + throw new Error('Not implemented'); + } + + _AddFileCache(globalContextPtr: KPtr, filename: String): void { + throw new Error('Not implemented'); + } + + _InvalidateFileCache(globalContextPtr: KPtr, filename: String): void { + throw new Error('Not implemented'); + } + + _getNameByNodeInfo(nodeInfo: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getKindByNodeInfo(nodeInfo: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getNodeInfosByDefinitionData(context: KPtr, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _CreateNodeInfoPtr(nodeName: String, nodeKind: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getProgramAst(context: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getClassDefinition(astNode: KPtr, nodeName: String): KPtr { + throw new Error('Not implemented'); + } + + _getDefinitionDataFromNode(context: KPtr, nodeInfoPtrs: Uint8Array, arraySize: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getIdentifier(astNode: KPtr, nodeName: String): 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'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -452,7 +1066,7 @@ export function initEs2panda(): Es2pandaNativeModule { export function initGeneratedEs2panda(): GeneratedEs2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../ts_bindings.node'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -468,7 +1082,7 @@ export function initGeneratedEs2panda(): GeneratedEs2pandaNativeModule { export function initPublicEs2panda(): Es2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } @@ -484,7 +1098,7 @@ export function initPublicEs2panda(): Es2pandaNativeModule { export function initPublicGeneratedEs2panda(): GeneratedEs2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } diff --git a/ets2panda/bindings/src/InteropNativeModule.ts b/ets2panda/bindings/src/common/InteropNativeModule.ts similarity index 94% rename from ets2panda/bindings/src/InteropNativeModule.ts rename to ets2panda/bindings/src/common/InteropNativeModule.ts index 35eac9b80641b233c9e1c5e4add9fb2f7d995224..a404fce1491ae50a1646650b13aab1c0ae3e6d79 100644 --- a/ets2panda/bindings/src/InteropNativeModule.ts +++ b/ets2panda/bindings/src/common/InteropNativeModule.ts @@ -48,7 +48,7 @@ export class InteropNativeModule { throw new Error('Not implemented'); } - _getIntFromVariant(ptr: KPtr): KInt { + _GetIntFromVariant(ptr: KPtr): KInt { throw new Error('Not implemented'); } @@ -60,7 +60,7 @@ export class InteropNativeModule { export function initInterop(): InteropNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../ts_bindings.node'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -76,7 +76,7 @@ export function initInterop(): InteropNativeModule { export function initPublicInterop(): InteropNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } diff --git a/ets2panda/bindings/src/InteropTypes.ts b/ets2panda/bindings/src/common/InteropTypes.ts similarity index 100% rename from ets2panda/bindings/src/InteropTypes.ts rename to ets2panda/bindings/src/common/InteropTypes.ts diff --git a/ets2panda/bindings/src/Platform.ts b/ets2panda/bindings/src/common/Platform.ts similarity index 100% rename from ets2panda/bindings/src/Platform.ts rename to ets2panda/bindings/src/common/Platform.ts diff --git a/ets2panda/bindings/src/Wrapper.ts b/ets2panda/bindings/src/common/Wrapper.ts similarity index 100% rename from ets2panda/bindings/src/Wrapper.ts rename to ets2panda/bindings/src/common/Wrapper.ts diff --git a/ets2panda/bindings/src/build/generateArkTSConfig.ts b/ets2panda/bindings/src/common/arkTSConfigGenerator.ts similarity index 30% rename from ets2panda/bindings/src/build/generateArkTSConfig.ts rename to ets2panda/bindings/src/common/arkTSConfigGenerator.ts index fe1dc108fc57d5604614ef0e4498e76d8f1b21c5..23998489346c34cf426f44cd4aff0c7f626817fd 100644 --- a/ets2panda/bindings/src/build/generateArkTSConfig.ts +++ b/ets2panda/bindings/src/common/arkTSConfigGenerator.ts @@ -16,14 +16,15 @@ 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, getFileLanguageVersion } from './utils'; +import { BuildConfig, ModuleInfo } from './types'; +import { LANGUAGE_VERSION, PANDA_SDK_PATH_FROM_SDK, SYSTEM_SDK_PATH_FROM_SDK } from './preDefine'; -interface DynamicPathItem { +interface DependencyItem { language: string; - declPath: string; - runtimeName: string; + path: string; + ohmUrl?: string; + alias?: string[]; } interface ArkTSConfigObject { @@ -31,9 +32,8 @@ interface ArkTSConfigObject { package: string; baseUrl: string; paths: Record; - dependencies: string[] | undefined; entry: string; - dynamicPaths: Record; + dependencies: Record; }; } @@ -42,22 +42,26 @@ export class ArkTSConfigGenerator { private stdlibStdPath: string; private stdlibEscompatPath: string; private systemSdkPath: string; + private externalApiPath: string; + private interopApiPath: string; - private moduleInfos: Map; + private moduleInfos: Record; private pathSection: Record; - private constructor(buildConfig: BuildConfig, moduleInfos: Map) { - let pandaStdlibPath: string = - buildConfig.pandaStdlibPath ?? path.resolve(buildConfig.pandaSdkPath!!, 'lib', 'stdlib'); + private constructor(buildConfig: BuildConfig, moduleInfos: Record) { + let pandaSdkPath = path.resolve(buildConfig.buildSdkPath, PANDA_SDK_PATH_FROM_SDK); + let pandaStdlibPath: string = path.resolve(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); + this.externalApiPath = buildConfig.externalApiPath !== undefined ? buildConfig.externalApiPath : ''; + this.interopApiPath = buildConfig.interopApiPath !== undefined ? buildConfig.interopApiPath : ''; this.moduleInfos = moduleInfos; this.pathSection = {}; } - public static getInstance(buildConfig?: BuildConfig, moduleInfos?: Map): ArkTSConfigGenerator { + public static getInstance(buildConfig?: BuildConfig, moduleInfos?: Record): ArkTSConfigGenerator { if (!ArkTSConfigGenerator.instance) { if (!buildConfig || !moduleInfos) { throw new Error('buildConfig and moduleInfos is required for the first instantiation of ArkTSConfigGenerator.'); @@ -67,7 +71,7 @@ export class ArkTSConfigGenerator { return ArkTSConfigGenerator.instance; } - public static getGenerator(buildConfig: BuildConfig, moduleInfos: Map): ArkTSConfigGenerator { + public static getGenerator(buildConfig: BuildConfig, moduleInfos: Record): ArkTSConfigGenerator { return new ArkTSConfigGenerator(buildConfig, moduleInfos); } @@ -75,41 +79,84 @@ export class ArkTSConfigGenerator { ArkTSConfigGenerator.instance = undefined; } - private generateSystemSdkPathSection(pathSection: Record): void { - 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); - const stat = fs.statSync(itemPath); - - if (stat.isFile()) { - const basename = path.basename(item, '.d.ets'); - const key = isExcludedDir ? basename : relativePath ? `${relativePath}.${basename}` : basename; - pathSection[key] = [changeFileExtension(itemPath, '', '.d.ets')]; - } - if (stat.isDirectory()) { - // For non-arkui files under api dir, - // fill path section with `"pathFromApi.subdir.fileName" = [${absolute_path_to_file}]`; - // 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; - traverse(path.resolve(currentDir, item), newRelativePath, isCurrentDirExcluded || isExcludedDir); - } + private traverse( + pathSection: Record, + currentDir: string, + prefix: string = '', + isInteropSdk: boolean = false, + relativePath: string = '', + isExcludedDir: boolean = false, + allowedExtensions: string[] = ['.d.ets'] + ): void { + const items = fs.readdirSync(currentDir); + for (const item of items) { + const itemPath = path.join(currentDir, item); + const stat = fs.statSync(itemPath); + const isAllowedFile = allowedExtensions.some((ext) => item.endsWith(ext)); + const separator = isInteropSdk ? '/' : '.'; + if (stat.isFile() && !isAllowedFile) { + continue; } - } - let apiPath: string = path.resolve(this.systemSdkPath, 'api'); - fs.existsSync(apiPath) ? traverse(apiPath) : console.error(`sdk path ${apiPath} not exist.`); + if (stat.isFile()) { + const basename = path.basename(item, '.d.ets'); + const key = isExcludedDir ? basename : relativePath ? `${relativePath}${separator}${basename}` : basename; + pathSection[prefix + key] = isInteropSdk + ? { + language: 'js', + path: itemPath, + ohmUrl: '', + alias: [key] + } + : [changeFileExtension(itemPath, '', '.d.ets')]; + } + if (stat.isDirectory()) { + // For files under api dir excluding arkui/runtime-api dir, + // fill path section with `"pathFromApi.subdir.fileName" = [${absolute_path_to_file}]`; + // For @koalaui files under arkui/runtime-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}${separator}${item}` : item; + this.traverse( + pathSection, + path.resolve(currentDir, item), + prefix, + isInteropSdk, + newRelativePath, + isCurrentDirExcluded || isExcludedDir + ); + } + } + } - let arktsPath: string = path.resolve(this.systemSdkPath, 'arkts'); - fs.existsSync(arktsPath) ? traverse(arktsPath) : console.error(`sdk path ${arktsPath} not exist.`); + private generateSystemSdkPathSection(pathSection: Record): void { + let directoryNames: string[] = ['api', 'arkts', 'kits']; + directoryNames.forEach((dir) => { + let systemSdkPath = path.resolve(this.systemSdkPath, dir); + let externalApiPath = path.resolve(this.externalApiPath, dir); + fs.existsSync(systemSdkPath) + ? this.traverse(pathSection, systemSdkPath) + : console.warn(`sdk path ${systemSdkPath} not exist.`); + fs.existsSync(externalApiPath) + ? this.traverse(pathSection, externalApiPath) + : console.warn(`sdk path ${externalApiPath} not exist.`); + }); + } - let kitsPath: string = path.resolve(this.systemSdkPath, 'kits'); - fs.existsSync(kitsPath) ? traverse(kitsPath) : console.error(`sdk path ${kitsPath} not exist.`); + private getAlias(fullPath: string, entryRoot: string, packageName: string): string { + const normalizedFull = path.normalize(fullPath); + const normalizedEntry = path.normalize(entryRoot); + const entryDir = normalizedEntry.endsWith(path.sep) ? normalizedEntry : normalizedEntry + path.sep; + if (!normalizedFull.startsWith(entryDir)) { + throw new Error(`Path ${fullPath} is not under entry root ${entryRoot}`); + } + const relativePath = normalizedFull.substring(entryDir.length); + const formatPath = path.join(packageName, relativePath).replace(/\\/g, '/'); + const alias = formatPath; + return changeFileExtension(alias, ''); } - private getPathSection(): Record { + private getPathSection(moduleInfo: ModuleInfo): Record { if (Object.keys(this.pathSection).length !== 0) { return this.pathSection; } @@ -119,20 +166,34 @@ export class ArkTSConfigGenerator { 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])]; + Object.values(moduleInfo.staticDepModuleInfos).forEach((depModuleName: string) => { + let depModuleInfo = this.moduleInfos[depModuleName]; + if (depModuleInfo.language === LANGUAGE_VERSION.ARKTS_1_2) { + this.pathSection[depModuleInfo.packageName] = [path.resolve(depModuleInfo.moduleRootPath)]; + } else if (depModuleInfo.language === LANGUAGE_VERSION.ARKTS_HYBRID) { + depModuleInfo.compileFiles.forEach((file) => { + const firstLine = fs.readFileSync(file, 'utf-8').split('\n')[0]; + if (firstLine.includes('use static')) { + this.pathSection[this.getAlias(file, depModuleInfo.moduleRootPath, depModuleInfo.packageName)] = [ + path.resolve(file) + ]; + } + }); } }); - return this.pathSection; - } + if (moduleInfo.language === LANGUAGE_VERSION.ARKTS_HYBRID) { + moduleInfo.compileFiles.forEach((file) => { + const firstLine = fs.readFileSync(file, 'utf-8').split('\n')[0]; + if (getFileLanguageVersion(firstLine) === LANGUAGE_VERSION.ARKTS_1_2) { + this.pathSection[this.getAlias(file, moduleInfo.moduleRootPath, moduleInfo.packageName)] = [ + path.resolve(file) + ]; + } + }); + } - private getDependenciesSection(moduleInfo: ModuleInfo, dependenciesSection: string[]): void { - let depModules: Map = moduleInfo.staticDepModuleInfos; - depModules.forEach((depModuleInfo: ModuleInfo) => { - dependenciesSection.push(depModuleInfo.arktsConfigFile); - }); + return this.pathSection; } private getOhmurl(file: string, moduleInfo: ModuleInfo): string { @@ -141,51 +202,71 @@ export class ArkTSConfigGenerator { return changeFileExtension(ohmurl, ''); } - private getDynamicPathSection(moduleInfo: ModuleInfo, dynamicPathSection: Record): void { - let depModules: Map = moduleInfo.dynamicDepModuleInfos; + private parseDeclFile(moduleInfo: ModuleInfo, dependencySection: Record) { + if (!moduleInfo.declFilesPath || !fs.existsSync(moduleInfo.declFilesPath)) { + console.error(`Module ${moduleInfo.packageName} depends on dynamic module ${moduleInfo.packageName}, but + decl file not found on path ${moduleInfo.declFilesPath}`); + return; + } + let declFilesObject = JSON.parse(fs.readFileSync(moduleInfo.declFilesPath, 'utf-8')); + Object.keys(declFilesObject.files).forEach((file: string) => { + let ohmurl: string = this.getOhmurl(file, moduleInfo); + dependencySection[ohmurl] = { + language: 'js', + path: declFilesObject.files[file].declPath, + ohmUrl: declFilesObject.files[file].ohmUrl + }; + + let absFilePath: string = path.resolve(moduleInfo.moduleRootPath, file); + let entryFileWithoutExtension: string = changeFileExtension(moduleInfo.entryFile, ''); + if (absFilePath === entryFileWithoutExtension) { + dependencySection[moduleInfo.packageName] = dependencySection[ohmurl]; + } + }); + } - depModules.forEach((depModuleInfo: ModuleInfo) => { - if (!depModuleInfo.declFilesPath || !fs.existsSync(depModuleInfo.declFilesPath)) { - console.error(`Module ${moduleInfo.packageName} depends on dynamic module ${depModuleInfo.packageName}, but - decl file not found on path ${depModuleInfo.declFilesPath}`); + private generateSystemSdkDependenciesSection(dependencySection: Record): void { + let directoryNames: string[] = ['api', 'arkts', 'kits', 'component']; + directoryNames.forEach((dirName) => { + const basePath = path.resolve(this.interopApiPath, dirName); + if (!fs.existsSync(basePath)) { + console.warn(`interop sdk path ${basePath} not exist.`); return; } - let declFilesObject = JSON.parse(fs.readFileSync(depModuleInfo.declFilesPath, 'utf-8')); - Object.keys(declFilesObject.files).forEach((file: string) => { - let ohmurl: string = this.getOhmurl(file, depModuleInfo); - dynamicPathSection[ohmurl] = { - 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, ''); - if (absFilePath === entryFileWithoutExtension) { - dynamicPathSection[depModuleInfo.packageName] = dynamicPathSection[ohmurl]; - } - }); + if (dirName === 'component') { + this.traverse(dependencySection, basePath, 'component/', true); + } else { + this.traverse(dependencySection, basePath, 'dynamic/', true); + } }); } - public writeArkTSConfigFile(moduleInfo: ModuleInfo): void { - if (!moduleInfo.sourceRoots || moduleInfo.sourceRoots.length === 0) { - console.error('SourceRoots not set from hvigor.'); + private getDependenciesSection(moduleInfo: ModuleInfo, dependencySection: Record): void { + this.generateSystemSdkDependenciesSection(dependencySection); + let depModules: string[] = moduleInfo.dynamicDepModuleInfos; + depModules.forEach((depModuleName: string) => { + let depModuleInfo = this.moduleInfos[depModuleName]; + this.parseDeclFile(depModuleInfo, dependencySection); + }); + + if (moduleInfo.language === LANGUAGE_VERSION.ARKTS_HYBRID) { + this.parseDeclFile(moduleInfo, dependencySection); } - let pathSection = this.getPathSection(); - let dependenciesSection: string[] = []; - let dynamicPathSection: Record = {}; - this.getDynamicPathSection(moduleInfo, dynamicPathSection); + } + + public writeArkTSConfigFile(moduleInfo: ModuleInfo): void { + let pathSection = this.getPathSection(moduleInfo); + let dependencySection: Record = {}; + this.getDependenciesSection(moduleInfo, dependencySection); - let baseUrl: string = path.resolve(moduleInfo.moduleRootPath, moduleInfo.sourceRoots[0]); + let baseUrl: string = path.resolve(moduleInfo.moduleRootPath); let arktsConfig: ArkTSConfigObject = { compilerOptions: { package: moduleInfo.packageName, baseUrl: baseUrl, paths: pathSection, - dependencies: dependenciesSection.length === 0 ? undefined : dependenciesSection, entry: moduleInfo.entryFile, - dynamicPaths: dynamicPathSection + dependencies: dependencySection } }; diff --git a/ets2panda/bindings/src/arrays.ts b/ets2panda/bindings/src/common/arrays.ts similarity index 94% rename from ets2panda/bindings/src/arrays.ts rename to ets2panda/bindings/src/common/arrays.ts index d0fe7499458c408d5b0467407f3d97bfc65007ab..75483d12dbba15e807d3867b1afadc17fafa3002 100644 --- a/ets2panda/bindings/src/arrays.ts +++ b/ets2panda/bindings/src/common/arrays.ts @@ -42,6 +42,15 @@ export function withStringArray(strings: Array | undefined): Uint8Array return array; } +export function withBigingArray(bigints: Array | undefined): Uint8Array { + if (bigints === undefined || bigints.length === 0) { + throwError('Error in strings array'); + } + + let array = encoder.encodeBigintArray(bigints); + return array; +} + function withArray(data: C | undefined, exec: ExecWithLength): R { return exec(data ?? null, data?.length ?? 0); } diff --git a/ets2panda/bindings/src/driver_helper.ts b/ets2panda/bindings/src/common/driver_helper.ts similarity index 69% rename from ets2panda/bindings/src/driver_helper.ts rename to ets2panda/bindings/src/common/driver_helper.ts index 29f82f3d0133095d21558faa4e4d3a501234b6ac..0f3b97b9435a633f6f3031ae098467dde97d543e 100644 --- a/ets2panda/bindings/src/driver_helper.ts +++ b/ets2panda/bindings/src/common/driver_helper.ts @@ -16,9 +16,10 @@ import { Context, Config } from './types'; import { global } from './global'; import { throwError } from './utils'; -import { Es2pandaContextState } from './generated/Es2pandaEnums'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; import { withStringResult } from './Platform'; -import { KBoolean, KNativePointer, KPointer } from './InteropTypes'; +import { KBoolean, KInt, KNativePointer, KPointer } from './InteropTypes'; +import { passStringArray } from './private'; export class DriverHelper { constructor(filePath: string, cmd: string[]) { @@ -76,19 +77,59 @@ export class DriverHelper { global.destroyCfg(); } - public generateTsDecl(declOutPath: string, etsOutPath: string, exportAll: boolean): void { + public generateTsDecl( + declOutPath: string, + etsOutPath: string, + exportAll: boolean, + isolated: boolean, + recordFile: string + ): void { let exportAll_: KBoolean = exportAll ? 1 : 0; - global.es2panda._GenerateTsDeclarationsFromContext(this._cfg.peer, declOutPath, etsOutPath, exportAll_); + let isolated_: KBoolean = isolated ? 1 : 0; + global.es2panda._GenerateTsDeclarationsFromContext( + this._cfg.peer, + declOutPath, + etsOutPath, + exportAll_, + isolated_, + recordFile + ); } } export class LspDriverHelper { - public createCfg(cmd: string[], filePath: string, pandaLibPath: string): Config { + public memInitialize(pandaLibPath: string): void { + global.es2pandaPublic._MemInitialize(pandaLibPath); + } + + public memFinalize(): void { + global.es2pandaPublic._MemFinalize(); + } + + public createGlobalContext(config: KNativePointer, externalFileList: string[], fileNum: KInt): KNativePointer { + return global.es2pandaPublic._CreateGlobalContext(config, passStringArray(externalFileList), fileNum); + } + + public destroyGlobalContext(context: KNativePointer): void { + global.es2pandaPublic._DestroyGlobalContext(context); + } + + 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); + public createCtx( + source: string, + filePath: string, + cfg: Config, + globalContextPtr?: KNativePointer, + isExternal: boolean = false + ): KNativePointer { + if (globalContextPtr) { + return Context.lspCreateCacheContextFromString(source, filePath, cfg, globalContextPtr, isExternal); + } else { + return Context.lspCreateFromString(source, filePath, cfg); + } } public proceedToState(ctx: KNativePointer, state: Es2pandaContextState): void { diff --git a/ets2panda/bindings/src/global.ts b/ets2panda/bindings/src/common/global.ts similarity index 97% rename from ets2panda/bindings/src/global.ts rename to ets2panda/bindings/src/common/global.ts index 2c99dce5caf8834048741b4c88d1f713df2cd8d1..b6841d5e5fb6dd6ecd41df67f522238b72bdc3ce 100644 --- a/ets2panda/bindings/src/global.ts +++ b/ets2panda/bindings/src/common/global.ts @@ -22,9 +22,8 @@ import { initPublicEs2panda, initPublicGeneratedEs2panda } from './Es2pandaNativeModule'; -import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from './generated/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 { diff --git a/ets2panda/bindings/src/loadLibraries.ts b/ets2panda/bindings/src/common/loadLibraries.ts similarity index 100% rename from ets2panda/bindings/src/loadLibraries.ts rename to ets2panda/bindings/src/common/loadLibraries.ts diff --git a/ets2panda/bindings/src/mainWrapper.ts b/ets2panda/bindings/src/common/mainWrapper.ts similarity index 100% rename from ets2panda/bindings/src/mainWrapper.ts rename to ets2panda/bindings/src/common/mainWrapper.ts diff --git a/ets2panda/bindings/src/preDefine.ts b/ets2panda/bindings/src/common/preDefine.ts similarity index 72% rename from ets2panda/bindings/src/preDefine.ts rename to ets2panda/bindings/src/common/preDefine.ts index b0dc4d7f85d7414a5494160cebb02e6b18b62b68..30bec4a221436c5178e5d7c880246dcd222bb9d6 100644 --- a/ets2panda/bindings/src/preDefine.ts +++ b/ets2panda/bindings/src/common/preDefine.ts @@ -15,13 +15,17 @@ export const ARKTSCONFIG_JSON_FILE: string = 'arktsconfig.json'; -export const ABC_SUFFIX: string = '.abc'; - export enum LANGUAGE_VERSION { ARKTS_1_2 = '1.2', ARKTS_1_1 = '1.1', ARKTS_HYBRID = 'hybrid' } +export const DECL_ETS_SUFFIX: string = '.d.ets'; export const PANDA_SDK_PATH_FROM_SDK: string = './build-tools/ets2panda'; export const SYSTEM_SDK_PATH_FROM_SDK: string = './'; +export const EXTERNAL_API_PATH_FROM_SDK: string = '../../../hms/ets/ets1.2'; +export const INTEROP_API_PATH_FROM_SDK: string = '../ets1.1/build-tools/interop'; +export const DEFAULT_CACHE_DIR: string = './.idea/.deveco'; +export const ETS_SUFFIX: string = '.ets'; +export const TS_SUFFIX: string = '.ts'; diff --git a/ets2panda/bindings/src/private.ts b/ets2panda/bindings/src/common/private.ts similarity index 87% rename from ets2panda/bindings/src/private.ts rename to ets2panda/bindings/src/common/private.ts index 777aad9066bcee2f3e76ede341d48ea2057b884e..3ad06d3be69edede57a0f02e5bcbaafbca66c6b8 100644 --- a/ets2panda/bindings/src/private.ts +++ b/ets2panda/bindings/src/common/private.ts @@ -15,9 +15,9 @@ import { throwError } from './utils'; import { KNativePointer, nullptr } from './InteropTypes'; -import { withString, withStringArray } from './arrays'; +import { withString, withStringArray, withBigingArray } from './arrays'; import { NativePtrDecoder, withStringResult } from './Platform'; -import { LspDiagsNode, LspNode } from './lspNode'; +import { LspDiagsNode, LspNode } from '../lsp/lspNode'; export function lspData(peer: KNativePointer): LspNode { return new LspDiagsNode(peer); @@ -63,3 +63,7 @@ export function passString(str: string | undefined): string { export function passStringArray(strings: string[]): Uint8Array { return withStringArray(strings); } + +export function passPointerArray(pointers: KNativePointer[]): Uint8Array { + return withBigingArray(pointers.map((pointer) => BigInt(Number(pointer)))); +} diff --git a/ets2panda/bindings/src/strings.ts b/ets2panda/bindings/src/common/strings.ts similarity index 86% rename from ets2panda/bindings/src/strings.ts rename to ets2panda/bindings/src/common/strings.ts index ff72c1626e279be2e4e2a098b25fac2aaa3d84f5..4e0a118ad1b41663ae8cdcfa330936b90eaf35d1 100644 --- a/ets2panda/bindings/src/strings.ts +++ b/ets2panda/bindings/src/common/strings.ts @@ -122,6 +122,37 @@ export class CustomTextEncoder { return array; } + encodedBigintLength(value: bigint): int32 { + let str = value.toString(); + return this.encodedLength(str); + } + + encodeBigintInto(value: bigint, result: Uint8Array, position: int32): Uint8Array { + let str = value.toString(); + return this.encodeInto(str, result, position); + } + + encodeBigintArray(bigints: Array): Uint8Array { + let totalBytes = CustomTextEncoder.HeaderLen; + let lengths = new Int32Array(bigints.length); + for (let i = 0; i < lengths.length; i++) { + let len = this.encodedBigintLength(bigints[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; + for (let i = 0; i < lengths.length; i++) { + this.addLength(array, position, lengths[i]); + position += CustomTextEncoder.HeaderLen; + this.encodeBigintInto(bigints[i], array, position); + position += lengths[i]; + } + return array; + } + encodeInto(input: string, result: Uint8Array, position: int32): Uint8Array { if (this.encoder !== undefined) { this.encoder!.encodeInto(input, result.subarray(position, result.length)); diff --git a/ets2panda/bindings/src/ts-reflection.ts b/ets2panda/bindings/src/common/ts-reflection.ts similarity index 100% rename from ets2panda/bindings/src/ts-reflection.ts rename to ets2panda/bindings/src/common/ts-reflection.ts diff --git a/ets2panda/bindings/src/types.ts b/ets2panda/bindings/src/common/types.ts similarity index 56% rename from ets2panda/bindings/src/types.ts rename to ets2panda/bindings/src/common/types.ts index 2a34d968b7c5a540cb7d7cfa7f17e0c7622eb623..39fc958ab7a167174b9d00ceab569414fa81d051 100644 --- a/ets2panda/bindings/src/types.ts +++ b/ets2panda/bindings/src/common/types.ts @@ -13,11 +13,12 @@ * limitations under the License. */ -import { KNativePointer as KPtr } from './InteropTypes'; +import { KNativePointer, KNativePointer as KPtr } from './InteropTypes'; import { global } from './global'; import { throwError } from './utils'; import { passString, passStringArray, unpackString } from './private'; import { isNullPtr } from './Wrapper'; +import { Worker as ThreadWorker } from 'worker_threads'; export const arrayOfNullptr = new BigUint64Array([BigInt(0)]); @@ -103,12 +104,44 @@ export class Context extends ArktsObject { ); } + static createFromStringWithHistory(source: string): Context { + if (!global.configIsInitialized()) { + throwError(`Config not initialized`); + } + return new Context( + global.es2panda._CreateContextFromStringWithHistory( + global.config, + passString(source), + passString(global.filePath) + ) + ); + } + static lspCreateFromString(source: string, filePath: string, cfg: Config): KPtr { if (cfg === undefined) { throwError(`Config not initialized`); } return global.es2pandaPublic._CreateContextFromString(cfg.peer, passString(source), passString(filePath)); } + + static lspCreateCacheContextFromString( + source: string, + filePath: string, + cfg: Config, + globalContextPtr: KNativePointer, + isExternal: boolean + ): KPtr { + if (cfg === undefined) { + throwError(`Config not initialized`); + } + return global.es2pandaPublic._CreateCacheContextFromString( + cfg.peer, + passString(source), + passString(filePath), + globalContextPtr, + isExternal + ); + } } // ProjectConfig begins @@ -116,83 +149,139 @@ export interface PluginsConfig { [pluginName: string]: string; } -export interface BuildBaseConfig { - buildType: 'build' | 'preview' | 'hotreload' | 'coldreload'; - buildMode: 'Debug' | 'Release'; - hasMainModule: boolean; - arkts: object; - arktsGlobal: object; -} - export interface ModuleConfig { packageName: string; moduleType: string; moduleRootPath: string; - sourceRoots: string[]; + language: string; + declFilesPath?: string; + dependencies?: string[]; } 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 - abcLinkerPath?: string; + projectPath: string; + declgenOutDir: string; + cacheDir?: string; + externalApiPath?: string; + aceModuleJsonPath?: string; + interopApiPath?: string; } export interface DeclgenConfig { - enableDeclgenEts2Ts: boolean; declgenV1OutPath?: string; declgenBridgeCodePath?: string; } -export interface LoggerConfig { - getHvigorConsoleLogger?: Function; -} - -export interface DependentModuleConfig { - packageName: string; - moduleName: string; - moduleType: string; - modulePath: string; - sourceRoots: string[]; - entryFile: string; - language: string; - declFilesPath?: string; - dependencies?: string[]; -} - -export interface BuildConfig extends BuildBaseConfig, DeclgenConfig, LoggerConfig, ModuleConfig, PathConfig { +export interface BuildConfig extends DeclgenConfig, ModuleConfig, PathConfig { plugins: PluginsConfig; compileFiles: string[]; - dependentModuleList: DependentModuleConfig[]; + depModuleCompileFiles: string[]; } // ProjectConfig ends -export interface CompileFileInfo { - 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[]; + compileFiles: string[]; + depModuleCompileFiles: string[]; declgenV1OutPath: string | undefined; declgenBridgeCodePath: string | undefined; + staticDepModuleInfos: string[]; + dynamicDepModuleInfos: string[]; + language: string; dependencies?: string[]; - staticDepModuleInfos: Map; - dynamicDepModuleInfos: Map; - language?: string; declFilesPath?: string; } + +export interface Job { + id: string; + isDeclFile: boolean; + isInCycle?: boolean; + fileList: string[]; + dependencies: string[]; + dependants: string[]; + isValid: boolean; +} + +export interface JobInfo { + id: string; + filePath: string; + arktsConfigFile: string; + globalContextPtr: KNativePointer; + buildConfig: BuildConfig; + isValid: boolean; +} + +export interface FileDepsInfo { + dependencies: Record; + dependants: Record; +} + +export interface WorkerInfo { + worker: ThreadWorker; + isIdle: boolean; +} +export interface TextDocumentChangeInfo { + newDoc: string; + rangeStart?: number; + rangeEnd?: number; + updateText?: string; +} + +export enum AstNodeType { + ANNOTATION_DECLARATION = 1, + ANNOTATION_USAGE = 2, + AWAIT_EXPRESSION = 4, + CALL_EXPRESSION = 10, + CLASS_DEFINITION = 14, + CLASS_DECLARATION = 15, + CLASS_PROPERTY = 17, + EMPTY_STATEMENT = 25, + EXPORT_DEFAULT_DECLARATION = 27, + EXPORT_NAMED_DECLARATION = 28, + EXPORT_SPECIFIER = 29, + EXPRESSION_STATEMENT = 30, + FUNCTION_EXPRESSION = 35, + IDENTIFIER = 36, + IMPORT_DECLARATION = 39, + IMPORT_DEFAULT_SPECIFIER = 41, + IMPORT_NAMESPACE_SPECIFIER = 42, + IMPORT_SPECIFIER = 43, + MEMBER_EXPRESSION = 45, + METHOD_DEFINITION = 47, + PROPERTY = 56, + REEXPORT_STATEMENT = 58, + RETURN_STATEMENT = 59, + SCRIPT_FUNCTION = 60, + ETS_STRING_LITERAL_TYPE = 67, + ETS_FUNCTION_TYPE = 69, + ETS_TYPE_REFERENCE = 74, + ETS_KEYOF_TYPE = 77, + ETS_NEW_CLASS_INSTANCE_EXPRESSION = 80, + ETS_IMPORT_DECLARATION = 81, + ETS_PARAMETER_EXPRESSION = 82, + SUPER_EXPRESSION = 85, + STRUCT_DECLARATION = 86, + TS_ENUM_DECLARATION = 89, + TS_ENUM_MEMBER = 90, + TS_TYPE_PARAMETER = 120, + TS_FUNCTION_TYPE = 127, + TS_MODULE_DECLARATION = 125, + TS_TYPE_ALIAS_DECLARATION = 129, + TS_TYPE_REFERENCE = 130, + TS_INTERFACE_DECLARATION = 133, + TS_CLASS_IMPLEMENTS = 141, + VARIABLE_DECLARATION = 152, + VARIABLE_DECLARATOR = 153, + SPREAD_ELEMENT = 165, + UNKNOWN, +} + +export interface NodeInfo { + name: string; + kind: AstNodeType; +} diff --git a/ets2panda/bindings/src/ui_plugins_driver.ts b/ets2panda/bindings/src/common/ui_plugins_driver.ts similarity index 93% rename from ets2panda/bindings/src/ui_plugins_driver.ts rename to ets2panda/bindings/src/common/ui_plugins_driver.ts index 1d30fb980313a62dfab333d979f6b776ca207725..464cd6b396dc8ef61bd9036fdb0dd07084331c12 100644 --- a/ets2panda/bindings/src/ui_plugins_driver.ts +++ b/ets2panda/bindings/src/common/ui_plugins_driver.ts @@ -65,12 +65,14 @@ class PluginContext { private program: object | undefined; private projectConfig: object | undefined; private contextPtr: KNativePointer | undefined; + private codingFilePath: string | undefined; constructor() { this.ast = undefined; this.program = undefined; this.projectConfig = undefined; this.contextPtr = undefined; + this.codingFilePath = undefined; } public setArkTSAst(ast: object): void { @@ -104,6 +106,18 @@ class PluginContext { public getContextPtr(): KNativePointer | undefined { return this.contextPtr; } + + public setCodingFilePath(codingFilePath: string): void { + this.codingFilePath = codingFilePath; + } + + public getCodingFilePath(): string | undefined { + return this.codingFilePath; + } + + public isCoding(): boolean { + return this.codingFilePath !== undefined; + } } export class PluginDriver { diff --git a/ets2panda/bindings/src/common/utils.ts b/ets2panda/bindings/src/common/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..43e3d21f0d00a7b202ac76ab264b2e6ba011260a --- /dev/null +++ b/ets2panda/bindings/src/common/utils.ts @@ -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. + */ + +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import { DECL_ETS_SUFFIX, LANGUAGE_VERSION } from './preDefine'; + +export function throwError(error: string): never { + throw new Error(error); +} + +export function withWarning(value: T, message: string): T { + console.warn(message); + return value; +} + +export function changeFileExtension(file: string, targetExt: string, originExt = ''): string { + let currentExt = originExt.length === 0 ? path.extname(file) : originExt; + let fileWithoutExt = file.substring(0, file.lastIndexOf(currentExt)); + return fileWithoutExt + targetExt; +} + +export function ensurePathExists(filePath: string): void { + try { + const dirPath: string = path.dirname(filePath); + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } + } catch (error) { + if (error instanceof Error) { + console.error(`Error: ${error.message}`); + } + } +} + +export function isMac(): boolean { + return os.type() === 'Darwin'; +} + +export function changeDeclgenFileExtension(file: string, targetExt: string): string { + if (file.endsWith(DECL_ETS_SUFFIX)) { + return changeFileExtension(file, targetExt, DECL_ETS_SUFFIX); + } + return changeFileExtension(file, targetExt); +} + +export function getModuleNameAndPath(filePath: string, projectPath: string): [string, string] { + let moduleName: string = ''; + let moduleRootPath: string = ''; + if (filePath.indexOf(projectPath) >= 0) { + const relativePath = path.relative(projectPath, filePath); + moduleName = relativePath.split(path.sep)[0]; + moduleRootPath = path.join(projectPath, moduleName); + } + return [moduleName, moduleRootPath]; +} + +// Skip comment, check whether the first valid line contains 'use static'. +export function getFileLanguageVersion(fileSource: string): string { + const lines = fileSource.split('\n'); + let inMultiLineComment = false; + let effectiveLine = ''; + + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + + if (inMultiLineComment) { + const endIndex = line.indexOf('*/'); + if (endIndex !== -1) { + line = line.substring(endIndex + 2); + inMultiLineComment = false; + } else { + continue; + } + } + + const singleLineIndex = line.indexOf('//'); + if (singleLineIndex !== -1) { + line = line.substring(0, singleLineIndex); + } + + const multiLineStart = line.indexOf('/*'); + if (multiLineStart !== -1) { + const multiLineEnd = line.indexOf('*/', multiLineStart + 2); + if (multiLineEnd !== -1) { + line = line.substring(0, multiLineStart) + line.substring(multiLineEnd + 2); + } else { + line = line.substring(0, multiLineStart); + inMultiLineComment = true; + } + } + + const trimmedLine = line.trim(); + if (trimmedLine === '') { + continue; + } + + effectiveLine = trimmedLine; + break; + } + + if (effectiveLine.includes('use static')) { + return LANGUAGE_VERSION.ARKTS_1_2; + } + + return LANGUAGE_VERSION.ARKTS_1_1; +} 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 8bd49b74b2f0d7c05b5b93ba613015467b5282c1..bb53f1d512a49c81af2aaf9a797748ea9f96f4d7 100644 --- a/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { KBoolean, KInt, KNativePointer } from '../InteropTypes'; +import { KBoolean, KInt, KNativePointer } from '../common/InteropTypes'; export class Es2pandaNativeModule { _CreateMemberExpression( diff --git a/ets2panda/bindings/src/index.ts b/ets2panda/bindings/src/index.ts index ac1bbaaa34841ab4040ecfec43baa0e300dc1017..d508b948c88a327860440a69dc67f46dfc34172e 100644 --- a/ets2panda/bindings/src/index.ts +++ b/ets2panda/bindings/src/index.ts @@ -13,18 +13,4 @@ * 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 type { ModuleDescriptor } from './buildConfigGenerate'; +export * from './lsp/index'; diff --git a/ets2panda/bindings/src/lsp/compile_thread_worker.ts b/ets2panda/bindings/src/lsp/compile_thread_worker.ts new file mode 100644 index 0000000000000000000000000000000000000000..572ad8e0ab9d0333617f17d66c51c0280b3a31d4 --- /dev/null +++ b/ets2panda/bindings/src/lsp/compile_thread_worker.ts @@ -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. + */ + +import { parentPort, workerData } from 'worker_threads'; +import * as fs from 'fs'; +import { PluginDriver, PluginHook } from '../common/ui_plugins_driver'; +import { LspDriverHelper } from '../common/driver_helper'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; +import { JobInfo } from '../common/types'; + +const { workerId } = workerData; + +function compileExternalProgram(jobInfo: JobInfo): void { + PluginDriver.getInstance().initPlugins(jobInfo.buildConfig); + let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', jobInfo.arktsConfigFile]; + let lspDriverHelper = new LspDriverHelper(); + let config = lspDriverHelper.createCfg(ets2pandaCmd, jobInfo.filePath); + if (!fs.existsSync(jobInfo.filePath) || fs.statSync(jobInfo.filePath).isDirectory()) { + return; + } + const source = fs.readFileSync(jobInfo.filePath, 'utf8').replace(/\r\n/g, '\n'); + let context = lspDriverHelper.createCtx(source, jobInfo.filePath, config, jobInfo.globalContextPtr, true); + PluginDriver.getInstance().getPluginContext().setContextPtr(context); + lspDriverHelper.proceedToState(context, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(context, Es2pandaContextState.ES2PANDA_STATE_LOWERED); +} + +parentPort?.on('message', (msg) => { + if (msg.type === 'ASSIGN_TASK') { + const job = msg.jobInfo; + if (!job.isValid) { + compileExternalProgram(job); + } + + parentPort?.postMessage({ + type: 'TASK_FINISH', + jobId: job.id, + workerId + }); + } else if (msg.type === 'EXIT') { + process.exit(0); + } +}); diff --git a/ets2panda/bindings/src/lsp/generateArkTSConfig.ts b/ets2panda/bindings/src/lsp/generateArkTSConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..9cb0874bc14ac099e6515e80109edbb16967b431 --- /dev/null +++ b/ets2panda/bindings/src/lsp/generateArkTSConfig.ts @@ -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. + */ + +import * as path from 'path'; + +import { ARKTSCONFIG_JSON_FILE, LANGUAGE_VERSION } from '../common/preDefine'; +import { BuildConfig, ModuleInfo } from '../common/types'; +import { ArkTSConfigGenerator } from '../common/arkTSConfigGenerator'; + +function collectDepModuleInfos(moduleInfo: ModuleInfo, allBuildConfig: Record): void { + let dynamicDepModules: string[] = []; + let staticDepModules: string[] = []; + + if (moduleInfo.dependencies) { + moduleInfo.dependencies.forEach((moduleName: string) => { + let depModule = allBuildConfig[moduleName]; + if (depModule.language === LANGUAGE_VERSION.ARKTS_1_2) { + staticDepModules.push(depModule.packageName); + } else if (depModule.language === LANGUAGE_VERSION.ARKTS_1_1) { + dynamicDepModules.push(depModule.packageName); + } else { + staticDepModules.push(depModule.packageName); + dynamicDepModules.push(depModule.packageName); + } + }); + } + moduleInfo.dynamicDepModuleInfos = dynamicDepModules; + moduleInfo.staticDepModuleInfos = staticDepModules; +} + +function collectModuleInfos(allBuildConfig: Record): Record { + let moduleInfos: Record = {}; + Object.values(allBuildConfig).forEach((buildConfig) => { + let moduleInfo = generateModuleInfo(allBuildConfig, buildConfig); + moduleInfos[moduleInfo.packageName] = moduleInfo; + }); + return moduleInfos; +} + +export function generateModuleInfo(allBuildConfig: Record, buildConfig: BuildConfig): ModuleInfo { + if (!buildConfig.packageName || !buildConfig.moduleRootPath) { + console.error('Main buildConfig info from hvigor is not correct.'); + } + let moduleInfo: ModuleInfo = { + packageName: buildConfig.packageName, + moduleRootPath: buildConfig.moduleRootPath, + moduleType: buildConfig.moduleType, + entryFile: buildConfig.packageName !== 'entry' ? path.join(buildConfig.moduleRootPath, 'Index.ets') : '', + arktsConfigFile: path.resolve(buildConfig.cacheDir!, buildConfig.packageName, ARKTSCONFIG_JSON_FILE), + compileFiles: buildConfig.compileFiles, + depModuleCompileFiles: buildConfig.depModuleCompileFiles, + declgenV1OutPath: buildConfig.declgenV1OutPath, + declgenBridgeCodePath: buildConfig.declgenBridgeCodePath, + staticDepModuleInfos: [], + dynamicDepModuleInfos: [], + language: buildConfig.language, + dependencies: buildConfig.dependencies, + declFilesPath: buildConfig.declFilesPath + }; + collectDepModuleInfos(moduleInfo, allBuildConfig); + return moduleInfo; +} + +export function generateArkTsConfigs(allBuildConfig: Record): Record { + let moduleInfos: Record = collectModuleInfos(allBuildConfig); + Object.keys(moduleInfos).forEach((packageName: string) => { + let buildConfig = allBuildConfig[packageName]; + let generator = ArkTSConfigGenerator.getGenerator(buildConfig, moduleInfos); + generator.writeArkTSConfigFile(moduleInfos[packageName]); + }); + let fileToModuleInfo: Record = {}; + Object.values(moduleInfos).forEach((moduleInfo: ModuleInfo) => { + moduleInfo.compileFiles.forEach((file: string) => { + fileToModuleInfo[file] = moduleInfo; + }); + }); + return fileToModuleInfo; +} diff --git a/ets2panda/bindings/src/buildConfigGenerate.ts b/ets2panda/bindings/src/lsp/generateBuildConfig.ts similarity index 56% rename from ets2panda/bindings/src/buildConfigGenerate.ts rename to ets2panda/bindings/src/lsp/generateBuildConfig.ts index 4d1b1c34d1b2f17fc3f4695db8601732c24d72e6..0f58474a8953e4b1ea7f3a33306767ba69426a74 100644 --- a/ets2panda/bindings/src/buildConfigGenerate.ts +++ b/ets2panda/bindings/src/lsp/generateBuildConfig.ts @@ -16,13 +16,21 @@ import * as fs from 'fs'; import * as path from 'path'; import * as JSON5 from 'json5'; -import { BuildConfig } from './types'; +import { BuildConfig, PathConfig } from '../common/types'; +import { + DEFAULT_CACHE_DIR, + EXTERNAL_API_PATH_FROM_SDK, + INTEROP_API_PATH_FROM_SDK, + LANGUAGE_VERSION +} from '../common/preDefine'; +import { getFileLanguageVersion } from '../common/utils'; export interface ModuleDescriptor { - arktsversion: string; name: string; moduleType: string; srcPath: string; + arktsversion?: string; + aceModuleJsonPath?: string; } interface Json5Object { @@ -39,15 +47,10 @@ interface Json5Object { }; } -function removeTrailingCommas(jsonString: string): string { - return jsonString.replace(/,\s*([}\]])/g, '$1'); -} - function parseJson5(filePath: string): Json5Object { try { const rawContent = fs.readFileSync(filePath, 'utf8'); - const cleanedContent = removeTrailingCommas(rawContent); - return JSON5.parse(cleanedContent) as Json5Object; + return JSON5.parse(rawContent) as Json5Object; } catch (error) { console.error(`Error parsing ${filePath}:`, error); return {} as Json5Object; @@ -92,9 +95,8 @@ 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 filterList = [`src${path.sep}test`, `src${path.sep}ohosTest`, `build${path.sep}`, `oh_modules${path.sep}`]; + return filterList.some((directoryPrefix: string) => relativePath.startsWith(directoryPrefix)); }; const processEntry = (dir: string, entry: fs.Dirent): void => { @@ -150,81 +152,111 @@ function getModuleDependencies(modulePath: string, visited = new Set()): } }; - const resolveNestedDependencies = (deps: string[]): string[] => { - return deps.flatMap((depPath) => - visited.has(depPath) ? [] : [depPath, ...getModuleDependencies(depPath, visited)] - ); - }; - const dependencies = extractDependencies(); - const nestedDependencies = resolveNestedDependencies(dependencies); - return Array.from(new Set([...dependencies, ...nestedDependencies])); + return Array.from(new Set([...dependencies])); +} + +function createMapEntryForPlugin(buildSdkPath: string, pluginName: string): string { + return path.join(buildSdkPath, 'build-tools', 'ui-plugins', 'lib', pluginName, 'index'); +} + +function createPluginMap(buildSdkPath: string): Record { + let pluginMap: Record = {}; + const pluginList: string[] = ['ui-syntax-plugins', 'ui-plugins', 'memo-plugins']; + for (const plugin of pluginList) { + pluginMap[plugin] = createMapEntryForPlugin(buildSdkPath, plugin); + } + return pluginMap; +} + +function addPluginPathConfigs(buildConfig: BuildConfig, module: ModuleDescriptor): void { + buildConfig.aceModuleJsonPath = module.aceModuleJsonPath; +} + +function getModuleLanguageVersion(compileFiles: Set): string { + let found1_1 = false; + let found1_2 = false; + + for (const file of compileFiles) { + const sourceFile = fs.readFileSync(file, 'utf8'); + const languageVersion = getFileLanguageVersion(sourceFile); + + if (languageVersion === LANGUAGE_VERSION.ARKTS_1_2) { + found1_2 = true; + } else if (languageVersion === LANGUAGE_VERSION.ARKTS_1_1) { + found1_1 = true; + } + + if (found1_1 && found1_2) { + return LANGUAGE_VERSION.ARKTS_HYBRID; + } + } + + return found1_2 ? LANGUAGE_VERSION.ARKTS_1_2 : found1_1 ? LANGUAGE_VERSION.ARKTS_1_1 : ''; } export function generateBuildConfigs( - buildSdkPath: string, - projectRoot: string, + pathConfig: PathConfig, modules?: ModuleDescriptor[] ): Record { const allBuildConfigs: Record = {}; if (!modules) { - const buildProfilePath = path.join(projectRoot, 'build-profile.json5'); + const buildProfilePath = path.join(pathConfig.projectPath, '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)); + const pluginMap = createPluginMap(pathConfig.buildSdkPath); // Get recursive dependencies + const depModuleCompileFiles = new Set(); const dependencies = getModuleDependencies(modulePath); for (const depPath of dependencies) { - getEtsFiles(depPath).forEach((file) => compileFiles.add(file)); + getEtsFiles(depPath).forEach((file) => depModuleCompileFiles.add(file)); } - + let languageVersion = getModuleLanguageVersion(compileFiles); 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: {}, + plugins: pluginMap, compileFiles: Array.from(compileFiles), + depModuleCompileFiles: Array.from(depModuleCompileFiles), 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) => { + language: languageVersion, + buildSdkPath: pathConfig.buildSdkPath, + projectPath: pathConfig.projectPath, + declgenOutDir: pathConfig.declgenOutDir, + externalApiPath: pathConfig.externalApiPath + ? pathConfig.externalApiPath + : path.resolve(pathConfig.buildSdkPath, EXTERNAL_API_PATH_FROM_SDK), + interopApiPath: pathConfig.interopApiPath + ? pathConfig.interopApiPath + : path.resolve(pathConfig.buildSdkPath, INTEROP_API_PATH_FROM_SDK), + cacheDir: + pathConfig.cacheDir !== undefined ? pathConfig.cacheDir : path.join(pathConfig.projectPath, DEFAULT_CACHE_DIR), + declFilesPath: + languageVersion !== LANGUAGE_VERSION.ARKTS_1_2 + ? path.join(pathConfig.declgenOutDir, module.name, 'declgen', 'dynamic', 'decl-fileInfo.json') + : undefined, + declgenV1OutPath: + languageVersion !== LANGUAGE_VERSION.ARKTS_1_1 + ? path.join(pathConfig.declgenOutDir, module.name, 'declgen', 'static') + : undefined, + declgenBridgeCodePath: + languageVersion !== LANGUAGE_VERSION.ARKTS_1_1 + ? path.join(pathConfig.declgenOutDir, module.name, 'declgen', 'static', 'declgenBridgeCode') + : undefined, + dependencies: 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' - }; + return depModule ? depModule.name : ''; }) }; + addPluginPathConfigs(allBuildConfigs[module.name], module); } - 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/lsp/index.ts b/ets2panda/bindings/src/lsp/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..612db77bfe038ccb173741b283ef31b18b1cc010 --- /dev/null +++ b/ets2panda/bindings/src/lsp/index.ts @@ -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 { Lsp } from './lsp_helper'; +export { Es2pandaContextState } from '../generated/Es2pandaEnums'; +export { + LspCompletionInfo, + LspCompletionEntryKind, + LspDefinitionData, + LspDiagsNode, + LspDiagnosticNode, + LspDiagSeverity, + LspQuickInfo, + LspSymbolDisplayPart +} from './lspNode'; +export { ModuleDescriptor } from './generateBuildConfig'; +export { PathConfig, TextDocumentChangeInfo, AstNodeType, NodeInfo } from '../common/types'; diff --git a/ets2panda/bindings/src/lspNode.ts b/ets2panda/bindings/src/lsp/lspNode.ts similarity index 34% rename from ets2panda/bindings/src/lspNode.ts rename to ets2panda/bindings/src/lsp/lspNode.ts index 7bb465f526731cdabaaf027cbec8e954067c0414..32111b13d6f9c8f16da13924fca64a93c71bc999 100644 --- a/ets2panda/bindings/src/lspNode.ts +++ b/ets2panda/bindings/src/lsp/lspNode.ts @@ -13,12 +13,45 @@ * 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 '../common/InteropTypes'; +import { unpackString, VariantTypes } from '../common/private'; +import { throwError } from '../common/utils'; +import { isNullPtr } from '../common/Wrapper'; +import { global } from '../common/global'; +import { NativePtrDecoder } from '../common/Platform'; +import { AstNodeType, NodeInfo } from '../common/types'; + +enum HierarchyType { + OTHERS, + INTERFACE, + CLASS +} + +export enum SetterStyle { + NONE = 0, + SETTER, + GETTER +} + +export enum AccessModifierStyle { + PUBLIC = 0, + PROTECTED, + PRIVATE +} + +enum ClassRelationKind { + UNKNOWN, + INTERFACE, + CLASS, + FIELD, + METHOD, + PROPERTY +} + +export enum ClassDefinitionStyle { + FIELD = 0, + METHOD +} export abstract class LspNode { readonly peer: KNativePointer; @@ -105,13 +138,13 @@ export class LspDiagnosticNode extends LspNode { .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); + this.code = global.interop._GetIntFromVariant(codeVarPtr); } else { 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); + this.data = global.interop._GetIntFromVariant(dataPtr); } else { this.data = unpackString(global.interop._getStringFromVariant(dataPtr)); } @@ -142,15 +175,16 @@ export class LspDiagsNode extends LspNode { } export class LspDefinitionData extends LspNode { - constructor(peer: KNativePointer) { + constructor(peer: KNativePointer, filePath?: string) { super(peer); - this.fileName = unpackString(global.es2panda._getFileNameFromDef(peer)); - this.start = global.es2panda._getStartFromDef(peer); + this.fileName = filePath ? filePath : 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; + nodeInfos?: NodeInfo[]; } export class LspReferenceData extends LspNode { @@ -197,6 +231,21 @@ export class LspTextSpan extends LspNode { readonly length: KInt; } +export class LspSourceLocation extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.line = global.es2panda._getSourceLocationLine(peer); + this.column = global.es2panda._getSourceLocationColumn(peer); + } + readonly line: number; + readonly column: number; +} + +export interface TextSpan { + start: KInt; + length: KInt; +} + export class LspSymbolDisplayPart extends LspNode { constructor(peer: KNativePointer) { super(peer); @@ -207,6 +256,170 @@ export class LspSymbolDisplayPart extends LspNode { readonly kind: String; } +export class LspClassHierarchyItem extends LspNode { + constructor(peer: KNativePointer, style: ClassDefinitionStyle) { + super(peer); + this.style = style; + this.detail = unpackString(global.es2panda._getDetailFromClassHierarchyItem(this.peer)); + this.accessModifier = global.es2panda._getAccessModifierStyleFromClassHierarchyItem(this.peer); + } + readonly detail: string; + readonly accessModifier: AccessModifierStyle; + readonly style: ClassDefinitionStyle; +} + +export class LspClassMethodItem extends LspClassHierarchyItem { + constructor(peer: KNativePointer) { + super(peer, ClassDefinitionStyle.METHOD); + this.setter = global.es2panda._getSetterStyleFromClassMethodItem(this.peer); + } + readonly setter: SetterStyle; +} + +export class LspClassPropertyItem extends LspClassHierarchyItem { + constructor(peer: KNativePointer) { + super(peer, ClassDefinitionStyle.FIELD); + } +} + +export class LspClassHierarchyInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.className = unpackString(global.es2panda._getClassNameFromClassHierarchyInfo(this.peer)); + this.methodItems = new NativePtrDecoder() + .decode(global.es2panda._getMethodItemsFromClassHierarchyInfo(this.peer)) + .map((elPeer: KNativePointer) => { + return new LspClassMethodItem(elPeer); + }); + this.fieldItems = new NativePtrDecoder() + .decode(global.es2panda._getPropertyItemsFromClassHierarchyInfo(this.peer)) + .map((elPeer: KNativePointer) => { + return new LspClassPropertyItem(elPeer); + }); + } + readonly className: string; + readonly methodItems: LspClassMethodItem[]; + readonly fieldItems: LspClassPropertyItem[]; +} + +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(unpackString(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); @@ -299,7 +512,8 @@ export enum LspCompletionEntryKind { STRUCT = 22, EVENT = 23, OPERATOR = 24, - TYPE_PARAMETER = 25 + TYPE_PARAMETER = 25, + ALIAS_TYPE = 26 } export enum ResolutionStatus { @@ -398,3 +612,420 @@ export class LspLineAndCharacter extends LspNode { 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.span_ = new LspTextSpan(global.es2panda._getTextSpanFromConstructorInfo(peer)); + this.newText_ = unpackString(global.es2panda._getNewTextFromConstructorInfo(peer)); + } + 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 CodeActionInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.changes = new NativePtrDecoder() + .decode(global.es2panda._getFileTextChangesFromCodeActionInfo(peer)) + .map((elPeer: KNativePointer) => { + return new FileTextChanges(elPeer); + }); + this.description = unpackString(global.es2panda._getDescriptionFromCodeActionInfo(peer)); + } + readonly changes: FileTextChanges[]; + readonly description: String; +} + +export class CodeFixActionInfo extends CodeActionInfo { + constructor(peer: KNativePointer) { + super(peer); + this.fixName = unpackString(global.es2panda._getFixNameFromCodeFixActionInfo(peer)); + this.fixId_ = unpackString(global.es2panda._getFixIdFromCodeFixActionInfo(peer)); + this.fixAllDescription_ = unpackString(global.es2panda._getFixAllDescriptionFromCodeFixActionInfo(peer)); + } + readonly fixName: String; + readonly fixId_: String; + readonly fixAllDescription_: String; +} + +export class CodeFixActionInfoList extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.codeFixActionInfos = new NativePtrDecoder() + .decode(global.es2panda._getCodeFixActionInfos(peer)) + .map((elPeer: KNativePointer) => { + return new CodeFixActionInfo(elPeer); + }); + } + readonly codeFixActionInfos: CodeFixActionInfo[]; +} + +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 RefactorAction 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 ApplicableRefactorItemInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getApplicableRefactorName(peer)); + this.description = unpackString(global.es2panda._getApplicableRefactorDescription(peer)); + this.action = new RefactorAction(global.es2panda._getApplicableRefactorAction(peer)); + } + + readonly name: String; + readonly description: String; + readonly action: RefactorAction; +} + +export class LspApplicableRefactorInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.applicableRefactorInfo = new NativePtrDecoder() + .decode(global.es2panda._getApplicableRefactorInfoList(peer)) + .map((elPeer: KNativePointer) => { + return new ApplicableRefactorItemInfo(elPeer); + }); + } + + readonly applicableRefactorInfo: ApplicableRefactorItemInfo[]; +} + +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; +} + +export class LspRenameInfoSuccess extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.canRenameSuccess = true; + this.fileToRename = unpackString(global.es2panda._getRenameSuccessFileName(peer)); + this.kind = unpackString(global.es2panda._getRenameSuccessKind(peer)); + this.displayName = unpackString(global.es2panda._getRenameSuccessDisplayName(peer)); + this.fullDisplayName = unpackString(global.es2panda._getRenameSuccessFullDisplayName(peer)); + this.kindModifiers = unpackString(global.es2panda._getRenameSuccessKindModifiers(peer)); + this.triggerSpan = new LspTextSpan(global.es2panda._getRenameSuccessTriggerSpan(peer)); + } + readonly canRenameSuccess: boolean; + readonly fileToRename: string; + readonly kind: string; + readonly displayName: string; + readonly fullDisplayName: string; + readonly kindModifiers: string; + readonly triggerSpan: LspTextSpan; +} + +export class LspRenameInfoFailure extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.canRenameFailure = false; + this.localizedErrorMessage = unpackString(global.es2panda._getRenameFailureLocalizedErrorMessage(peer)); + } + readonly canRenameFailure: boolean; + readonly localizedErrorMessage: string; +} + +export type LspRenameInfoType = LspRenameInfoSuccess | LspRenameInfoFailure; + +export class LspRenameLocation extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getRenameLocationFileName(peer)); + this.start = global.es2panda._getRenameLocationStart(peer); + this.end = global.es2panda._getRenameLocationEnd(peer); + this.line = global.es2panda._getRenameLocationLine(peer); + this.prefixText = global.es2panda._renameLocationHasPrefixText(peer) + ? unpackString(global.es2panda._getRenameLocationPrefixText(peer)) + : undefined; + this.suffixText = global.es2panda._renameLocationHasSuffixText(peer) + ? unpackString(global.es2panda._getRenameLocationSuffixText(peer)) + : undefined; + } + readonly fileName: string; + readonly start: number; + readonly end: number; + readonly line: number; + readonly prefixText?: string; + readonly suffixText?: string; +} + +export function toAstNodeType(str: string) { + switch (str) { + case 'Identifier': { + return AstNodeType.IDENTIFIER; + } + case 'ClassDefinition': { + return AstNodeType.CLASS_DEFINITION; + } + default: + return AstNodeType.UNKNOWN; + } +} + +export class LspNodeInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getNameByNodeInfo(peer)); + this.kind = toAstNodeType(unpackString(global.es2panda._getKindByNodeInfo(peer))); + } + readonly name: string; + readonly kind: AstNodeType; +} diff --git a/ets2panda/bindings/src/lsp/lsp_helper.ts b/ets2panda/bindings/src/lsp/lsp_helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5fab550454031e98f113fb2ad98fffe58e01319 --- /dev/null +++ b/ets2panda/bindings/src/lsp/lsp_helper.ts @@ -0,0 +1,1333 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LspDriverHelper } from '../common/driver_helper'; +import { global } from '../common/global'; +import { + LspDefinitionData, + LspDiagsNode, + LspReferences, + LspQuickInfo, + LspClassHierarchy, + LspCompletionEntryKind, + LspClassPropertyInfo, + LspClassHierarchies, + LspDocumentHighlightsReferences, + LspCompletionInfo, + LspReferenceLocationList, + LspLineAndCharacter, + LspReferenceData, + LspClassConstructorInfo, + ApplicableRefactorItemInfo, + LspApplicableRefactorInfo, + CompletionEntryDetails, + LspFileTextChanges, + LspSafeDeleteLocationInfo, + LspSafeDeleteLocation, + LspTypeHierarchiesInfo, + LspTextSpan, + LspInlayHint, + LspInlayHintList, + TextSpan, + LspSignatureHelpItems, + CodeFixActionInfo, + CodeFixActionInfoList, + LspRenameLocation, + LspRenameInfoType, + LspRenameInfoSuccess, + LspRenameInfoFailure, + LspSourceLocation, + LspNodeInfo +} from './lspNode'; +import { passStringArray, unpackString } from '../common/private'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; +import { + BuildConfig, + Config, + FileDepsInfo, + Job, + JobInfo, + WorkerInfo, + ModuleInfo, + PathConfig, + TextDocumentChangeInfo, + NodeInfo, + AstNodeType +} from '../common/types'; +import { PluginDriver, PluginHook } from '../common/ui_plugins_driver'; +import { ModuleDescriptor, generateBuildConfigs } from './generateBuildConfig'; +import { generateArkTsConfigs, generateModuleInfo } from './generateArkTSConfig'; + +import * as fs from 'fs'; +import * as path from 'path'; +import { KInt, KNativePointer, KPointer } from '../common/InteropTypes'; +import { passPointerArray } from '../common/private'; +import { NativePtrDecoder } from '../common/Platform'; +import { Worker as ThreadWorker } from 'worker_threads'; +import { ensurePathExists, getFileLanguageVersion } from '../common/utils'; +import * as child_process from 'child_process'; +import { DECL_ETS_SUFFIX, DEFAULT_CACHE_DIR, LANGUAGE_VERSION, TS_SUFFIX } from '../common/preDefine'; +import * as crypto from 'crypto'; +import * as os from 'os'; +import { changeDeclgenFileExtension } from '../common/utils'; + +const ets2pandaCmdPrefix = ['-', '--extension', 'ets', '--arktsconfig']; + +function initBuildEnv(): void { + const currentPath: string | undefined = process.env.PATH; + let pandaLibPath: string = process.env.PANDA_LIB_PATH + ? process.env.PANDA_LIB_PATH + : path.resolve(__dirname, '../../../ets2panda/lib'); + process.env.PATH = `${currentPath}${path.delimiter}${pandaLibPath}`; +} + +export class Lsp { + private pandaLibPath: string; + private pandaBinPath: string; + private getFileContent: (filePath: string) => string; + private filesMap: Map; // Map + private cacheDir: string; + private globalContextPtr?: KNativePointer; + private globalConfig?: Config; + private globalLspDriverHelper?: LspDriverHelper; + private defaultArkTsConfig: string; + private defaultBuildConfig: BuildConfig; + private fileDependencies: string; + private buildConfigs: Record; // Map + private moduleInfos: Record; // Map + private pathConfig: PathConfig; + private lspDriverHelper = new LspDriverHelper(); + private declFileMap: Record = {}; // Map + + constructor(pathConfig: PathConfig, getContentCallback?: (filePath: string) => string, modules?: ModuleDescriptor[]) { + initBuildEnv(); + this.cacheDir = + pathConfig.cacheDir !== undefined ? pathConfig.cacheDir : path.join(pathConfig.projectPath, DEFAULT_CACHE_DIR); + this.fileDependencies = path.join(this.cacheDir, 'file_dependencies.json'); + this.pandaLibPath = process.env.PANDA_LIB_PATH + ? process.env.PANDA_LIB_PATH + : path.resolve(__dirname, '../../../ets2panda/lib'); + this.pandaBinPath = process.env.PANDA_BIN_PATH + ? process.env.PANDA_BIN_PATH + : path.resolve(__dirname, '../../../ets2panda/bin'); + this.filesMap = new Map(); + this.getFileContent = getContentCallback || ((path: string): string => fs.readFileSync(path, 'utf8')); + this.buildConfigs = generateBuildConfigs(pathConfig, modules); + this.moduleInfos = generateArkTsConfigs(this.buildConfigs); + this.pathConfig = pathConfig; + this.defaultArkTsConfig = Object.values(this.moduleInfos)[0].arktsConfigFile; + this.defaultBuildConfig = Object.values(this.buildConfigs)[0]; + PluginDriver.getInstance().initPlugins(this.defaultBuildConfig); + this.initDeclFile(); + } + + // Partially update for new file + updateModuleInfos(module: ModuleDescriptor, newFilePath: String): void { + let buildConfig = this.buildConfigs[module.name]; + buildConfig.compileFiles.push(newFilePath.valueOf()); + let moduleInfo = generateModuleInfo(this.buildConfigs, buildConfig); + this.moduleInfos[newFilePath.valueOf()] = moduleInfo; + } + + // Full update for `Sync Now` + update(modules: ModuleDescriptor[]): void { + this.buildConfigs = generateBuildConfigs(this.pathConfig, modules); + this.moduleInfos = generateArkTsConfigs(this.buildConfigs); + } + + modifyFilesMap(fileName: string, fileContent: TextDocumentChangeInfo): void { + this.filesMap.set(fileName, fileContent.newDoc); + } + + deleteFromFilesMap(fileName: string): void { + this.filesMap.delete(fileName); + } + + private getFileSource(filePath: string): string { + const getSource = this.filesMap.get(filePath) || this.getFileContent(filePath) || fs.readFileSync(filePath, 'utf8'); + if (getSource === undefined) { + throw new Error(`File content not found for path: ${filePath}`); + } + return getSource.replace(/\r\n/g, '\n'); + } + + private createContext(filename: String, processToCheck: boolean = true): [Config, KNativePointer] { + const filePath = path.resolve(filename.valueOf()); + const arktsconfig = Object.prototype.hasOwnProperty.call(this.moduleInfos, filePath) + ? this.moduleInfos[filePath].arktsConfigFile + : this.defaultArkTsConfig; + if (!arktsconfig) { + throw new Error(`Missing arktsconfig for ${filePath}`); + } + + const ets2pandaCmd = [...ets2pandaCmdPrefix, arktsconfig]; + const localCfg = this.lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + + const localCtx = this.lspDriverHelper.createCtx(source, filePath, localCfg, this.globalContextPtr); + try { + const packageName = Object.prototype.hasOwnProperty.call(this.moduleInfos, filePath) + ? this.moduleInfos[filePath].packageName + : undefined; + const buildConfig = packageName ? this.buildConfigs[packageName] : this.defaultBuildConfig; + const pluginContext = PluginDriver.getInstance().getPluginContext(); + pluginContext.setCodingFilePath(filePath); + pluginContext.setProjectConfig(buildConfig); + pluginContext.setContextPtr(localCtx); + + this.lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + + if (processToCheck) { + this.lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + } + return [localCfg, localCtx]; + } catch (error) { + this.lspDriverHelper.destroyContext(localCtx); + this.lspDriverHelper.destroyConfig(localCfg); + throw error; + } + } + + private destroyContext(config: Config, context: KNativePointer): void { + try { + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + } finally { + this.lspDriverHelper.destroyContext(context); + this.lspDriverHelper.destroyConfig(config); + } + } + + private generateDeclFile(filePath: string): void { + const fileSource = this.getFileSource(filePath); + if (getFileLanguageVersion(fileSource) === LANGUAGE_VERSION.ARKTS_1_2) { + const [cfg, ctx] = this.createContext(filePath); + try { + let moduleInfo = this.moduleInfos[filePath]; + let modulePath: string = path.relative(moduleInfo.moduleRootPath, filePath); + let declEtsOutputPath: string = changeDeclgenFileExtension( + path.join(moduleInfo.declgenV1OutPath!, modulePath), + DECL_ETS_SUFFIX + ); + let etsOutputPath: string = changeDeclgenFileExtension( + path.join(moduleInfo.declgenBridgeCodePath!, modulePath), + TS_SUFFIX + ); + this.declFileMap[declEtsOutputPath] = filePath; + ensurePathExists(declEtsOutputPath); + ensurePathExists(etsOutputPath); + global.es2pandaPublic._GenerateTsDeclarationsFromContext(ctx, declEtsOutputPath, etsOutputPath, 1, 0, ''); + } finally { + this.destroyContext(cfg, ctx); + } + } + } + + private initDeclFile(): void { + for (const filePath of Object.keys(this.moduleInfos)) { + this.generateDeclFile(filePath); + } + } + + updateDeclFile(filePath: string): void { + if (!Object.prototype.hasOwnProperty.call(this.moduleInfos, filePath)) { + return; + } + this.generateDeclFile(filePath); + } + + getOffsetByColAndLine(filename: String, line: number, column: number): number { + const sourceCode = this.getFileSource(filename.valueOf()); + return global.es2panda._getOffsetByColAndLine(sourceCode, line, column); + } + + getColAndLineByOffset(filename: String, offset: number): LspSourceLocation { + const sourceCode = this.getFileSource(filename.valueOf()); + return new LspSourceLocation(global.es2panda._getColAndLineByOffset(sourceCode, offset)); + } + + getDefinitionAtPosition(filename: String, offset: number, nodeInfos?: NodeInfo[]): LspDefinitionData { + if (nodeInfos) { + return this.getDefinitionAtPositionByNodeInfos(filename, nodeInfos); + } + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getDefinitionAtPosition(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + const result = new LspDefinitionData(ptr); + const moduleName = this.moduleInfos[filename.valueOf()].packageName; + const declgenOutDir = this.buildConfigs[moduleName].declgenOutDir; + if (result.fileName.endsWith(DECL_ETS_SUFFIX) && result.fileName.startsWith(declgenOutDir)) { + let ptr: KPointer; + const [declFileCfg, declFileCtx] = this.createContext(result.fileName, false); + try { + ptr = global.es2panda._getNodeInfosByDefinitionData(declFileCtx, result.start); + result.nodeInfos = new NativePtrDecoder().decode(ptr).map((elPeer: KNativePointer) => { + return new LspNodeInfo(elPeer); + }); + } finally { + this.destroyContext(declFileCfg, declFileCtx); + } + } + return result; + } + + private getDefinitionAtPositionByNodeInfos(declFilePath: String, nodeInfos: NodeInfo[]): LspDefinitionData { + let ptr: KPointer; + let nodeInfoPtrs: KPointer[] = []; + const sourceFilePath = this.declFileMap[declFilePath.valueOf()]; + const [cfg, ctx] = this.createContext(sourceFilePath, false); + try { + nodeInfos.forEach((nodeInfo) => { + nodeInfoPtrs.push(global.es2panda._CreateNodeInfoPtr(nodeInfo.name, nodeInfo.kind)); + }); + ptr = global.es2panda._getDefinitionDataFromNode(ctx, passPointerArray(nodeInfoPtrs), nodeInfoPtrs.length); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDefinitionData(ptr, sourceFilePath); + } + + private getMergedCompileFiles(filename: String): string[] { + const moduleInfo = this.moduleInfos[path.resolve(filename.valueOf())]; + return moduleInfo ? [...moduleInfo.compileFiles, ...moduleInfo.depModuleCompileFiles] : []; + } + + getSemanticDiagnostics(filename: String): LspDiagsNode { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getSemanticDiagnostics(ctx); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDiagsNode(ptr); + } + + getCurrentTokenValue(filename: String, offset: number): string { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getCurrentTokenValue(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return unpackString(ptr); + } + + getImplementationAtPosition(filename: String, offset: number): LspDefinitionData { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getImplementationAtPosition(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDefinitionData(ptr); + } + + getFileReferences(filename: String): LspReferenceData[] { + let isPackageModule: boolean; + const [cfg, searchCtx] = this.createContext(filename); + try { + isPackageModule = global.es2panda._isPackageModule(searchCtx); + } finally { + this.destroyContext(cfg, searchCtx); + } + let result: LspReferenceData[] = []; + let compileFiles = this.getMergedCompileFiles(filename); + for (let i = 0; i < compileFiles.length; i++) { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(compileFiles[i]); + try { + ptr = global.es2panda._getFileReferences(path.resolve(filename.valueOf()), ctx, isPackageModule); + } finally { + this.destroyContext(cfg, ctx); + } + let refs = new LspReferences(ptr); + for (let j = 0; j < refs.referenceInfos.length; j++) { + if (refs.referenceInfos[j].fileName !== '') { + result.push(refs.referenceInfos[j]); + } + } + } + return result; + } + + getReferencesAtPosition(filename: String, offset: number): LspReferenceData[] { + let declInfo: KPointer; + const [cfg, searchCtx] = this.createContext(filename); + try { + declInfo = global.es2panda._getDeclInfo(searchCtx, offset); + } finally { + this.destroyContext(cfg, searchCtx); + } + let result: LspReferenceData[] = []; + let compileFiles = this.getMergedCompileFiles(filename); + for (let i = 0; i < compileFiles.length; i++) { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(compileFiles[i]); + try { + ptr = global.es2panda._getReferencesAtPosition(ctx, declInfo); + } finally { + this.destroyContext(cfg, ctx); + } + let refs = new LspReferences(ptr); + result.push(...refs.referenceInfos); + } + return Array.from(new Set(result)); + } + + getTypeHierarchies(filename: String, offset: number): LspTypeHierarchiesInfo | null { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + ptr = global.es2panda._getTypeHierarchies(ctx, ctx, offset); + let ref = new LspTypeHierarchiesInfo(ptr); + if (ref.fileName === '') { + this.destroyContext(cfg, ctx); + return null; + } + let result: LspTypeHierarchiesInfo[] = []; + let compileFiles = this.getMergedCompileFiles(filename); + for (let i = 0; i < compileFiles.length; i++) { + let searchPtr: KPointer; + const [cfg, searchCtx] = this.createContext(compileFiles[i]); + try { + searchPtr = global.es2panda._getTypeHierarchies(searchCtx, ctx, offset); + } finally { + this.destroyContext(cfg, searchCtx); + } + let refs = new LspTypeHierarchiesInfo(searchPtr); + 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 ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getClassHierarchyInfo(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspClassHierarchy(ptr); + } + + getAliasScriptElementKind(filename: String, offset: number): LspCompletionEntryKind { + let kind: KInt; + const [cfg, ctx] = this.createContext(filename); + try { + kind = global.es2panda._getAliasScriptElementKind(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return kind; + } + + getClassHierarchies(filename: String, offset: number): LspClassHierarchies { + let contextList = []; + const [cfg, ctx] = this.createContext(filename); + contextList.push({ ctx: ctx, cfg: cfg }); + let nativeContextList = global.es2panda._pushBackToNativeContextVector(ctx, ctx, 1); + let compileFiles = this.getMergedCompileFiles(filename); + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + if (path.resolve(filename.valueOf()) === filePath) { + continue; + } + const [searchCfg, searchCtx] = this.createContext(filePath); + contextList.push({ ctx: searchCtx, cfg: searchCfg }); + global.es2panda._pushBackToNativeContextVector(searchCtx, nativeContextList, 0); + } + let ptr = global.es2panda._getClassHierarchies(nativeContextList, filename, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + for (const { ctx, cfg } of contextList) { + this.destroyContext(cfg, ctx); + } + return new LspClassHierarchies(ptr); + } + + getClassPropertyInfo( + filename: String, + offset: number, + shouldCollectInherited: boolean = false + ): LspClassPropertyInfo { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getClassPropertyInfo(ctx, offset, shouldCollectInherited); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspClassPropertyInfo(ptr); + } + + getOrganizeImports(filename: String): LspFileTextChanges { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._organizeImports(ctx, filename); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspFileTextChanges(ptr); + } + + findSafeDeleteLocation(filename: String, offset: number): LspSafeDeleteLocationInfo[] { + let declInfo: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + declInfo = global.es2panda._getDeclInfo(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + let result: LspSafeDeleteLocationInfo[] = []; + let compileFiles = this.getMergedCompileFiles(filename); + for (let i = 0; i < compileFiles.length; i++) { + let ptr: KPointer; + const [searchCfg, searchCtx] = this.createContext(compileFiles[i]); + try { + ptr = global.es2panda._findSafeDeleteLocation(searchCtx, declInfo); + } finally { + this.destroyContext(searchCfg, searchCtx); + } + let refs = new LspSafeDeleteLocation(ptr); + result.push(...refs.safeDeleteLocationInfos); + } + return Array.from(new Set(result)); + } + + getCompletionEntryDetails(filename: String, offset: number, entryName: String): CompletionEntryDetails { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getCompletionEntryDetails(entryName, filename, ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new CompletionEntryDetails(ptr); + } + + getApplicableRefactors(filename: String, kind: String, offset: number): ApplicableRefactorItemInfo[] { + let ptr: KPointer; + let result: ApplicableRefactorItemInfo[] = []; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getApplicableRefactors(ctx, kind, offset); + } finally { + this.destroyContext(cfg, ctx); + } + let refs = new LspApplicableRefactorInfo(ptr); + result.push(...refs.applicableRefactorInfo); + return Array.from(new Set(result)); + } + + getClassConstructorInfo(filename: String, offset: number, properties: string[]): LspClassConstructorInfo { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getClassConstructorInfo(ctx, offset, passStringArray(properties)); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspClassConstructorInfo(ptr); + } + + getSyntacticDiagnostics(filename: String): LspDiagsNode { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename, false); + try { + ptr = global.es2panda._getSyntacticDiagnostics(ctx); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDiagsNode(ptr); + } + + getSuggestionDiagnostics(filename: String): LspDiagsNode { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getSuggestionDiagnostics(ctx); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDiagsNode(ptr); + } + + getQuickInfoAtPosition(filename: String, offset: number): LspQuickInfo { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getQuickInfoAtPosition(filename, ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspQuickInfo(ptr); + } + + getDocumentHighlights(filename: String, offset: number): LspDocumentHighlightsReferences { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getDocumentHighlights(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspDocumentHighlightsReferences(ptr); + } + + getCompletionAtPosition(filename: String, offset: number): LspCompletionInfo { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; + 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, this.globalContextPtr); + const packageName = this.moduleInfos[filePath].packageName; + const buildConfig = this.buildConfigs[packageName]; + PluginDriver.getInstance().getPluginContext().setCodingFilePath(filePath); + PluginDriver.getInstance().getPluginContext().setProjectConfig(buildConfig); + 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 ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._toLineColumnOffset(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspLineAndCharacter(ptr); + } + + getSafeDeleteInfo(filename: String, position: number): boolean { + let result: boolean; + const [cfg, ctx] = this.createContext(filename); + try { + result = global.es2panda._getSafeDeleteInfo(ctx, position); + } finally { + this.destroyContext(cfg, ctx); + } + return result; + } + + findRenameLocations(filename: String, offset: number): LspRenameLocation[] { + const [cfg, ctx] = this.createContext(filename); + const needsCrossFileRename = global.es2panda._needsCrossFileRename(ctx, offset); + if (!needsCrossFileRename) { + let ptr: KPointer; + try { + ptr = global.es2panda._findRenameLocationsInCurrentFile(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + const result = new NativePtrDecoder().decode(ptr).map((elPeer: KPointer) => { + return new LspRenameLocation(elPeer); + }); + return Array.from(new Set(result)); + } else { + let compileFiles = this.getMergedCompileFiles(filename); + const fileContexts: KPointer[] = []; + const fileConfigs: Config[] = []; + for (let i = 0; i < compileFiles.length; i++) { + const [compileFileCfg, compileFileCtx] = this.createContext(compileFiles[i]); + fileContexts.push(compileFileCtx); + fileConfigs.push(compileFileCfg); + } + const ptr = global.es2panda._findRenameLocations( + fileContexts.length, + passPointerArray(fileContexts), + ctx, + offset + ); + const result: LspRenameLocation[] = new NativePtrDecoder().decode(ptr).map((elPeer: KPointer) => { + return new LspRenameLocation(elPeer); + }); + for (let i = 0; i < fileContexts.length; i++) { + this.destroyContext(fileConfigs[i], fileContexts[i]); + } + this.destroyContext(cfg, ctx); + return Array.from(new Set(result)); + } + } + + getRenameInfo(filename: String, offset: number): LspRenameInfoType { + let ptr: KPointer; + let res: LspRenameInfoType; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getRenameInfo(ctx, offset, this.pandaLibPath); + const success = global.es2panda._getRenameInfoIsSuccess(ptr); + if (success) { + res = new LspRenameInfoSuccess(global.es2panda._getRenameInfoSuccess(ptr)); + } else { + res = new LspRenameInfoFailure(global.es2panda._getRenameInfoFailure(ptr)); + } + } finally { + this.destroyContext(cfg, ctx); + } + return res; + } + + getSpanOfEnclosingComment(filename: String, offset: number, onlyMultiLine: boolean): LspTextSpan { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getSpanOfEnclosingComment(ctx, offset, onlyMultiLine); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspTextSpan(ptr); + } + + getCodeFixesAtPosition(filename: String, start: number, end: number, errorCodes: number[]): CodeFixActionInfo[] { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getCodeFixesAtPosition(ctx, start, end, new Int32Array(errorCodes), errorCodes.length); + } finally { + this.destroyContext(cfg, ctx); + } + const codeFixActionInfoList = new CodeFixActionInfoList(ptr); + const codeFixActionInfos: CodeFixActionInfo[] = []; + codeFixActionInfos.push(...codeFixActionInfoList.codeFixActionInfos); + return codeFixActionInfos; + } + + provideInlayHints(filename: String, span: TextSpan): LspInlayHint[] { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + const nativeSpan = global.es2panda._createTextSpan(span.start, span.length); + ptr = global.es2panda._getInlayHintList(ctx, nativeSpan); + } finally { + this.destroyContext(cfg, ctx); + } + const inlayHintList = new LspInlayHintList(ptr); + const inlayHints: LspInlayHint[] = []; + inlayHints.push(...inlayHintList.inlayHints); + return inlayHints; + } + + getSignatureHelpItems(filename: String, offset: number): LspSignatureHelpItems { + let ptr: KPointer; + const [cfg, ctx] = this.createContext(filename); + try { + ptr = global.es2panda._getSignatureHelpItems(ctx, offset); + } finally { + this.destroyContext(cfg, ctx); + } + return new LspSignatureHelpItems(ptr); + } + + // Use AST cache start + private getFileDependencies(inputs: string[], output: string): void { + let depInputContent = ''; + let outputFile: string = output; + let depAnalyzerPath: string = path.join(this.pandaBinPath, 'dependency_analyzer'); + let depInputFile = path.join(this.cacheDir, 'depInput.txt'); + inputs.forEach((file) => { + depInputContent += file + os.EOL; + }); + fs.writeFileSync(depInputFile, depInputContent); + ensurePathExists(outputFile); + const result = child_process.spawnSync( + depAnalyzerPath, + [`@${depInputFile}`, `--output=${output}`, `--arktsconfig=${this.defaultArkTsConfig}`], + { + encoding: 'utf-8', + windowsHide: true + } + ); + if (result.error || result.status !== 0) { + console.error('getFileDependencies failed: ', result.stderr || result.error); + } + } + + // Collect circular dependencies, like: A→B→C→A + private findStronglyConnectedComponents(graph: FileDepsInfo): Map> { + const adjacencyList: Record = {}; + const reverseAdjacencyList: Record = {}; + const allNodes = new Set(); + + for (const node in graph.dependencies) { + allNodes.add(node); + graph.dependencies[node].forEach((dep) => allNodes.add(dep)); + } + for (const node in graph.dependants) { + allNodes.add(node); + graph.dependants[node].forEach((dep) => allNodes.add(dep)); + } + + Array.from(allNodes).forEach((node) => { + adjacencyList[node] = graph.dependencies[node] || []; + reverseAdjacencyList[node] = graph.dependants[node] || []; + }); + + const visited = new Set(); + const order: string[] = []; + + function dfs(node: string): void { + visited.add(node); + for (const neighbor of adjacencyList[node]) { + if (!visited.has(neighbor)) { + dfs(neighbor); + } + } + order.push(node); + } + + Array.from(allNodes).forEach((node) => { + if (!visited.has(node)) { + dfs(node); + } + }); + + visited.clear(); + const components = new Map>(); + + function reverseDfs(node: string, component: Set): void { + visited.add(node); + component.add(node); + for (const neighbor of reverseAdjacencyList[node]) { + if (!visited.has(neighbor)) { + reverseDfs(neighbor, component); + } + } + } + + for (let i = order.length - 1; i >= 0; i--) { + const node = order[i]; + if (!visited.has(node)) { + const component = new Set(); + reverseDfs(node, component); + if (component.size > 1) { + const sortedFiles = Array.from(component).sort(); + const hashKey = createHash(sortedFiles.join('|')); + components.set(hashKey, component); + } + } + } + + return components; + } + + private getJobDependencies(fileDeps: string[], cycleFiles: Map): Set { + let depJobList: Set = new Set(); + fileDeps.forEach((file) => { + if (!cycleFiles.has(file)) { + depJobList.add('0' + file); + } else { + cycleFiles.get(file)?.forEach((f) => { + depJobList.add(f); + }); + } + }); + + return depJobList; + } + + private getJobDependants(fileDeps: string[], cycleFiles: Map): Set { + let depJobList: Set = new Set(); + fileDeps.forEach((file) => { + if (!file.endsWith(DECL_ETS_SUFFIX)) { + depJobList.add('1' + file); + } + if (cycleFiles.has(file)) { + cycleFiles.get(file)?.forEach((f) => { + depJobList.add(f); + }); + } else { + depJobList.add('0' + file); + } + }); + + return depJobList; + } + + private collectCompileJobs(jobs: Record, isValid: boolean = false): void { + let entryFileList: string[] = Object.keys(this.moduleInfos).filter((file) => { + if (this.moduleInfos[file].language === LANGUAGE_VERSION.ARKTS_1_2) { + return true; + } else if (this.moduleInfos[file].language === LANGUAGE_VERSION.ARKTS_HYBRID) { + const fileSource = this.getFileSource(file); + return getFileLanguageVersion(fileSource) === LANGUAGE_VERSION.ARKTS_1_2; + } + }); + this.getFileDependencies(entryFileList, this.fileDependencies); + const data = fs.readFileSync(this.fileDependencies, 'utf-8'); + let fileDepsInfo: FileDepsInfo = JSON.parse(data) as FileDepsInfo; + + Object.keys(fileDepsInfo.dependants).forEach((file) => { + if (!(file in fileDepsInfo.dependencies)) { + fileDepsInfo.dependencies[file] = []; + } + }); + + let cycleGroups = this.findStronglyConnectedComponents(fileDepsInfo); + + let cycleFiles: Map = new Map(); + cycleGroups.forEach((value: Set, key: string) => { + value.forEach((file) => { + cycleFiles.set(file, [key]); + }); + }); + + Object.entries(fileDepsInfo.dependencies).forEach(([key, value]) => { + let dependencies = this.getJobDependencies(value, cycleFiles); + if (cycleFiles.has(key)) { + const externalProgramJobIds = cycleFiles.get(key)!; + externalProgramJobIds.forEach((id) => { + let fileList: string[] = Array.from(cycleGroups.get(id)!); + this.createExternalProgramJob(id, fileList, jobs, dependencies, isValid, true); + }); + } else { + const id = '0' + key; + let fileList: string[] = [key]; + this.createExternalProgramJob(id, fileList, jobs, dependencies, isValid); + } + }); + + Object.entries(fileDepsInfo.dependants).forEach(([key, value]) => { + const dependants = this.getJobDependants(value, cycleFiles); + const jobIds = cycleFiles.has(key) ? cycleFiles.get(key)! : ['0' + key]; + + jobIds.forEach((jobId) => { + const currentDependants = new Set(dependants); + jobs[jobId].dependants.forEach((dep) => currentDependants.add(dep)); + currentDependants.delete(jobId); + jobs[jobId].dependants = Array.from(currentDependants); + }); + }); + } + + private createExternalProgramJob( + id: string, + fileList: string[], + jobs: Record, + dependencies: Set, + isValid: boolean, + isInCycle?: boolean + ): void { + if (dependencies.has(id)) { + dependencies.delete(id); + } + if (jobs[id]) { + const existingJob = jobs[id]; + const mergedFileList = [...new Set([...existingJob.fileList, ...fileList])]; + const mergedDependencies = [...new Set([...existingJob.dependencies, ...Array.from(dependencies)])]; + const mergedIsInCycle = existingJob.isInCycle || isInCycle; + + existingJob.fileList = mergedFileList; + existingJob.dependencies = mergedDependencies; + existingJob.isInCycle = mergedIsInCycle; + } else { + jobs[id] = { + id, + fileList, + isDeclFile: true, + isInCycle, + dependencies: Array.from(dependencies), + dependants: [], + isValid + }; + } + } + + private addJobToQueues(job: Job, queues: Job[]): void { + if (queues.some((j) => j.id === job.id)) { + return; + } + queues.push(job); + } + + private initCompileQueues(jobs: Record, queues: Job[], dependantJobs?: Record): void { + Object.values(jobs).forEach((job) => { + if (job.dependencies.length === 0) { + if (dependantJobs && job.id in dependantJobs) { + job.isValid = false; + this.invalidateFileCache(job.fileList); + } + this.addJobToQueues(job, queues); + } + }); + } + + private checkAllTasksDone(queues: Job[], workerPool: WorkerInfo[]): boolean { + if (queues.length === 0) { + for (let i = 0; i < workerPool.length; i++) { + if (!workerPool[i].isIdle) { + return false; + } + } + return true; + } + return false; + } + + private initGlobalContext(jobs: Record): void { + let files: string[] = []; + Object.entries(jobs).forEach(([key, job]) => { + for (let i = 0; i < job.fileList.length; i++) { + files.push(job.fileList[i]); + } + }); + + if (files.length === 0) { + return; + } + + let ets2pandaCmd: string[] = [ + '_', + '--extension', + 'ets', + '--arktsconfig', + this.defaultArkTsConfig, + Object.keys(this.moduleInfos)[0] + ]; + + this.globalLspDriverHelper = new LspDriverHelper(); + this.globalLspDriverHelper.memInitialize(this.pandaLibPath); + this.globalConfig = this.globalLspDriverHelper.createCfg(ets2pandaCmd, files[0], this.pandaLibPath); + this.globalContextPtr = this.globalLspDriverHelper.createGlobalContext(this.globalConfig.peer, files, files.length); + } + + private updateQueues( + jobs: Record, + queues: Job[], + jobId: string, + dependantJobs?: Record + ): void { + const completedJob = jobs[jobId]; + completedJob.dependants.forEach((depJobId) => { + const depJob = jobs[depJobId]; + if (!depJob) { + return; + } + const depIndex = depJob.dependencies.indexOf(jobId); + if (depIndex === -1) { + return; + } + depJob.dependencies.splice(depIndex, 1); + if (depJob.dependencies.length > 0) { + return; + } + this.processCompletedDependencies(depJob, queues, dependantJobs); + }); + } + + private processCompletedDependencies(depJob: Job, queues: Job[], dependantJobs?: Record): void { + if (dependantJobs && depJob.id in dependantJobs) { + depJob.isValid = false; + this.invalidateFileCache(depJob.fileList); + } + this.addJobToQueues(depJob, queues); + } + + private invalidateFileCache(fileList: string[]): void { + fileList.forEach((file) => { + global.es2pandaPublic._InvalidateFileCache(this.globalContextPtr!, file); + }); + } + + private async invokeWorkers( + jobs: Record, + queues: Job[], + processingJobs: Set, + workers: ThreadWorker[], + numWorkers: number, + dependantJobs?: Record + ): Promise { + return new Promise((resolve) => { + const workerPool = this.createWorkerPool(numWorkers, workers); + + workerPool.forEach((workerInfo) => { + this.setupWorkerListeners(workerInfo.worker, workerPool, jobs, queues, processingJobs, resolve, dependantJobs); + this.assignTaskToIdleWorker(workerInfo, queues, processingJobs); + }); + }); + } + + private createWorkerPool(numWorkers: number, workers: ThreadWorker[]): WorkerInfo[] { + const workerPool: WorkerInfo[] = []; + + for (let i = 0; i < numWorkers; i++) { + const worker = new ThreadWorker(path.resolve(__dirname, 'compile_thread_worker.js'), { + workerData: { workerId: i } + }); + workers.push(worker); + workerPool.push({ worker, isIdle: true }); + } + + return workerPool; + } + + private setupWorkerListeners( + worker: ThreadWorker, + workerPool: WorkerInfo[], + jobs: Record, + queues: Job[], + processingJobs: Set, + resolve: () => void, + dependantJobs?: Record + ): void { + worker.on('message', (msg) => { + if (msg.type !== 'TASK_FINISH') { + return; + } + + this.handleTaskCompletion(msg.jobId, worker, workerPool, jobs, queues, processingJobs, dependantJobs); + + if (this.checkAllTasksDone(queues, workerPool)) { + this.terminateWorkers(workerPool); + resolve(); + } + }); + } + + private handleTaskCompletion( + jobId: string, + worker: ThreadWorker, + workerPool: WorkerInfo[], + jobs: Record, + queues: Job[], + processingJobs: Set, + dependantJobs?: Record + ): void { + const workerInfo = workerPool.find((w) => w.worker === worker); + if (workerInfo) { + workerInfo.isIdle = true; + } + processingJobs.delete(jobId); + this.updateQueues(jobs, queues, jobId, dependantJobs); + workerPool.forEach((workerInfo) => { + if (workerInfo.isIdle) { + this.assignTaskToIdleWorker(workerInfo, queues, processingJobs); + } + }); + } + + private terminateWorkers(workerPool: WorkerInfo[]): void { + workerPool.forEach(({ worker }) => { + worker.postMessage({ type: 'EXIT' }); + }); + } + + private assignTaskToIdleWorker(workerInfo: WorkerInfo, queues: Job[], processingJobs: Set): void { + let job: Job | undefined; + let jobInfo: JobInfo | undefined; + + if (queues.length > 0) { + job = queues.shift()!; + jobInfo = { + id: job.id, + filePath: job.fileList[0], + arktsConfigFile: Object.prototype.hasOwnProperty.call(this.moduleInfos, job.fileList[0]) + ? this.moduleInfos[job.fileList[0]].arktsConfigFile + : this.defaultArkTsConfig, + globalContextPtr: this.globalContextPtr!, + buildConfig: Object.values(this.buildConfigs)[0], + isValid: job.isValid + }; + } + + if (job) { + processingJobs.add(job.id); + workerInfo.worker.postMessage({ type: 'ASSIGN_TASK', jobInfo }); + workerInfo.isIdle = false; + } + } + + // AST caching is not enabled by default. + // Call `initAstCache` before invoking the language service interface to enable AST cache + public async initAstCache(numWorkers: number = 1): Promise { + const jobs: Record = {}; + const queues: Job[] = []; + this.collectCompileJobs(jobs); + this.initGlobalContext(jobs); + this.initCompileQueues(jobs, queues); + if (Object.keys(jobs).length === 0 && queues.length === 0) { + return; + } + const processingJobs = new Set(); + const workers: ThreadWorker[] = []; + await this.invokeWorkers(jobs, queues, processingJobs, workers, numWorkers); + } + + private compileExternalProgram(jobInfo: JobInfo): void { + PluginDriver.getInstance().initPlugins(jobInfo.buildConfig); + let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', jobInfo.arktsConfigFile]; + let lspDriverHelper = new LspDriverHelper(); + let config = lspDriverHelper.createCfg(ets2pandaCmd, jobInfo.filePath); + const source = fs.readFileSync(jobInfo.filePath, 'utf8').replace(/\r\n/g, '\n'); + let context = lspDriverHelper.createCtx(source, jobInfo.filePath, config, jobInfo.globalContextPtr, true); + PluginDriver.getInstance().getPluginContext().setContextPtr(context); + lspDriverHelper.proceedToState(context, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(context, Es2pandaContextState.ES2PANDA_STATE_LOWERED); + } + + public addFileCache(filename: String): void { + global.es2pandaPublic._AddFileCache(this.globalContextPtr!, filename); + let jobInfo = { + id: filename.valueOf(), + filePath: filename.valueOf(), + arktsConfigFile: Object.prototype.hasOwnProperty.call(this.moduleInfos, filename.valueOf()) + ? this.moduleInfos[filename.valueOf()].arktsConfigFile + : this.defaultArkTsConfig, + globalContextPtr: this.globalContextPtr!, + buildConfig: Object.values(this.buildConfigs)[0], + isValid: true + }; + this.compileExternalProgram(jobInfo); + } + + public removeFileCache(filename: String): void { + global.es2pandaPublic._RemoveFileCache(this.globalContextPtr!, filename); + } + + public async updateFileCache(filename: String, numWorkers: number = 1): Promise { + const queues: Job[] = []; + const jobs: Record = {}; + this.collectCompileJobs(jobs, true); + const dependantJobs = this.findJobDependants(jobs, filename.valueOf()); + this.initCompileQueues(jobs, queues, dependantJobs); + const processingJobs = new Set(); + const workers: ThreadWorker[] = []; + await this.invokeWorkers(jobs, queues, processingJobs, workers, numWorkers, dependantJobs); + } + + private findJobDependants(jobs: Record, filePath: string): Record { + const targetJobs = this.findTargetJobs(jobs, filePath); + const { visited, dependantJobs } = this.collectDependantJobs(jobs, targetJobs); + + return this.mergeJobs(targetJobs, dependantJobs); + } + + private findTargetJobs(jobs: Record, filePath: string): Job[] { + return Object.values(jobs).filter( + (job) => job.fileList.includes(filePath) || (job.isInCycle && job.fileList.some((f) => f === filePath)) + ); + } + + private collectDependantJobs( + jobs: Record, + targetJobs: Job[] + ): { visited: Set; dependantJobs: Map } { + const visited = new Set(); + const dependantJobs = new Map(); + const queue: Job[] = []; + + targetJobs.forEach((job) => { + if (!visited.has(job.id)) { + visited.add(job.id); + queue.push(job); + } + + while (queue.length) { + const current = queue.shift()!; + this.processDependants(jobs, current, visited, queue, dependantJobs); + } + }); + + return { visited, dependantJobs }; + } + + private processDependants( + jobs: Record, + current: Job, + visited: Set, + queue: Job[], + dependantJobs: Map + ): void { + current.dependants.forEach((dependantId) => { + const dependantJob = jobs[dependantId]; + if (dependantJob && !visited.has(dependantId)) { + visited.add(dependantId); + queue.push(dependantJob); + dependantJobs.set(dependantId, dependantJob); + } + }); + } + + private mergeJobs(targetJobs: Job[], dependantJobs: Map): Record { + return [...targetJobs, ...dependantJobs.values()].reduce( + (acc, job) => { + acc[job.id] = job; + return acc; + }, + {} as Record + ); + } + + public dispose(): void { + this.globalLspDriverHelper!.destroyGlobalContext(this.globalContextPtr!); + this.globalLspDriverHelper!.destroyConfig(this.globalConfig!); + this.globalLspDriverHelper!.memFinalize(); + } +} + +function createHash(str: string): string { + const hash = crypto.createHash('sha256'); + hash.update(str); + return hash.digest('hex'); +} +// Use AST cache end diff --git a/ets2panda/bindings/src/lsp_helper.ts b/ets2panda/bindings/src/lsp_helper.ts deleted file mode 100644 index 48bbf71c166bf8db78c8d54966cbb1825e08b0e4..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/src/lsp_helper.ts +++ /dev/null @@ -1,355 +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. - */ - -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 } 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'; - -function initBuildEnv(): void { - const currentPath: string | undefined = process.env.PATH; - let pandaLibPath: string = path.resolve(__dirname, '../../ets2panda/lib'); - process.env.PATH = `${currentPath}${path.delimiter}${pandaLibPath}`; -} - -export class Lsp { - private pandaLibPath: string; - private projectPath: string; - private fileNameToArktsconfig: Record; // Map - private moduleToBuildConfig: Record; // Map - private getFileContent: (filePath: string) => string; - - 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.getFileContent = getContentCallback || ((path: string): string => fs.readFileSync(path, 'utf8')); - } - - 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')); - } - - 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, 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._getDefinitionAtPosition(localCtx, offset); - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); - lspDriverHelper.destroyContext(localCtx); - lspDriverHelper.destroyConfig(localCfg); - 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 pandaLibPath: string = path.resolve(__dirname, '../../ets2panda/lib'); - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, 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._getSemanticDiagnostics(localCtx); - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); - lspDriverHelper.destroyContext(localCtx); - lspDriverHelper.destroyConfig(localCfg); - 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, 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._getCurrentTokenValue(localCtx, offset); - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); - lspDriverHelper.destroyContext(localCtx); - lspDriverHelper.destroyConfig(localCfg); - 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, 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._getImplementationAtPosition(localCtx, offset); - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); - lspDriverHelper.destroyContext(localCtx); - lspDriverHelper.destroyConfig(localCfg); - return new LspDefinitionData(ptr); - } - - getFileReferences(filename: String): LspReferenceData[] { - let lspDriverHelper = new LspDriverHelper(); - let searchFilePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[searchFilePath]; - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig]; - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, searchFilePath, this.pandaLibPath); - const source = this.getFileContent(searchFilePath).replace(/\r\n/g, '\n'); - 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]; - 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, this.pandaLibPath); - 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(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]); - } - } - } - 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, 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 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 = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig]; - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); - 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); - } - return Array.from(new Set(result)); - } - - 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, 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._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, 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._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, 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._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, 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._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, this.pandaLibPath); - let source = this.getFileContent(filePath).replace(/\r\n/g, '\n'); - // 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, 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._toLineColumnOffset(localCtx, offset); - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); - lspDriverHelper.destroyContext(localCtx); - lspDriverHelper.destroyConfig(localCfg); - return new LspLineAndCharacter(ptr); - } -} diff --git a/ets2panda/bindings/test/BUILD.gn b/ets2panda/bindings/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b8699dfef79e25877c8f6ad21792901d8f557336 --- /dev/null +++ b/ets2panda/bindings/test/BUILD.gn @@ -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("//build/version.gni") + +group("bindings_test") { + deps = [ ":check_result" ] +} + +action("check_result") { + deps = [ ":run_test" ] + script = "check_result.sh" + args = [ rebase_path("../finished.txt") ] + outputs = [ "$target_out_dir/$target_name.timestamp" ] +} + +action("run_test") { + script = "run_bindings.sh" + args = [ + rebase_path("./"), + rebase_path( + "//prebuilts/build-tools/common/nodejs/node-v16.20.2-linux-x64/bin"), + rebase_path("//prebuilts/ohos-sdk/linux/${api_version}/ets"), + ] + outputs = [ "$target_out_dir/$target_name.timestamp" ] +} diff --git a/ets2panda/bindings/test/README.md b/ets2panda/bindings/test/README.md index 76f2db43899e68bfb2a93d2688cc69afa04ce1be..bce307bd3a7c4b9e782c71c91208b2dd33a84999 100644 --- a/ets2panda/bindings/test/README.md +++ b/ets2panda/bindings/test/README.md @@ -1,29 +1,24 @@ ### How to run bindings test? +first, you need download a SDK package, then unzip ets component into `bindings/test/` directory. +Download SDK package from [here](http://ci.openharmony.cn/workbench/cicd/dailybuild/dailylist). + ```Bash +unzip /path/to/ets-xxx.zip -d /path/to/bindings/test/ cd /path/to/bindings -### check environment, replace the path base on your machine -# 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` +1. If you want to update a lot of expected results, you can use `npm run test:update` to update all expected results. ### testcase directory structure . +├── cases.ts +├── run_tests.ts ├── expected │   ├── exampleFuncName.json └── testcases @@ -33,14 +28,13 @@ powershell -f test/prepare.ps1 --restore    │   │   └── arktsconfig.json    │   ├── lsp_build_config.json    │   └── lsp_compileFileInfos.json -    ├── cases.json    └── exampleFuncName       └── exampleFuncName1.ets -case.json: -```json +case.ts: +```typescript { - "testName": { + testName: { "expectedFilePath": "/path/to/expected.json", "1": [ "param1", "param2" ], // lsp will call lsp.testName(param1, param2) "2": [ "param1", "param2" ] @@ -49,16 +43,12 @@ case.json: ``` #### How to add a new test case? -1. add exampleFuncName2.ets file in `testcases/exampleFuncName` -2. add parameters in `testcases/cases.json` -3. add expected result in `expected/exampleFuncName.json` +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` -2. add exampleFuncName2 field in `testcases/cases.json` -3. add exampleFuncName2.json in `expected` +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 - -⚠️⚠️⚠️ -Before push your code, please make sure that the path formats in all JSON files under the testcases directory are correct. -Incorrect path formats will render the function of prepare.sh ineffective, and manually handling the paths can be quite annoying. \ No newline at end of file diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts new file mode 100644 index 0000000000000000000000000000000000000000..5cbc7d7123db8048ce3cf150c1541ad0eafae69a --- /dev/null +++ b/ets2panda/bindings/test/cases.ts @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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/lsp/lspNode'; +import { AstNodeType, NodeInfo } from '../src/lsp'; + +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 basicCases: 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], + '11': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.ets'), 634], + '12': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets'), 637], + '13': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition20.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CLASS_DEFINITION, + name: 'Foo' + }, + { + kind: AstNodeType.IDENTIFIER, + name: 'Foo' + } + ] as NodeInfo[] + ], + '14': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition21.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CLASS_DEFINITION, + name: 'Foo' + }, + { + kind: AstNodeType.METHOD_DEFINITION, + name: 'bar' + } + ] as NodeInfo[] + ], + '15': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition22.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CLASS_DEFINITION, + name: 'Foo' + }, + { + kind: AstNodeType.CLASS_PROPERTY, + name: 'staticProperty' + } + ] as NodeInfo[] + ], + '16': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition23.d.ets' + ), + 0, + [ + { + kind: AstNodeType.MEMBER_EXPRESSION, + name: 'bar' + } + ] as NodeInfo[] + ], + '17': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition24.d.ets' + ), + 0, + [ + { + kind: AstNodeType.EXPORT_SPECIFIER, + name: 'PI' + } + ] as NodeInfo[] + ], + '18': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition25.d.ets' + ), + 0, + [ + { + kind: AstNodeType.TS_INTERFACE_DECLARATION, + name: 'User' + } + ] as NodeInfo[] + ], + '19': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition26.d.ets' + ), + 0, + [ + { + kind: AstNodeType.TS_TYPE_ALIAS_DECLARATION, + name: 'ID' + } + ] as NodeInfo[] + ], + '20': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition27.d.ets' + ), + 0, + [ + { + kind: AstNodeType.TS_ENUM_DECLARATION, + name: 'Color' + } + ] as NodeInfo[] + ], + '21': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition28.d.ets' + ), + 0, + [ + { + kind: AstNodeType.TS_ENUM_MEMBER, + name: 'Green' + } + ] as NodeInfo[] + ], + '22': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition30.d.ets' + ), + 0, + [ + { + kind: AstNodeType.TS_CLASS_IMPLEMENTS, + name: 'Printable' + } + ] as NodeInfo[] + ], + '23': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition31.d.ets' + ), + 0, + [ + { + kind: AstNodeType.VARIABLE_DECLARATION, + name: 'a' + } + ] as NodeInfo[] + ], + '24': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition31.d.ets' + ), + 0, + [ + { + kind: AstNodeType.VARIABLE_DECLARATOR, + name: 'b' + } + ] as NodeInfo[] + ], + '25': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition32.d.ets' + ), + 0, + [ + { + kind: AstNodeType.ANNOTATION_DECLARATION, + name: 'Validate' + } + ] as NodeInfo[] + ], + '26': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition32.d.ets' + ), + 0, + [ + { + kind: AstNodeType.ANNOTATION_USAGE, + name: 'Log' + } + ] as NodeInfo[] + ], + '27': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition33.d.ets' + ), + 0, + [ + { + kind: AstNodeType.AWAIT_EXPRESSION, + name: 'p' + } + ] as NodeInfo[] + ], + '28': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition34.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CLASS_DECLARATION, + name: 'Derived' + } + ] as NodeInfo[] + ], + '29': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_SPECIFIER, + name: 'State' + } + ] as NodeInfo[] + ], + '30': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_DEFAULT_SPECIFIER, + name: 'hilog' + } + ] as NodeInfo[] + ], + '31': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_NAMESPACE_SPECIFIER, + name: 'All' + } + ] as NodeInfo[] + ], + '32': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition36.d.ets' + ), + 0, + [ + { + kind: AstNodeType.PROPERTY, + name: 'prop' + } + ] as NodeInfo[] + ], + '33': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition37.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CALL_EXPRESSION, + name: 'a' + } + ] as NodeInfo[] + ], + '34': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition38.d.ets' + ), + 0, + [ + { + kind: AstNodeType.SUPER_EXPRESSION, + name: 'super' + } + ] as NodeInfo[] + ], + '35': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition39.d.ets' + ), + 0, + [ + { + kind: AstNodeType.REEXPORT_STATEMENT, + name: 'PI' + } + ] as NodeInfo[] + ], + '36': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition40.d.ets' + ), + 0, + [ + { + kind: AstNodeType.SCRIPT_FUNCTION, + name: 'test' + } + ] as NodeInfo[] + ], + '37': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition41.d.ets' + ), + 0, + [ + { + kind: AstNodeType.ETS_TYPE_REFERENCE, + name: 'Person' + }, + { + kind: AstNodeType.ETS_TYPE_REFERENCE, + name: 'Person1' + }, + { + kind: AstNodeType.ETS_TYPE_REFERENCE, + name: 'Array' + } + ] as NodeInfo[] + ], + '38': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition42.d.ets' + ), + 0, + [ + { + kind: AstNodeType.SPREAD_ELEMENT, + name: 'numbers' + }, + { + kind: AstNodeType.SPREAD_ELEMENT, + name: 'args' + } + ] as NodeInfo[] + ] + }, + getSemanticDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSemanticDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.ets')], + '2': [resolveTestPath('test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.ets')], + '3': [resolveTestPath('test/testcases/getSemanticDiagnostics/getSemanticDiagnostics3.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], + '5': [resolveTestPath('test/testcases/getCurrentTokenValue/getCurrentTokenValue5.ets'), 697] + }, + getFileReferences: { + expectedFilePath: resolveTestPath('test/expected/getFileReferences.json'), + '1': [resolveTestPath('test/testcases/getFileReferences/getFileReferences1_export.ets')] + }, + getFileSource: { + expectedFilePath: resolveTestPath('test/expected/getFileSource.json'), + '1': [resolveTestPath('test/testcases/getFileSource/getFileSource1.ets')] + }, + getReferencesAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getReferencesAtPosition.json'), + '1': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets'), 613], + '2': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition2.ets'), 635], + '3': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition4.ets'), 625], + '4': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition6.ets'), 697] + }, + getSyntacticDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSyntacticDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.ets')], + '2': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.ets')], + '3': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics3.ets')], + '4': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics4.ets')] + }, + getSuggestionDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSuggestionDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.ets')] + }, + getOrganizeImports: { + expectedFilePath: resolveTestPath('test/expected/getOrganizeImports.json'), + '1': [resolveTestPath('test/testcases/getOrganizeImports/getOrganizeImports1.ets')], + '2': [resolveTestPath('test/testcases/getOrganizeImports/ExtractDefaultImport1_import.ets')], + '3': [resolveTestPath('test/testcases/getOrganizeImports/ExtractDefaultImport2_import.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], + '4': [resolveTestPath('test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition4.ets'), 697], + '5': [resolveTestPath('test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition5.ets'), 701] + }, + 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], flaky issue + '6': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights6.ets'), 657], + '7': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights7.ets'), 733], + '8': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights8.ets'), 677], + '9': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights9.ets'), 620] + }, + 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], + '15': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition15.ets'), 722], + '16': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition17.ets'), 764], + '17': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition17.ets'), 782] + }, + toLineColumnOffset: { + expectedFilePath: resolveTestPath('test/expected/toLineColumnOffset.json'), + '1': [resolveTestPath('test/testcases/toLineColumnOffset/toLineColumnOffset1.ets'), 0], + '2': [resolveTestPath('test/testcases/toLineColumnOffset/toLineColumnOffset1.ets'), 642], + '3': [resolveTestPath('test/testcases/toLineColumnOffset/toLineColumnOffset2.ets'), 709] + }, + 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 + ], + '2': [ + resolveTestPath('test/testcases/provideInlayHints/provideInlayHints2.ets'), + { start: 683, length: 5 } as TextSpan + ] + }, + getCodeFixesAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getCodeFixesAtPosition.json'), + '1': [resolveTestPath('test/testcases/getCodeFixesAtPosition/getCodeFixesAtPosition1.ets'), 994, 995, [4000]] + }, + getSignatureHelpItems: { + expectedFilePath: resolveTestPath('test/expected/getSignatureHelpItems.json'), + '1': [resolveTestPath('test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets'), 678] + }, + findRenameLocations: { + expectedFilePath: resolveTestPath('test/expected/findRenameLocations.json'), + '1': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations2.ets'), 632], + '2': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations1.ets'), 627], + '3': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations1.ets'), 670], + '4': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations1.ets'), 721], + '5': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations2.ets'), 676], + '6': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations2.ets'), 868], + '7': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations1.ets'), 720], + '8': [resolveTestPath('test/testcases/findRenameLocations/findRenameLocations3.ets'), 627] + }, + getRenameInfo: { + expectedFilePath: resolveTestPath('test/expected/getRenameInfo.json'), + '1': [resolveTestPath('test/testcases/getRenameInfo/getRenameInfo1.ets'), 615], + '2': [resolveTestPath('test/testcases/getRenameInfo/getRenameInfo2.ets'), 626], + '3': [resolveTestPath('test/testcases/getRenameInfo/getRenameInfo3.ets'), 697] + }, + getOffsetByColAndLine: { + expectedFilePath: resolveTestPath('test/expected/getOffsetByColAndLine.json'), + '1': [resolveTestPath('test/testcases/getOffsetByColAndLine/getOffsetByColAndLine1.ets'), 51, 14] + }, + getColAndLineByOffset: { + expectedFilePath: resolveTestPath('test/expected/getColAndLineByOffset.json'), + '1': [resolveTestPath('test/testcases/getColAndLineByOffset/getColAndLineByOffset1.ets'), 1035] + }, + entry: { + expectedFilePath: '', + '1': [resolveTestPath('test/testcases/entry/Index.ets'), 615] + }, + generateDeclFile: { + expectedFilePath: resolveTestPath('test/expected/generateDeclFile.json') + } +}; + +export const getSpanOfEnclosingCommentTests = basicCases.getSpanOfEnclosingComment; diff --git a/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh b/ets2panda/bindings/test/check_result.sh old mode 100644 new mode 100755 similarity index 55% rename from ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh rename to ets2panda/bindings/test/check_result.sh index 282d190c670e4295438767188c996c864deea436..98f6d2a5b5cb81aba722724070cf003d9cf405eb --- a/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh +++ b/ets2panda/bindings/test/check_result.sh @@ -4,30 +4,19 @@ # you may not use this 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, # WITHOUT 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 +set -e -# revert the project files -mv ../arkanalyzer/package.json.bak ../arkanalyzer/package.json -rm ../arkanalyzer/$TAR_FILE +if [ -f "$1" ]; then + echo "test execution successfully" +else + echo "test execution failed" + exit 1 +fi diff --git a/ets2panda/bindings/test/expected/findRenameLocations.json b/ets2panda/bindings/test/expected/findRenameLocations.json new file mode 100644 index 0000000000000000000000000000000000000000..ac6d8fdd1a2a7b788e0c8c387a9e9d847666dc51 --- /dev/null +++ b/ets2panda/bindings/test/expected/findRenameLocations.json @@ -0,0 +1,224 @@ +{ + "1": [ + { + "fileName": "findRenameLocations2.ets", + "start": 630, + "end": 633, + "line": 15, + "prefixText": "Foo as " + }, + { + "fileName": "findRenameLocations2.ets", + "start": 738, + "end": 741, + "line": 23 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 781, + "end": 784, + "line": 24 + } + ], + "2": [ + { + "fileName": "findRenameLocations1.ets", + "start": 625, + "end": 628, + "line": 15 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 1259, + "end": 1262, + "line": 49 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 1267, + "end": 1270, + "line": 50 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 1275, + "end": 1278, + "line": 51 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 625, + "end": 628, + "line": 15 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 694, + "end": 697, + "line": 19 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 702, + "end": 705, + "line": 20 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 711, + "end": 714, + "line": 21 + } + ], + "3": [ + { + "fileName": "findRenameLocations1.ets", + "start": 667, + "end": 672, + "line": 18 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 1239, + "end": 1244, + "line": 47 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 1249, + "end": 1254, + "line": 48 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 618, + "end": 623, + "line": 15 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 673, + "end": 678, + "line": 17 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 683, + "end": 688, + "line": 18 + } + ], + "4": [ + { + "fileName": "findRenameLocations1.ets", + "start": 718, + "end": 722, + "line": 22 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 882, + "end": 886, + "line": 27 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 866, + "end": 870, + "line": 28 + }, + { + "fileName": "findRenameLocations3.ets", + "start": 728, + "end": 732, + "line": 18 + } + ], + "5": [ + { + "fileName": "findRenameLocations2.ets", + "start": 618, + "end": 623, + "line": 15, + "prefixText": "dummy as " + }, + { + "fileName": "findRenameLocations2.ets", + "start": 673, + "end": 678, + "line": 17 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 683, + "end": 688, + "line": 18 + } + ], + "6": [ + { + "fileName": "findRenameLocations1.ets", + "start": 718, + "end": 722, + "line": 22 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 882, + "end": 886, + "line": 27 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 866, + "end": 870, + "line": 28 + }, + { + "fileName": "findRenameLocations3.ets", + "start": 728, + "end": 732, + "line": 18 + } + ], + "7": [ + { + "fileName": "findRenameLocations1.ets", + "start": 718, + "end": 722, + "line": 22 + }, + { + "fileName": "findRenameLocations1.ets", + "start": 882, + "end": 886, + "line": 27 + }, + { + "fileName": "findRenameLocations2.ets", + "start": 866, + "end": 870, + "line": 28 + }, + { + "fileName": "findRenameLocations3.ets", + "start": 728, + "end": 732, + "line": 18 + } + ], + "8": [ + { + "fileName": "findRenameLocations3.ets", + "start": 625, + "end": 629, + "line": 15 + }, + { + "fileName": "findRenameLocations3.ets", + "start": 685, + "end": 689, + "line": 17 + } + ] +} diff --git a/ets2panda/bindings/test/expected/generateDeclFile.json b/ets2panda/bindings/test/expected/generateDeclFile.json new file mode 100644 index 0000000000000000000000000000000000000000..f4c3675ed3609bfc30ff5bb90453fdf7d213d6e7 --- /dev/null +++ b/ets2panda/bindings/test/expected/generateDeclFile.json @@ -0,0 +1,16 @@ +{ + "1": [ + "generateDeclFile1.d.ets", + "generateDeclFile2.d.ets", + "generateDeclFile3.d.ets", + "generateDeclFile4.d.ets", + "generateDeclFile5.d.ets", + "generateDeclFile6.d.ets", + "generateDeclFile7.d.ets", + "generateDeclFile8.d.ets", + "generateDeclFile9.d.ets", + "generateDeclFile10.d.ets", + "generateDeclFile11.d.ets", + "generateDeclFile12.d.ets" + ] +} diff --git a/ets2panda/bindings/test/expected/getCodeFixesAtPosition.json b/ets2panda/bindings/test/expected/getCodeFixesAtPosition.json new file mode 100644 index 0000000000000000000000000000000000000000..198d10973c7959790ea9d207b926dec4b5acf505 --- /dev/null +++ b/ets2panda/bindings/test/expected/getCodeFixesAtPosition.json @@ -0,0 +1,36 @@ +{ + "1": [ + { + "changes": [ + { + "fileName": "getCodeFixesAtPosition1.ets", + "textChanges": [ + { + "span": { + "start": 990, + "length": 6 + }, + "newText": "" + } + ] + } + ], + "description": "Remove the duplicate 'Entry' annotation", + "fixName": "Fix", + "fixId_": "UI_PLUGIN_SUGGEST", + "fixAllDescription_": "Fix All Description" + }, + { + "changes": [ + { + "fileName": "getCodeFixesAtPosition1.ets", + "textChanges": [] + } + ], + "description": "Remove the duplicate 'Entry' annotation", + "fixName": "Fix", + "fixId_": "UI_PLUGIN_SUGGEST", + "fixAllDescription_": "Fix All Description" + } + ] +} diff --git a/ets2panda/bindings/test/expected/getColAndLineByOffset.json b/ets2panda/bindings/test/expected/getColAndLineByOffset.json new file mode 100644 index 0000000000000000000000000000000000000000..775479eeba7ac69f5884ff771b9eb40cb4899f47 --- /dev/null +++ b/ets2panda/bindings/test/expected/getColAndLineByOffset.json @@ -0,0 +1,6 @@ +{ + "1": { + "line": 35, + "column": 8 + } +} diff --git a/ets2panda/bindings/test/expected/getCompletionAtPosition.json b/ets2panda/bindings/test/expected/getCompletionAtPosition.json index cfb523e800853e05d62a147ade8d1672a867aef8..a437e80c6541b554fe5eb308b79d7ae54406125c 100644 --- a/ets2panda/bindings/test/expected/getCompletionAtPosition.json +++ b/ets2panda/bindings/test/expected/getCompletionAtPosition.json @@ -1,372 +1,259 @@ { - "1": { - "entries": [ - { - "name": "namespace", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "native", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "never", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "new", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "null", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "num1", - "sortText": "15", - "insertText": "", - "kind": 3, - "data": null - }, - { - "name": "num2", - "sortText": "15", - "insertText": "", - "kind": 3, - "data": null - }, - { - "name": "number", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - } - ] - }, - "2": { - "entries": [ - { - "name": "aaa", - "sortText": "15", - "insertText": "", - "kind": 6, - "data": null - }, - { - "name": "abb", - "sortText": "15", - "insertText": "", - "kind": 21, - "data": null - }, - { - "name": "abstract", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "any", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "anyref", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "arguments", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "as", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "asserts", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "async", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "await", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "axx", - "sortText": "15", - "insertText": "", - "kind": 3, - "data": null - } - ] - }, - "3": { - "entries": [ - { - "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": "bigint", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "boolean", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "break", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "bxx", - "sortText": "15", - "insertText": "", - "kind": 3, - "data": null - }, - { - "name": "byte", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - } - ] - }, - "4": { - "entries": [ - { - "name": "baa", - "sortText": "15", - "insertText": "", - "kind": 6, - "data": null - }, - { - "name": "bbb", - "sortText": "15", - "insertText": "", - "kind": 6, - "data": null - }, - { - "name": "bigint", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "boolean", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "break", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - }, - { - "name": "bxx", - "sortText": "15", - "insertText": "", - "kind": 3, - "data": null - }, - { - "name": "byte", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - } - ] - }, - "5": { - "entries": [ - { - "name": "myProp", - "sortText": "14", - "insertText": "", - "kind": 10, - "data": null - } - ] - }, - "6": { - "entries": [ - { - "name": "classInSpace", - "sortText": "13", - "insertText": "", - "kind": 7, - "data": null - } - ] - }, - "7": { - "entries": [ - { - "name": "Red", - "sortText": "13", - "insertText": "", - "kind": 20, - "data": null - } - ] - }, - "8": { - "entries": [] - }, - "9": { - "entries": [ - { - "name": "number", - "sortText": "15", - "insertText": "", - "kind": 14, - "data": null - } - ] - }, - "10": { - "entries": [ - { - "name": "classInSpace", - "sortText": "13", - "insertText": "", - "kind": 7, - "data": null - } - ] - }, - "11": { - "entries": [ - { - "name": "Blue", - "sortText": "13", - "insertText": "", - "kind": 20, - "data": null - }, - { - "name": "Red", - "sortText": "13", - "insertText": "", - "kind": 20, - "data": null - } - ] - }, - "12": { - "entries": [ - { - "name": "myProp", - "sortText": "14", - "insertText": "", - "kind": 10, - "data": null - }, - { - "name": "prop", - "sortText": "14", - "insertText": "", - "kind": 10, - "data": null - } - ] - }, - "13": { - "entries": [ - { - "name": "key", - "sortText": "17", - "insertText": "", - "kind": 2, - "data": null - } - ] - }, - "14": { - "entries": [ - { - "name": "key", - "sortText": "17", - "insertText": "", - "kind": 2, - "data": null - } - ] - } -} \ No newline at end of file + "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 + } + ], + "15": [ + { + "name": "isEmpty", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + }, + { + "name": "peek", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + }, + { + "name": "pop", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + }, + { + "name": "push", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + } + ], + "16": [ + { + "name": "Entry", + "sortText": "15", + "insertText": "", + "kind": 27, + "data": null + }, + { + "name": "Entry2", + "sortText": "15", + "insertText": "", + "kind": 27, + "data": null + } + ], + "17": [ + { + "name": "Entry", + "sortText": "15", + "insertText": "", + "kind": 27, + "data": null + }, + { + "name": "Entry2", + "sortText": "15", + "insertText": "", + "kind": 27, + "data": null + }, + { + "name": "TestAnnotation", + "sortText": "15", + "insertText": "", + "kind": 27, + "data": null + } + ] +} diff --git a/ets2panda/bindings/test/expected/getCurrentTokenValue.json b/ets2panda/bindings/test/expected/getCurrentTokenValue.json index 2efc1c7dcc7425280098742dee114aaf29f47d4e..7e8e9ca7cbaa75db8b4adad99797db4a7b4d162f 100644 --- a/ets2panda/bindings/test/expected/getCurrentTokenValue.json +++ b/ets2panda/bindings/test/expected/getCurrentTokenValue.json @@ -2,5 +2,6 @@ "1": "ab", "2": "ab", "3": "ab", - "4": "ab" -} \ No newline at end of file + "4": "ab", + "5": "pu" +} diff --git a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json index 74bd51b3c26f3f49e8838394eed310a2e59b72d1..e05cf3d18cb81dee7379e8d111e474dc4a83dd0b 100644 --- a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json +++ b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json @@ -48,5 +48,145 @@ "fileName": "text.d.ets", "start": 7586, "length": 4 + }, + "11": { + "fileName": "taskpool.ets", + "start": 686, + "length": 4 + }, + "12": { + "fileName": "getDefinitionAtPosition1.ets", + "start": 0, + "length": 0 + }, + "13": { + "fileName": "getDefinitionAtPosition20.ets", + "start": 632, + "length": 3 + }, + "14": { + "fileName": "getDefinitionAtPosition21.ets", + "start": 643, + "length": 3 + }, + "15": { + "fileName": "getDefinitionAtPosition22.ets", + "start": 650, + "length": 14 + }, + "16": { + "fileName": "getDefinitionAtPosition23.ets", + "start": 679, + "length": 3 + }, + "17": { + "fileName": "getDefinitionAtPosition24.ets", + "start": 629, + "length": 2 + }, + "18": { + "fileName": "getDefinitionAtPosition25.ets", + "start": 637, + "length": 4 + }, + "19": { + "fileName": "getDefinitionAtPosition26.ets", + "start": 632, + "length": 2 + }, + "20": { + "fileName": "getDefinitionAtPosition27.ets", + "start": 632, + "length": 5 + }, + "21": { + "fileName": "getDefinitionAtPosition28.ets", + "start": 649, + "length": 5 + }, + "22": { + "fileName": "getDefinitionAtPosition30.ets", + "start": 728, + "length": 9 + }, + "23": { + "fileName": "getDefinitionAtPosition31.ets", + "start": 729, + "length": 1 + }, + "24": { + "fileName": "getDefinitionAtPosition31.ets", + "start": 748, + "length": 1 + }, + "25": { + "fileName": "getDefinitionAtPosition32.ets", + "start": 631, + "length": 8 + }, + "26": { + "fileName": "getDefinitionAtPosition32.ets", + "start": 862, + "length": 3 + }, + "27": { + "fileName": "getDefinitionAtPosition33.ets", + "start": 709, + "length": 1 + }, + "28": { + "fileName": "getDefinitionAtPosition34.ets", + "start": 679, + "length": 7 + }, + "29": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 629, + "length": 5 + }, + "30": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 680, + "length": 5 + }, + "31": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 719, + "length": 3 + }, + "32": { + "fileName": "getDefinitionAtPosition36.ets", + "start": 638, + "length": 4 + }, + "33": { + "fileName": "getDefinitionAtPosition37.ets", + "start": 664, + "length": 1 + }, + "34": { + "fileName": "getDefinitionAtPosition38.ets", + "start": 814, + "length": 5 + }, + "35": { + "fileName": "getDefinitionAtPosition39.ets", + "start": 629, + "length": 2 + }, + "36": { + "fileName": "getDefinitionAtPosition40.ets", + "start": 636, + "length": 4 + }, + "37": { + "fileName": "getDefinitionAtPosition41.ets", + "start": 941, + "length": 13 + }, + "38": { + "fileName": "getDefinitionAtPosition42.ets", + "start": 966, + "length": 12 } -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/getDocumentHighlights.json b/ets2panda/bindings/test/expected/getDocumentHighlights.json index 49190c9ce2c7e36b26677db053333613d4eb04fc..6ac9f6191e07a308c95e936c2668f0fb247a44bb 100644 --- a/ets2panda/bindings/test/expected/getDocumentHighlights.json +++ b/ets2panda/bindings/test/expected/getDocumentHighlights.json @@ -313,5 +313,71 @@ ] } ] + }, + "8": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights8.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights8.ets", + "textSpan": { + "start": 628, + "length": 5 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights8.ets", + "textSpan": { + "start": 674, + "length": 5 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "9": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights9.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights9.ets", + "textSpan": { + "start": 618, + "length": 4 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights9.ets", + "textSpan": { + "start": 655, + "length": 4 + }, + "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 index 270729c437bc25ccff94f07becd5a81f684b8ba2..dfa9cce006bd48d00b702448bd8ce1581c1186d8 100644 --- a/ets2panda/bindings/test/expected/getFileReferences.json +++ b/ets2panda/bindings/test/expected/getFileReferences.json @@ -23,4 +23,4 @@ "length": 29 } ] -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/getFileSource.json b/ets2panda/bindings/test/expected/getFileSource.json new file mode 100644 index 0000000000000000000000000000000000000000..e78e8263809eb2e6790b12307f456fad30c3db94 --- /dev/null +++ b/ets2panda/bindings/test/expected/getFileSource.json @@ -0,0 +1,3 @@ +{ + "1": "/*\n * Copyright (c) 2025 Huawei Device Co., Ltd.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet a = 1;" +} diff --git a/ets2panda/bindings/test/expected/getOffsetByColAndLine.json b/ets2panda/bindings/test/expected/getOffsetByColAndLine.json new file mode 100644 index 0000000000000000000000000000000000000000..20feeefb6924fc3fe9e6de00ff27b882f8737c40 --- /dev/null +++ b/ets2panda/bindings/test/expected/getOffsetByColAndLine.json @@ -0,0 +1,3 @@ +{ + "1": 1373 +} diff --git a/ets2panda/bindings/test/expected/getOrganizeImports.json b/ets2panda/bindings/test/expected/getOrganizeImports.json new file mode 100644 index 0000000000000000000000000000000000000000..1de7f3ac0adb05fb643858d2bbc7c1bfb89ee427 --- /dev/null +++ b/ets2panda/bindings/test/expected/getOrganizeImports.json @@ -0,0 +1,50 @@ +{ + "1": { + "fileTextChanges": [ + { + "fileName": "getOrganizeImports1.ets", + "textChanges": [ + { + "span": { + "start": 608, + "length": 306 + }, + "newText": "import { Entry, Component } from '@ohos.arkui.component';\nimport { State } from '@ohos.arkui.stateManagement';\nimport { B, C } from './getOrganizeImports2';" + } + ] + } + ] + }, + "2": { + "fileTextChanges": [ + { + "fileName": "ExtractDefaultImport1_import.ets", + "textChanges": [ + { + "span": { + "start": 608, + "length": 56 + }, + "newText": "import Foo, { one } from './ExtractDefaultImport1_export';" + } + ] + } + ] + }, + "3": { + "fileTextChanges": [ + { + "fileName": "ExtractDefaultImport2_import.ets", + "textChanges": [ + { + "span": { + "start": 608, + "length": 51 + }, + "newText": "import Foo from './ExtractDefaultImport2_export';" + } + ] + } + ] + } +} diff --git a/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json b/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json index d8dd45871470028b82e634b66b599d7087f65e11..b942b7b1ae20495c324fd76a915fac810e83d756 100644 --- a/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json +++ b/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json @@ -1,6 +1,6 @@ { "1": { - "kind": "", + "kind": "enum member", "kindModifier": "static public readonly", "textSpan": { "start": 626, @@ -70,7 +70,7 @@ ] }, "3": { - "kind": "property", + "kind": "get", "kindModifier": "public abstract", "textSpan": { "start": 661, @@ -103,5 +103,87 @@ "kind": "returnType" } ] + }, + "4": { + "kind": "method", + "kindModifier": "public declare", + "textSpan": { + "start": 695, + "length": 4 + }, + "fileName": "getQuickInfoAtPosition4.ets", + "displayParts": [ + { + "text": "Stack", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "push", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "item", + "kind": "functionParameter" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "T", + "kind": "typeParameter" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "T", + "kind": "returnType" + } + ] + }, + "5": { + "kind": "struct", + "kindModifier": "final", + "textSpan": { + "start": 699, + "length": 5 + }, + "fileName": "getQuickInfoAtPosition5.ets", + "displayParts": [ + { + "text": "struct", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Index", + "kind": "structName" + } + ] } -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/getReferencesAtPosition.json b/ets2panda/bindings/test/expected/getReferencesAtPosition.json index 526e1ac25619fc3bbc93bf40deaacb4d251492c5..e487e7ef028a1fda1c6abc9466affaed9014552b 100644 --- a/ets2panda/bindings/test/expected/getReferencesAtPosition.json +++ b/ets2panda/bindings/test/expected/getReferencesAtPosition.json @@ -49,5 +49,17 @@ "start": 655, "length": 1 } + ], + "4": [ + { + "fileName": "getReferencesAtPosition6.ets", + "start": 695, + "length": 4 + }, + { + "fileName": "getReferencesAtPosition6.ets", + "start": 708, + "length": 4 + } ] -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/getRenameInfo.json b/ets2panda/bindings/test/expected/getRenameInfo.json new file mode 100644 index 0000000000000000000000000000000000000000..801d75bc296ca7ce95d18f148b599e4c8978a871 --- /dev/null +++ b/ets2panda/bindings/test/expected/getRenameInfo.json @@ -0,0 +1,22 @@ +{ + "1": { + "canRenameSuccess": true, + "fileToRename": "", + "kind": "property", + "displayName": "aaa", + "fullDisplayName": "aaa", + "kindModifiers": "", + "triggerSpan": { + "start": 613, + "length": 3 + } + }, + "2": { + "canRenameFailure": false, + "localizedErrorMessage": "You cannot rename this element" + }, + "3": { + "canRenameFailure": false, + "localizedErrorMessage": "You cannot rename this element" + } +} diff --git a/ets2panda/bindings/test/expected/getSemanticDiagnostics.json b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json index 679a81c0565df7ffcaec412a54ad8a473b295304..23cb7c2138b869ba1a223b8234a8f5309f5aafde 100644 --- a/ets2panda/bindings/test/expected/getSemanticDiagnostics.json +++ b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json @@ -5,21 +5,41 @@ "2": { "diagnostics": [ { - "message": "Type '\"1\"' is not compatible with type 'double' at index 1", - "source": "\"1\"", + "message": "Type '\"hello\"' cannot be assigned to type 'Double'", + "range": { + "start": { + "line": 16, + "character": 19 + }, + "end": { + "line": 16, + "character": 26 + } + }, + "tags": [], + "relatedInfo": [], + "code": 2318, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "No matching call signature for add(\"1\", Int)", "range": { "start": { "line": 20, - "character": 5 + "character": 1 }, "end": { "line": 20, - "character": 8 + "character": 4 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2127, "data": 0, "severity": 1, "codeDescription": { @@ -27,21 +47,45 @@ } }, { - "message": "No matching call signature for add(\"1\", int)", - "source": "add", + "message": "Type '\"1\"' is not compatible with type 'Double' at index 1", "range": { "start": { "line": 20, - "character": 1 + "character": 5 }, "end": { "line": 20, + "character": 8 + } + }, + "tags": [], + "relatedInfo": [], + "code": 2046, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + } + ] + }, + "3": { + "diagnostics": [ + { + "message": "No matching call signature for push(\"123\")", + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, "character": 4 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2127, "data": 0, "severity": 1, "codeDescription": { @@ -49,21 +93,20 @@ } }, { - "message": "Type '\"hello\"' cannot be assigned to type 'double'", - "source": "\"hello\"", + "message": "Type '\"123\"' is not compatible with type 'Double' at index 1", "range": { "start": { - "line": 16, - "character": 19 + "line": 19, + "character": 10 }, "end": { - "line": 16, - "character": 26 + "line": 19, + "character": 15 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2046, "data": 0, "severity": 1, "codeDescription": { @@ -72,4 +115,4 @@ } ] } -} \ 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..fc085309d9033a97bfd331ed8a9a77da105ccaec --- /dev/null +++ b/ets2panda/bindings/test/expected/getSignatureHelpItems.json @@ -0,0 +1,104 @@ +{ + "1": { + "items": [ + { + "prefixDisplayParts": [ + { + "text": "add", + "kind": "functionName" + }, + { + "text": "(", + "kind": "punctuation" + } + ], + "suffixDisplayParts": [ + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=>", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Double", + "kind": "keyword" + } + ], + "separatorDisplayParts": [ + { + "text": ",", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + } + ], + "parameters": [ + { + "name": "a", + "documentation": [], + "displayParts": [ + { + "text": "a", + "kind": "parameterNmae" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Double", + "kind": "keyword" + } + ] + }, + { + "name": "b", + "documentation": [], + "displayParts": [ + { + "text": "b", + "kind": "parameterNmae" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Double", + "kind": "keyword" + } + ] + } + ], + "documentation": [] + } + ], + "applicableSpan": { + "start": 678, + "length": 0 + }, + "selectedItemIndex": 0, + "argumentIndex": 0, + "argumentCount": 2 + } +} diff --git a/ets2panda/bindings/test/expected/getSpanOfEnclosingComment.json b/ets2panda/bindings/test/expected/getSpanOfEnclosingComment.json new file mode 100644 index 0000000000000000000000000000000000000000..ef15b8474c684d8babe957943722f9d9ee73c7b4 --- /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 + } +} diff --git a/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json b/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json index cd3d78acf8f1199d3918b328ceab6e0403ffaafe..1b00d3a830ea2505fb10aee10847fa7c6615ab57 100644 --- a/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json +++ b/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json @@ -3,323 +3,14 @@ "diagnostics": [ { "message": "This_may_be_converted_to_an_async_function", - "source": "", "range": { "start": { - "line": 15, - "character": 609 + "line": 16, + "character": 1 }, "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 + "character": 3 } }, "tags": [], @@ -333,37 +24,14 @@ }, { "message": "This_may_be_converted_to_an_async_function", - "source": "", "range": { "start": { - "line": 18, - "character": 662 + "line": 16, + "character": 10 }, "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 + "character": 3 } }, "tags": [], @@ -377,15 +45,14 @@ }, { "message": "This_may_be_converted_to_an_async_function", - "source": "", "range": { "start": { - "line": 18, - "character": 671 + "line": 19, + "character": 1 }, "end": { - "line": 20, - "character": 717 + "line": 21, + "character": 2 } }, "tags": [], @@ -399,125 +66,14 @@ }, { "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 + "line": 19, + "character": 10 }, "end": { - "line": 20, - "character": 717 + "line": 21, + "character": 2 } }, "tags": [], @@ -531,4 +87,4 @@ } ] } -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json index 2ed128d561f1f5ac1426fe6fbeabf5752a076545..647feecc453822e604b7757f9a99a5cb47cf2f75 100644 --- a/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json +++ b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json @@ -6,7 +6,6 @@ "diagnostics": [ { "message": "Unexpected token 'add'.", - "source": "add", "range": { "start": { "line": 16, @@ -19,7 +18,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -28,7 +27,6 @@ }, { "message": "Unexpected token, expected ',' or ')'.", - "source": "*ERROR_LITERAL*", "range": { "start": { "line": 16, @@ -41,7 +39,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1229, "data": 0, "severity": 1, "codeDescription": { @@ -50,7 +48,6 @@ }, { "message": "Unexpected token ':'.", - "source": "*ERROR_LITERAL*", "range": { "start": { "line": 16, @@ -63,7 +60,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -71,21 +68,20 @@ } }, { - "message": "Unexpected token ':'.", - "source": "*ERROR_LITERAL*", + "message": "Unexpected token 'number'.", "range": { "start": { "line": 16, - "character": 14 + "character": 16 }, "end": { "line": 16, - "character": 15 + "character": 22 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -93,21 +89,20 @@ } }, { - "message": "Unexpected token ':'.", - "source": "*ERROR_LITERAL*", + "message": "Unexpected token ','.", "range": { "start": { "line": 16, - "character": 14 + "character": 22 }, "end": { "line": 16, - "character": 15 + "character": 23 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -115,21 +110,20 @@ } }, { - "message": "Unexpected token ','.", - "source": "*ERROR_LITERAL*", + "message": "Unexpected token 'b'.", "range": { "start": { "line": 16, - "character": 22 + "character": 24 }, "end": { "line": 16, - "character": 23 + "character": 24 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -137,21 +131,20 @@ } }, { - "message": "Unexpected token ','.", - "source": "*ERROR_LITERAL*", + "message": "Label must be followed by a loop statement.", "range": { "start": { "line": 16, - "character": 22 + "character": 27 }, "end": { "line": 16, - "character": 23 + "character": 33 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1038, "data": 0, "severity": 1, "codeDescription": { @@ -159,21 +152,20 @@ } }, { - "message": "Unexpected token ','.", - "source": "*ERROR_LITERAL*", + "message": "Unexpected token ')'.", "range": { "start": { "line": 16, - "character": 22 + "character": 33 }, "end": { "line": 16, - "character": 23 + "character": 34 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -181,21 +173,20 @@ } }, { - "message": "Label must be followed by a loop statement.", - "source": "", + "message": "Unexpected token '{'.", "range": { "start": { "line": 16, - "character": 27 + "character": 35 }, "end": { - "line": 16, - "character": 33 + "line": 18, + "character": 2 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -203,21 +194,70 @@ } }, { - "message": "Unexpected token ')'.", - "source": "*ERROR_LITERAL*", + "message": "return keyword should be used in function body.", + "range": { + "start": { + "line": 17, + "character": 5 + }, + "end": { + "line": 17, + "character": 18 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1163, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + } + ] + }, + "3": { + "diagnostics": [ + { + "message": "Unexpected token, expected 'from'.", "range": { "start": { "line": 16, - "character": 33 + "character": 1 }, "end": { "line": 16, - "character": 34 + "character": 52 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1228, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + } + ] + }, + "4": { + "diagnostics": [ + { + "message": "A function can only be decorated by the 'Builder'.", + "range": { + "start": { + "line": 22, + "character": 2 + }, + "end": { + "line": 22, + "character": 7 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 4000, "data": 0, "severity": 1, "codeDescription": { @@ -225,21 +265,20 @@ } }, { - "message": "Unexpected token ')'.", - "source": "*ERROR_LITERAL*", + "message": "The '@Track' annotation can decorate only member variables of a class.", "range": { "start": { - "line": 16, - "character": 33 + "line": 19, + "character": 2 }, "end": { - "line": 16, - "character": 34 + "line": 19, + "character": 7 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 4000, "data": 0, "severity": 1, "codeDescription": { @@ -247,21 +286,20 @@ } }, { - "message": "Unexpected token ')'.", - "source": "*ERROR_LITERAL*", + "message": "The '@Track' annotation can decorate only member variables of a class.", "range": { "start": { - "line": 16, - "character": 33 + "line": 22, + "character": 2 }, "end": { - "line": 16, - "character": 34 + "line": 22, + "character": 7 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 4000, "data": 0, "severity": 1, "codeDescription": { @@ -269,21 +307,41 @@ } }, { - "message": "return keyword should be used in function body.", - "source": "return ((a) + (b));", + "message": "The '@Track' annotation can decorate only member variables of a class.", "range": { "start": { - "line": 17, - "character": 5 + "line": 27, + "character": 2 }, "end": { - "line": 17, - "character": 18 + "line": 27, + "character": 7 + } + }, + "tags": [], + "relatedInfo": [], + "code": 4000, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "The '@Track' annotation can decorate only member variables of a class.", + "range": { + "start": { + "line": 36, + "character": 6 + }, + "end": { + "line": 36, + "character": 11 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 4000, "data": 0, "severity": 1, "codeDescription": { @@ -292,4 +350,4 @@ } ] } -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/expected/modifyDeclFile.json b/ets2panda/bindings/test/expected/modifyDeclFile.json new file mode 100644 index 0000000000000000000000000000000000000000..5718f834601f0bb0db309af84706591e48e639ff --- /dev/null +++ b/ets2panda/bindings/test/expected/modifyDeclFile.json @@ -0,0 +1,3 @@ +{ + "1": ["modifyDeclFile1.d.ets", "modifyDeclFile2.d.ets", "modifyDeclFile3.d.ets"] +} diff --git a/ets2panda/bindings/test/expected/provideInlayHints.json b/ets2panda/bindings/test/expected/provideInlayHints.json new file mode 100644 index 0000000000000000000000000000000000000000..8e47e660c665f5c68d3cf5daeceda5a0f4d85c14 --- /dev/null +++ b/ets2panda/bindings/test/expected/provideInlayHints.json @@ -0,0 +1,43 @@ +{ + "1": [ + { + "text": "param1", + "number": 716, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + }, + { + "text": "param2", + "number": 720, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + } + ], + "2": [ + { + "text": "item", + "number": 687, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + } + ], + "3": [ + { + "text": "key", + "number": 750, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + }, + { + "text": "val", + "number": 755, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + } + ] +} diff --git a/ets2panda/bindings/test/expected/toLineColumnOffset.json b/ets2panda/bindings/test/expected/toLineColumnOffset.json index df135e00843c85304cca7f3dea794ca01f3d70c5..0ba3e4e454c623140ae8b67aea249ab99d6448c9 100644 --- a/ets2panda/bindings/test/expected/toLineColumnOffset.json +++ b/ets2panda/bindings/test/expected/toLineColumnOffset.json @@ -6,5 +6,9 @@ "2": { "line": 17, "character": 642 + }, + "3": { + "line": 18, + "character": 708 } -} \ No newline at end of file +} diff --git a/ets2panda/bindings/test/monitor_node.js b/ets2panda/bindings/test/monitor_node.js new file mode 100644 index 0000000000000000000000000000000000000000..3fa173d538ad6b0c1225a1c5f9a49ee3ed7f3ccd --- /dev/null +++ b/ets2panda/bindings/test/monitor_node.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const { spawn } = require('child_process'); + +const child = spawn(process.argv[2], process.argv.slice(3), { + stdio: 'inherit', + detached: true, + windowsHide: true +}); + +const timeout = setTimeout(() => { + console.error('process timeout'); + child.kill('SIGKILL'); + process.exit(124); +}, 1200000); + +child.on('exit', (code, signal) => { + clearTimeout(timeout); + + if (signal === 'SIGSEGV' || signal === 'SIGABRT') { + console.error(`process crashe: ${signal}`); + process.exit(128 + signal); + } else { + process.exit(code ?? 0); + } +}); + +child.on('error', (err) => { + clearTimeout(timeout); + console.error(`Promoter process failure: ${err.message}`); + process.exit(127); +}); + +child.unref(); \ No newline at end of file diff --git a/ets2panda/bindings/test/prepare.ps1 b/ets2panda/bindings/test/prepare.ps1 index e2954bfe84f72018740c8e80d6df646cf7586e60..ac679d55c1f18c078c27a0b1b28069f20234cdc6 100644 --- a/ets2panda/bindings/test/prepare.ps1 +++ b/ets2panda/bindings/test/prepare.ps1 @@ -29,55 +29,11 @@ if ($args.Count -gt 0 -and $args[0] -eq "--restore") { $RestoreMode = 1 } -$OldPath = "path/to/bindings/test" - -$TestcasesDir = "$ScriptDir\testcases" - -if ($RestoreMode -eq 1) { - Write-Host "Restoring path '$ScriptDir' back to '$OldPath' in files..." -} -else { - Write-Host "Replacing path '$OldPath' with '$ScriptDir' in files..." -} - -function Process-Directory { - param ( - [string] $directory - ) - - if (-not (Test-Path -Path $directory -PathType Container)) { - Write-Host "Directory $directory does not exist. Skipping." - return - } - - Write-Host "Processing directory: $directory" - - $jsonFiles = Get-ChildItem -Path $directory -Filter "*.json" -File -Recurse - - foreach ($file in $jsonFiles) { - Write-Host "Processing file: $($file.FullName)" - $content = Get-Content -Path $file.FullName -Raw - - $scriptDirJson = $ScriptDir -replace '\\', '/' - - if ($RestoreMode -eq 1) { - $newContent = $content -replace [regex]::Escape($scriptDirJson), $OldPath - } - else { - $newContent = $content -replace [regex]::Escape($OldPath), $scriptDirJson - } - - Set-Content -Path $file.FullName -Value $newContent -NoNewline - } -} - -Process-Directory -directory $TestcasesDir - if ($RestoreMode -eq 1) { if (Test-Path -Path "$ScriptDir\..\ets2panda") { Remove-Item -Path "$ScriptDir\..\ets2panda" -Recurse -Force + Write-Host "Removed '$ScriptDir\..\ets2panda' directory." } - Write-Host "Path restoration completed." } else { $sourceDir = "$ScriptDir\ets\ets1.2\build-tools\ets2panda" @@ -98,7 +54,6 @@ else { try { Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Force Write-Host "Directory copied successfully from '$sourceDir' to '$destinationDir'." - Write-Host "Path replacement completed." } catch { Write-Error "Failed to copy directory." diff --git a/ets2panda/bindings/test/prepare.sh b/ets2panda/bindings/test/prepare.sh index 4b8f9c4d6f9989cd562238831504a8e37fe0cc17..c56f56120a7221614e61fa64ebd00173abc8f024 100755 --- a/ets2panda/bindings/test/prepare.sh +++ b/ets2panda/bindings/test/prepare.sh @@ -31,44 +31,12 @@ if [ "$1" == "--restore" ]; then RESTORE_MODE=1 fi -OLD_PATH="path/to/bindings/test" - -TESTCASES_DIR="${SCRIPT_DIR}/testcases" - -if [ $RESTORE_MODE -eq 1 ]; then - echo "Restoring path '${SCRIPT_DIR}' back to '${OLD_PATH}' in files..." -else - echo "Replacing path '${OLD_PATH}' with '${SCRIPT_DIR}' in files..." -fi - -process_directory() { - local dir=$1 - - if [ ! -d "$dir" ]; then - echo "Directory $dir does not exist. Skipping." - return - fi - - echo "Processing directory: $dir" - - find "$dir" -type f -name "*.json" | while read -r file; do - echo "Processing file: $file" - if [ $RESTORE_MODE -eq 1 ]; then - sed -i "s|${SCRIPT_DIR}|${OLD_PATH}|g" "$file" - else - sed -i "s|${OLD_PATH}|${SCRIPT_DIR}|g" "$file" - fi - done -} - -process_directory "$TESTCASES_DIR" - if [ $RESTORE_MODE -eq 1 ]; then rm "${SCRIPT_DIR}/../ets2panda" - echo "Path restoration completed." + echo 'Remove the symbolic link to ets2panda' else ln -s "${SCRIPT_DIR}/ets/ets1.2/build-tools/ets2panda" "${SCRIPT_DIR}/../ets2panda" - echo "Path replacement completed." + echo 'Create a symbolic link to ets2panda' fi exit 0 diff --git a/ets2panda/bindings/test/run_bindings.sh b/ets2panda/bindings/test/run_bindings.sh new file mode 100755 index 0000000000000000000000000000000000000000..7fef1f2f16c23a3fbecf887dbaab90835f1141e3 --- /dev/null +++ b/ets2panda/bindings/test/run_bindings.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +readonly TEST_DIR="$1" +readonly NODE_DIR="$2" +readonly SDK_DIR="$3" +readonly CWD="${TEST_DIR}/../" +readonly CURRENT_NPM="${NODE_DIR}/npm" +readonly CURRENT_NODE="${NODE_DIR}/node" + +cp -rfp -- "$SDK_DIR" "$TEST_DIR" +cd "$CWD" && "$CURRENT_NPM" run test:build +if [ $? -eq 0 ]; then + echo "bindings test build successfully" +else + echo "bindings test build failed" + exit 1 +fi + +"$CURRENT_NODE" test/monitor_node.js "$CURRENT_NODE" --unhandled-rejections=strict dist-test/test/run_tests.js ./test +exit_code=$? +if [ $exit_code -eq 0 ]; then + echo "test execution successfully" +else + echo "test execution failed" + exit $exit_code +fi diff --git a/ets2panda/bindings/test/run_tests.ts b/ets2panda/bindings/test/run_tests.ts index 3eeb124ee0a45db43d354f309d9ecc96a3db3f77..f76d28a06689bfff32e54894d1c7eb797eb63c5b 100644 --- a/ets2panda/bindings/test/run_tests.ts +++ b/ets2panda/bindings/test/run_tests.ts @@ -15,38 +15,30 @@ import path from 'path'; import fs from 'fs'; -import { - Lsp, - LspDefinitionData, - LspCompletionInfo, - LspDiagsNode, - ModuleDescriptor, - generateArkTsConfigByModules -} from '../src/index'; - -interface TestConfig { - expectedFilePath: string; - // CC-OFFNXT(no_explicit_any) project code style - [key: string]: Array | string; -} +import { Lsp, LspDefinitionData, LspCompletionInfo, LspDiagsNode, ModuleDescriptor, PathConfig } from '../src/index'; +import { TestCases, basicCases } from './cases'; +import { LspCompletionEntry } from '../src/lsp/lspNode'; +import { diff } from 'jest-diff'; -interface TestCases { - [testName: string]: TestConfig; +interface NormalizeOptions { + fieldsToDelete?: string[]; // try to delete these fields in the expected result, just focus on the important fields + normalizeFileName?: boolean; } -let updateMode = false; +interface ComparisonOptions { + subMatch?: boolean; +} -function checkEnvironment(testDir: string): void { - const testCasesFilePath = path.join(testDir, 'testcases', 'cases.json'); - if (!fs.existsSync(testCasesFilePath)) { - console.error(`Test cases file not found: ${testCasesFilePath}`); - process.exit(1); - } +interface ComparisonOutcome { + passed: boolean; + expectedJSON?: string; + actualJSON?: string; } -function getModules(projectRoot: string): ModuleDescriptor[] { - const testCases = JSON.parse(fs.readFileSync(path.join(projectRoot, 'cases.json'), 'utf-8')) as TestCases; - return Object.keys(testCases).map((name) => { +let updateMode = false; + +function getModules(projectRoot: string, cases: TestCases): ModuleDescriptor[] { + return Object.keys(cases).map((name) => { const modulePath = path.join(projectRoot, name); return { arktsversion: '1.2', @@ -67,6 +59,16 @@ function getExpectedResult(filePath: string): any { } } +// CC-OFFNXT(no_explicit_any) project code style +function getFilesByDir(dirPath: string): string[] { + try { + return fs.readdirSync(dirPath).filter((file) => fs.statSync(path.join(dirPath, file)).isFile()); + } catch (err) { + console.error(`Failed to load files from ${dirPath}: ${err}`); + return []; + } +} + function sortCompletions(completionResult: LspCompletionInfo): LspCompletionInfo { if (!completionResult || !completionResult.entries || !Array.isArray(completionResult.entries)) { return completionResult; @@ -118,19 +120,27 @@ function sortActualResult(testName: string, res: any): any { } // CC-OFFNXT(no_explicit_any) project code style -function normalizeData(obj: any): any { +function normalizeData(obj: any, options: NormalizeOptions = {}): any { + const { fieldsToDelete = [], normalizeFileName = true } = options; if (Array.isArray(obj)) { - return obj.map(normalizeData); + return obj.map((item) => normalizeData(item, options)); } else if (obj && typeof obj === 'object') { const newObj = { ...obj }; + // always remove 'peer' field if ('peer' in newObj) { - delete newObj.peer; // do not compare peer + delete newObj.peer; } - if (newObj.fileName) { + // remove specified fields + fieldsToDelete.forEach((field) => { + if (field in newObj) { + delete newObj[field]; + } + }); + if (normalizeFileName && newObj.fileName) { newObj.fileName = path.basename(newObj.fileName); } for (const key of Object.keys(newObj)) { - newObj[key] = normalizeData(newObj[key]); + newObj[key] = normalizeData(newObj[key], options); } return newObj; } @@ -138,23 +148,121 @@ function normalizeData(obj: any): any { } // CC-OFFNXT(no_explicit_any) project code style -function compareResultsHelper(testName: string, actual: any, expected: any): boolean { - const normalizedActual = normalizeData(actual); +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: 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; - } else { - console.log(`[${testName}] ❌ Failed`); - console.log(`Expected: ${expectedJSON}`); - console.log(`Actual: ${actualJSON}`); + } + + console.log(`[${testName}] ❌ Failed`); + const diffResult = diff(comparison.expectedJSON, comparison.actualJSON); + if (diffResult) { + console.log(diffResult); } return false; } +function compareGetCompletionResult(testName: string, actual: unknown, expected: unknown): [boolean, unknown] { + 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; + }[]; + + const actualData = normalizeData(actualEntries); + return [ + compareResultsHelper(testName, actualData, expectedEntries, { + subMatch: true + } as ComparisonOptions), + actualData + ]; +} + +function compareDeclFileResult(testName: string, declgenOutDir: string, expected: unknown): [boolean, unknown] { + let fileList: string[] = getFilesByDir(declgenOutDir); + const actualEntries = fileList.filter((file) => file.endsWith('.d.ets')); + const expectedEntries = expected as string[]; + const actualData = normalizeData(actualEntries); + return [ + compareResultsHelper(testName, actualData, expectedEntries, { + subMatch: true + } as ComparisonOptions), + actualData + ]; +} + function findTextDefinitionPosition(sourceCode: string): number { const textDefinitionPattern = /export\s+declare\s+function\s+Text\(/; const match = textDefinitionPattern.exec(sourceCode); @@ -169,46 +277,92 @@ function findTextDefinitionPosition(sourceCode: string): number { throw new Error('Could not find Text definition in source code'); } +// CC-OFFNXT(huge_cyclomatic_complexity, huge_depth, huge_method) false positive +function findTaskDefinitionPosition(sourceCode: string): number { + const taskDefinitionPattern = /export\s+class\s+Task\s+{/; + const match = taskDefinitionPattern.exec(sourceCode); + if (match) { + const classTaskPattern = /class\s+Task\s+{/; + const subMatch = classTaskPattern.exec(sourceCode.substring(match.index)); + if (subMatch) { + const positionOfT = match.index + subMatch.index + 'class '.length; + return positionOfT; + } + } + throw new Error('Could not find Task definition in source code'); +} + function compareGetDefinitionResult( testName: string, - index: string, - actual: any, + actual: unknown, expected: Record -) { +): [boolean, unknown] { + let expectedResult = expected; + const actualDef = actual as LspDefinitionData; + const fileName = actualDef.fileName as string; + const fileContent = fs.readFileSync(fileName, 'utf8'); // 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 = { + expectedResult = { + ...expected, + start: expectedStart + }; + } + // This is the definition info for the class in std library. + // File in the SDK might changed, so the offset needs to be checked dynamically. + if (expected['fileName'] === 'taskpool.ets') { + const expectedStart = findTaskDefinitionPosition(fileContent); + expectedResult = { ...expected, start: expectedStart }; - return compareResultsHelper(`${testName}:${index}`, actual, expectedResult); } - return compareResultsHelper(`${testName}:${index}`, actual, expected); + const actualData = normalizeData(actual); + return [compareResultsHelper(testName, actualData, expectedResult), actualData]; } -// CC-OFFNXT(no_explicit_any) project code style -function compareResults(testName: string, index: string, actual: any, expected: any) { +function compareResults( + caseName: string, + actual: unknown, + expected: unknown, + pathConfig: PathConfig +): [boolean, unknown] { + const testName = caseName.substring(0, caseName.indexOf(':')); if (testName === 'getDefinitionAtPosition') { - return compareGetDefinitionResult(testName, index, actual, expected); + return compareGetDefinitionResult(caseName, actual, expected as Record); + } + if (testName === 'getCompletionAtPosition') { + return compareGetCompletionResult(caseName, actual, expected); + } + if (testName === 'generateDeclFile') { + const declOutPath = path.join(pathConfig.declgenOutDir, testName, 'declgen', 'static'); + return compareDeclFileResult(caseName, declOutPath, expected); + } + if ( + testName === 'getSemanticDiagnostics' || + testName === 'getSyntacticDiagnostics' || + testName === 'getSuggestionDiagnostics' + ) { + const normalizeOption: NormalizeOptions = { + fieldsToDelete: ['source'] + }; + const actualData = normalizeData(actual, normalizeOption); + return [compareResultsHelper(caseName, actualData, expected), actualData]; } - return compareResultsHelper(`${testName}:${index}`, actual, expected); + + const actualData = normalizeData(actual); + return [compareResultsHelper(caseName, actualData, expected), actualData]; } -function runTests(testDir: string, lsp: Lsp) { +function runTests(lsp: Lsp, cases: TestCases, failedList: string[], pathConfig: PathConfig): string[] { console.log('Running tests...'); - const testCases = JSON.parse(fs.readFileSync(path.join(testDir, 'testcases', 'cases.json'), 'utf-8')) as TestCases; - if (!testCases) { - console.error('Failed to load test cases'); - return; + if (!cases) { + return []; } - let failedList: string[] = []; - for (const [testName, testConfig] of Object.entries(testCases)) { + for (const [testName, testConfig] of Object.entries(cases)) { const { expectedFilePath, ...testCaseVariants } = testConfig; const expectedResult = getExpectedResult(expectedFilePath); if (expectedResult === null) { @@ -223,12 +377,13 @@ function runTests(testDir: string, lsp: Lsp) { for (const [index, params] of Object.entries(testCaseVariants)) { let pass = false; + let actualData = undefined; 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]); + [pass, actualData] = compareResults(`${testName}:${index}`, actualResult, expectedResult[index], pathConfig); } catch (error) { console.error(`[${testName}:${index}] ❌ Error: ${error}`); } @@ -237,7 +392,7 @@ function runTests(testDir: string, lsp: Lsp) { } if (!pass && updateMode) { console.log(`Updating expected result for ${testName}:${index}`); - expectedResult[index] = normalizeData(actualResult); + expectedResult[index] = actualData; } } if (updateMode) { @@ -246,13 +401,62 @@ function runTests(testDir: string, lsp: Lsp) { console.log(`Finished test: ${testName}`); console.log('-----------------------------------'); } + return failedList; +} + +function run(testDir: string, pathConfig: PathConfig): void { + let failedList: string[] = []; + + const basicModules = getModules(pathConfig.projectPath, basicCases); + const basicLsp = new Lsp(pathConfig, undefined, basicModules); + failedList = runTests(basicLsp, basicCases, failedList, pathConfig); + + console.log('Tests completed.'); + if (failedList.length > 0) { + console.log('❌ Failed tests:'); + failedList.forEach((failedCase: string) => { + console.log(`- ${failedCase}`); + }); + + console.error('Tests failed without AST cache'); + process.exit(1); + } + console.log('Finished test without ast cache'); +} + +async function runWithAstCache(testDir: string, pathConfig: PathConfig): Promise { + let failedList: string[] = []; + // for generate ast cache + const entry_module = [ + { + name: 'entry', + moduleType: 'har', + srcPath: path.join(pathConfig.projectPath, 'entry') + }, + { + name: 'getDefinitionAtPosition', + moduleType: 'har', + srcPath: path.join(pathConfig.projectPath, 'getDefinitionAtPosition') + } + ]; + + const basicModules = getModules(pathConfig.projectPath, basicCases); + const basicLsp = new Lsp(pathConfig, undefined, entry_module); + await basicLsp.initAstCache(); + basicLsp.update(basicModules); + failedList = runTests(basicLsp, basicCases, failedList, pathConfig); + console.log('Tests completed.'); if (failedList.length > 0) { console.log('❌ Failed tests:'); - failedList.forEach((failedCase) => { + failedList.forEach((failedCase: string) => { console.log(`- ${failedCase}`); }); + + console.error('Tests failed with AST cache'); + process.exit(1); } + console.log('Finished test with ast cache'); } if (require.main === module) { @@ -264,15 +468,18 @@ if (require.main === module) { if (process.argv[3] && process.argv[3] === '--update') { updateMode = true; } - const testDir = path.resolve(process.argv[2]); - checkEnvironment(testDir); - 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); + const testDir = path.resolve(process.argv[2]); + const pathConfig: PathConfig = { + buildSdkPath: path.join(testDir, 'ets', 'ets1.2'), + projectPath: path.join(testDir, 'testcases'), + declgenOutDir: path.join(testDir, 'testcases', '.idea', '.deveco') + }; - process.env.BINDINGS_PATH = path.join(buildSdkPath, 'build-tools', 'bindings'); - runTests(testDir, lsp); + process.env.BINDINGS_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'bindings'); + process.env.PANDA_LIB_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'ets2panda', 'lib'); + process.env.PANDA_BIN_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'ets2panda', 'bin'); + run(testDir, pathConfig); + runWithAstCache(testDir, pathConfig).then(() => {}); + fs.writeFileSync('./finished.txt', 'success', 'utf8'); } diff --git a/ets2panda/bindings/test/testcases/cases.json b/ets2panda/bindings/test/testcases/cases.json deleted file mode 100644 index 6e708b142563391b18964014fc043fa85f472664..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/test/testcases/cases.json +++ /dev/null @@ -1,225 +0,0 @@ -{ - "getDefinitionAtPosition": { - "expectedFilePath": "path/to/bindings/test/expected/getDefinitionAtPosition.json", - "1": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets", - 655 - ], - "2": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition3.ets", - 662 - ], - "3": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition5.ets", - 664 - ], - "4": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition7.ets", - 683 - ], - "5": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition9.ets", - 666 - ], - "6": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition11.ets", - 675 - ], - "7": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets", - 664 - ], - "8": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.ets", - 617 - ], - "9": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.ets", - 677 - ], - "10": [ - "path/to/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition18.ets", - 930 - ] - }, - "getSemanticDiagnostics": { - "expectedFilePath": "path/to/bindings/test/expected/getSemanticDiagnostics.json", - "1": [ - "path/to/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.ets" - ], - "2": [ - "path/to/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.ets" - ] - }, - "getCurrentTokenValue": { - "expectedFilePath": "path/to/bindings/test/expected/getCurrentTokenValue.json", - "1": [ - "path/to/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue1.ets", - 611 - ], - "2": [ - "path/to/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue2.ets", - 612 - ], - "3": [ - "path/to/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue3.ets", - 612 - ], - "4": [ - "path/to/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue4.ets", - 611 - ] - }, - "getFileReferences": { - "expectedFilePath": "path/to/bindings/test/expected/getFileReferences.json", - "1": [ - "path/to/bindings/test/testcases/getFileReferences/getFileReferences1_export.ets" - ] - }, - "getReferencesAtPosition": { - "expectedFilePath": "path/to/bindings/test/expected/getReferencesAtPosition.json", - "1": [ - "path/to/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets", - 613 - ], - "2": [ - "path/to/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition2.ets", - 635 - ], - "3": [ - "path/to/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition4.ets", - 625 - ] - }, - "getSyntacticDiagnostics": { - "expectedFilePath": "path/to/bindings/test/expected/getSyntacticDiagnostics.json", - "1": [ - "path/to/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.ets" - ], - "2": [ - "path/to/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.ets" - ] - }, - "getSuggestionDiagnostics": { - "expectedFilePath": "path/to/bindings/test/expected/getSuggestionDiagnostics.json", - "1": [ - "path/to/bindings/test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.ets" - ] - }, - "getQuickInfoAtPosition": { - "expectedFilePath": "path/to/bindings/test/expected/getQuickInfoAtPosition.json", - "1": [ - "path/to/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition1.ets", - 626 - ], - "2": [ - "path/to/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition2.ets", - 618 - ], - "3": [ - "path/to/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition3.ets", - 663 - ] - }, - "getDocumentHighlights": { - "expectedFilePath": "path/to/bindings/test/expected/getDocumentHighlights.json", - "1": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights1.ets", - 614 - ], - "2": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights2.ets", - 717 - ], - "3": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights3.ets", - 616 - ], - "4": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights4.ets", - 626 - ], - "5": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights5.ets", - 619 - ], - "6": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights6.ets", - 657 - ], - "7": [ - "path/to/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights7.ets", - 733 - ] - }, - "getCompletionAtPosition": { - "expectedFilePath": "path/to/bindings/test/expected/getCompletionAtPosition.json", - "1": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition1.ets", - 705 - ], - "2": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition2.ets", - 735 - ], - "3": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition3.ets", - 789 - ], - "4": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition4.ets", - 767 - ], - "5": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition5.ets", - 728 - ], - "6": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition6.ets", - 718 - ], - "7": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition7.ets", - 683 - ], - "8": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition8.ets", - 614 - ], - "9": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition9.ets", - 619 - ], - "10": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition10.ets", - 712 - ], - "11": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition11.ets", - 682 - ], - "12": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition12.ets", - 720 - ], - "13": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition13.ets", - 658 - ], - "14": [ - "path/to/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition14.ets", - 659 - ] - }, - "toLineColumnOffset": { - "expectedFilePath": "path/to/bindings/test/expected/toLineColumnOffset.json", - "1": [ - "path/to/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset1.ets", - 0 - ], - "2": [ - "path/to/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset1.ets", - 642 - ] - } -} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/entry/Index.ets b/ets2panda/bindings/test/testcases/entry/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..189cfcde579834bd993b7f0e25add712d2ebde1a --- /dev/null +++ b/ets2panda/bindings/test/testcases/entry/Index.ets @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use static'; +import { Text, Column, Component, Entry, Button, ClickEvent } from "@ohos.arkui.component" +import { State, Link, Prop } from "@ohos.arkui.stateManagement" +import hilog from '@ohos.hilog' + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = "state var"; + message: string = `click to change state variable, add **`; + changeValue() { + this.stateVar+="**" + } + build() { + Column() { + Button("clean variable").onClick((e: ClickEvent) => { this.stateVar = "state var" }) + Text("Hello World").fontSize(20) + Button(this.message).backgroundColor("#FFFF00FF") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue() + }) + Text(this.stateVar).fontSize(20) + Child({linkVar: this.stateVar, propVar: this.stateVar}) + }.margin(10) + } +} + +@Component +struct Child { + @Link linkVar: string = ""; // TODO: remove this + @Prop propVar: string = "Prop"; + + changeValue1() { + this.linkVar+="!!" + } + + changeValue2() { + this.propVar+="~~" + } + + build() { + Column() { + Button(`click to change Link variable, add symbol !!`) + .backgroundColor("#4169E1") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue1() + }) + Button(`click to change Prop variable, add symbol ~~`) + .backgroundColor("#3CB371") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue2() + }) + Text(`Link variable in child: ${this.linkVar}`).fontSize(30) + Text(`Prop variable in child: ${this.propVar}`).fontSize(30) + } + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations1.ets b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations1.ets new file mode 100644 index 0000000000000000000000000000000000000000..8fe412caf8c78831989ab3ffafb3794ee73091af --- /dev/null +++ b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations1.ets @@ -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. + */ + +export function abc(x: number): void { +} + +export function dummy(x: number): void { +} + +export class Foo { + name: string = "unassigned"; + x: number = 1; + y: number = 2; + z: number = 3; + constructor(name: string, x: number, y: number, z: number) { + this.name = name; + this.x = x; + this.y = y; + this.z = z; + } +}; + +export class Oranges { + name: string = "unassigned"; + x: number = 1; + y: number = 2; + z: number = 3; + constructor(name: string, x: number, y: number, z: number) { + this.name = name; + this.x = x; + this.y = y; + this.z = z; + } +}; + +dummy(0); +dummy(1); +abc(2); +abc(3); +abc(4); diff --git a/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations2.ets b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations2.ets new file mode 100644 index 0000000000000000000000000000000000000000..e37a0e5fc26bcbe61b345858655df093f17a14ed --- /dev/null +++ b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations2.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 { dummy, abc, Foo } from "./findRenameLocations1.ets"; + +dummy(4); +dummy(44); +abc(5); +abc(55); +abc(555); + +let myfoo = new Foo("apples", 1, 2, 3); +let otherfoo = new Foo("oranges", 4, 5, 6); + +console.log(myfoo) +console.log(otherfoo) +console.log(myfoo.name) diff --git a/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations3.ets b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations3.ets new file mode 100644 index 0000000000000000000000000000000000000000..32ecfad4230cd5ab9f0c9e21562aafb91c5ff2f3 --- /dev/null +++ b/ets2panda/bindings/test/testcases/findRenameLocations/findRenameLocations3.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 { Foo as Fooo } from "./findRenameLocations1.ets"; + +let myfoo = new Fooo("apples", 1, 2, 3); +console.log(myfoo.name) diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile1.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile1.ets new file mode 100644 index 0000000000000000000000000000000000000000..ebbdf6372c5e2dd72e260bb5fc40ce0ff703db3d --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile1.ets @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use static'; +let currentValue: string = 'currentValue'; + +let resultValue: number = -1; + +let mathRandom: number = 14; + +function getCurrentValue(): number { + let firstValue = getFirstValue(); + let secondValue = getSecondValue(); + let thridValue = getThridValue(); + resultValue = currentValue.length; + return currentValue.length; +} + +function getFirstValue(): number { + let c = 15; + let value = c * mathRandom; + mathRandom++; + EtsStepArkTest() + return value; +} + +function getSecondValue(): number { + let d = 11; + let value1 = getFirstValue(); + return value1 * d; +} + +function getThridValue(): number { + let value1 = getFirstValue(); + let value2 = getSecondValue(); + return value1 * value2; +} + +function getValue(): string { + return getCurrentValue() + currentValue; +} + +getValue(); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile10.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile10.ets new file mode 100644 index 0000000000000000000000000000000000000000..da4d794ca3b99ba682023bc89d37f17073c9467a --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile10.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. + */ + +'use static'; +interface Employee { + name: string; + salary: number; + hasBonus: boolean; +} + +function calculateTotalSalary(employees: Employee[]): number { + const bonusAmount = 500; + + let totalSalary = 0; + EtsStepArkTest(); + + for (const employee of employees) { + let adjustedSalary = employee.salary; + if (employee.hasBonus) { + adjustedSalary += bonusAmount; + } + totalSalary += adjustedSalary; + } + return totalSalary; +} + +const employees: Employee[] = [ + { name: "Alice", salary: 3000, hasBonus: true }, + { name: "Bob", salary: 2800, hasBonus: false }, + { name: "Charlie", salary: 3200, hasBonus: true }, + { name: "David", salary: 2900, hasBonus: false } +]; + +const totalSalary = calculateTotalSalary(employees); diff --git a/ets2panda/driver/build_system/src/utils.ts b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile11.ets similarity index 36% rename from ets2panda/driver/build_system/src/utils.ts rename to ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile11.ets index 50138e67e5fd9e0303ddcddb3b0ba20b58c262da..fb246bcd3eb036f4a5f5c8a3391ce70109f17851 100644 --- a/ets2panda/driver/build_system/src/utils.ts +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile11.ets @@ -13,45 +13,46 @@ * limitations under the License. */ -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; +'use static'; +class ChainCalculator { + private result: number; -const WINDOWS: string = 'Windows_NT'; -const LINUX: string = 'Linux'; -const MAC: string = 'Darwin'; - -export function isWindows(): boolean { - return os.type() === WINDOWS; -} + constructor(initialValue: number) { + this.result = initialValue; + } -export function isLinux(): boolean { - return os.type() === LINUX; -} + add(value: number): ChainCalculator { + this.result += value; + return this; + } -export function isMac(): boolean { - return os.type() === MAC; -} + subtract(value: number): ChainCalculator { + this.result -= value; + return this; + } -export function changeFileExtension(file: string, targetExt: string, originExt = ''): string { - let currentExt = originExt.length === 0 ? path.extname(file) : originExt; - let fileWithoutExt = file.substring(0, file.lastIndexOf(currentExt)); - return fileWithoutExt + targetExt; -} + multiply(value: number): ChainCalculator { + this.result *= value; + return this; + } -export function ensurePathExists(filePath: string): void { - try { - const dirPath: string = path.dirname(filePath); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath, { recursive: true }); - } - } catch (error) { - if (error instanceof Error) { - console.error(`Error: ${error.message}`); + divide(value: number): ChainCalculator { + EtsStepArkTest(); + if (value === 0) { + throw new Error("Division by zero is not allowed."); } + this.result /= value; + return this; } -} -export function isFileExistSync(filePath: string): boolean { - return fs.existsSync(filePath); + getResult(): number { + return this.result; + } + + geFinalResult(addValue: number, subtractValue: number, multiplyValue: number, divideValue: number): number { + return chainCalc.add(addValue).subtract(subtractValue).multiply(multiplyValue).divide(divideValue).getResult(); + } } + +const chainCalc = new ChainCalculator(10); +chainCalc.geFinalResult(2, 4, 6, 3); diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile12.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile12.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba3570e77de98a435f733c5af0c37480cc5270f9 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile12.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'; +function getC(a:number, b:number): number { + return a + b; +} + +getC(1, 120); diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile2.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile2.ets new file mode 100644 index 0000000000000000000000000000000000000000..9eeac9237d4394ca64a71677904d303e2920632f --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile2.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'; +export class Foo { + Foo(a:number, b:number): number { + return a + b; + } +} diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile3.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile3.ets new file mode 100644 index 0000000000000000000000000000000000000000..40e6333b3955a2fd80891e3095920e70f97f1c32 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile3.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'; +function A(a:number, b:number): number { + return a + b; +} +A(1, 2); +function A(a:number): number { + return a; +} +A(1); diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile4.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile4.ets new file mode 100644 index 0000000000000000000000000000000000000000..d49c3c33adeba8824c45ed269d11a5f55dff9de2 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile4.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. + */ + +'use static'; +export class A { + Foo(a:number, b:number): number { + return a + b; + } + readTest1(c:number, d:number): number { + return a - b; + } + + readTest2(e:number, f:number): number { + return a * b; + } + + readTest3(e:number, f:number): number { + return a / b; + } +}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile5.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile5.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf17f12cc61c35012bb59f6e77658096ff0ed052 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile5.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'; +export class A { + Foo(a:number, b:number): number { + return a + b; + } +} diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile6.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile6.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd7d740cff72a0b061ec744325fc40950b672aa9 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile6.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. + */ + +'use static'; +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/generateDeclFile/generateDeclFile7.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile7.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb91ea0d539d16e88223eb85564b709cacfa3ebd --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile7.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. + */ + +'use static'; +interface DataValue { + a: number; + b: string; + c: string; + d: number; +} + +let currentValue: DataValue = { + a: 12, + b: 'da', + c: 'vk', + d: 1111 +}; + +let result: number = 0; + +let resultStr: number = 0; + +let resultValue: number = -1; + +let mathRandom: number = 14; + +function getPath(c: number, d: number): number { + return c * d; +} + +function getPathDate(c: number): number { + return c * 2 + 6; +} + +function getCurrentValue(): DataValue { + let currentValue: DataValue = { + a: 12, + b: 'da', + c: 'vk', + d: 1111 + }; + currentValue.a = getFirstValue(); + currentValue.d = getSecondValue(); + currentValue.c = getThridValue() + getSecondValue() + getFirstValue(); + currentValue.b = getThridValue() + getSecondValue() + getFirstValue() + resultValue; + EtsStepArkTest() + while(currentValue.a < 12) { + if (resultValue % 2 === 0) { + currentValue.a = currentValue.a++; + } else { + currentValue.d = currentValue.d--; + } + } + return currentValue; +} + +function getFirstValue(): number { + let currentFirstValue: DataValue = { + a: 23, + b: '124.0f', + c: 'gfr', + d: 767 + }; + EtsStepArkTest() + return getPath(currentFirstValue.a, currentFirstValue.d); +} + +function getSecondValue(): number { + for(let index = 0; index < 2; index++) { + result = getPathDate(index); + } + return result; +} + +function getThridValue(): string { + let dd: string = ''; + for(let index = 0; index< 2; index++) { + dd = resultStr + getPathDate(index) + 'abc'; + } + EtsStepArkTest() + return dd; +} + +function getValueStr(): string { + return getCurrentValue().b + currentValue; +} + +getValueStr(); diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile8.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile8.ets new file mode 100644 index 0000000000000000000000000000000000000000..17d00a69d1d7e292cd802431165565541b00d80a --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile8.ets @@ -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. + */ + +'use static'; +function func06(): void { + EtsStepArkTest(); +} + +function func05(): void { + func06(); + EtsStepArkTest(); +} + +function func04(): void { + func05(); + EtsStepArkTest(); +} + +function func03(): void { + let id = 0; + for (let i = 0; i < 10; ++i) { + id++ + } + func04(); + EtsStepArkTest(); +} + +function func02(): void { + func03(); + EtsStepArkTest(); +} + +function func01(): void { + func02(); + EtsStepArkTest(); +} + +function main(argc:string[]): void { + func01(); +} diff --git a/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile9.ets b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile9.ets new file mode 100644 index 0000000000000000000000000000000000000000..107588b45c7deebc13424668657890ae174b5e11 --- /dev/null +++ b/ets2panda/bindings/test/testcases/generateDeclFile/generateDeclFile9.ets @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use static'; +interface FileDataValue { + fileName: string; + filePath: string; + data: DataValue; +} + +interface DataValue { + dataLength: number; + dataOffset: number; + dataStr: string; +} + +class OperationFactory { + private currentType: string = 'add'; + + createOperation(type: 'add' | 'subtract' | 'multiply' | 'divide', a: number, b: number): number { + this.currentType = type; + switch (type) { + case 'add': + return a + b; + case 'subtract': + return a - b; + case 'multiply': + return a * b; + case 'divide': + if (b === 0) { + throw new Error("Division by zero is not allowed."); + } + return a / b; + default: + throw new Error("Unknown operation type"); + } + } +} + +function getFileDate(): FileDataValue[] { + let FileDataValues: FileDataValue[] = [{ + fileName: 'OperationFactoryFile', + filePath: 'source/url/OperationFactoryFile', + data: { + dataLength: 10, + dataOffset: 2, + dataStr: 'This is a test data!' + } + }]; + EtsStepArkTest(); + return FileDataValues; +} + +function getOperationFactory(): void { + getFileDate(); + const factory = new OperationFactory(); + factory.createOperation('add', 2, 3); + factory.createOperation('subtract', 5, 5); + factory.createOperation('multiply', 3, 6); + factory.createOperation('divide', 2, 2); +} + +getOperationFactory(); diff --git a/ets2panda/bindings/test/testcases/getCodeFixesAtPosition/getCodeFixesAtPosition1.ets b/ets2panda/bindings/test/testcases/getCodeFixesAtPosition/getCodeFixesAtPosition1.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ac051ca62dbfb06be443f68172bf3ed900b0101 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCodeFixesAtPosition/getCodeFixesAtPosition1.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. + */ + +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement' +import { + Entry + Text, + TextAttributes, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView +} from '@ohos.arkui.component' +import { State, MutableSate, stateOf, observableProxy } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .onClick(() => { + console.info("hello, :") + console.log(result.toString()) + }) + .width('100%') + } + .height('100%') + } +} + +@Entry +@Component +struct Index { + build() {} +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getColAndLineByOffset/getColAndLineByOffset1.ets b/ets2panda/bindings/test/testcases/getColAndLineByOffset/getColAndLineByOffset1.ets new file mode 100644 index 0000000000000000000000000000000000000000..aece61fb54097614fdede1cf87e302f5f888a1e5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getColAndLineByOffset/getColAndLineByOffset1.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. + */ + +// comment of line + +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement' +import { + Entry + Text, + TextAttributes, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView +} from '@ohos.arkui.component' +import { State, MutableSate, stateOf, observableProxy } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .onClick(() => { + console.info("hello, :") + console.log(result.toString()) + }) + .width('100%') + } + .height('100%') + } +} diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition15.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition15.ets new file mode 100644 index 0000000000000000000000000000000000000000..d00b745ae4d0f96ac9e707f0ed4c4fed03127067 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition15.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); +stk.p diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition16.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition16.ets new file mode 100644 index 0000000000000000000000000000000000000000..c0d3b068da3eb48be767b83ea6637bebaf9844ad --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition16.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 @interface Entry { + routeName: string = ""; + storage: string = ""; +} +export @interface TestAnnotation { + routeName: string = ""; + storage: string = ""; +} diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition17.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition17.ets new file mode 100644 index 0000000000000000000000000000000000000000..9630f909cf0f6f2ccf489caa82055e68d6919a81 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition17.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, TestAnnotation } from './getCompletionsAtPosition16'; +export @interface Entry2 { + routeName: string = ""; + storage: string = ""; +} +@E +struct Index {} +@ +struct Index1 {} diff --git a/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue5.ets b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue5.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c76d7275e73210dc679cc43e75c2195a1e1f27 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue5.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.ets new file mode 100755 index 0000000000000000000000000000000000000000..fc811ab595deb7697c8748ef83cea4f1b3a609eb --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition19.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. + */ + +const task = new taskpool.Task(()=>{}); diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition20.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition20.ets new file mode 100644 index 0000000000000000000000000000000000000000..aefa90a9ab72ef65f6aaaf14437197f5c4040298 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition20.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. + */ + +'use static'; +export class Foo { } \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition21.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition21.ets new file mode 100644 index 0000000000000000000000000000000000000000..a9ba406e87c3b3c7ecadc5648a8497bff6cbf600 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition21.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'; + +export class Foo { + bar() {} +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition22.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition22.ets new file mode 100644 index 0000000000000000000000000000000000000000..1343348275d440e2d54684b0d015f5450aa18632 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition22.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'; + +export class Foo { + static staticProperty: number = 42; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition23.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition23.ets new file mode 100644 index 0000000000000000000000000000000000000000..62738079667eb81e86121d5a9e2e3c349cc6d5e4 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition23.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'; + +export class Foo { + bar() {} +} +let foo = new Foo(); +foo.bar(); diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition24.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition24.ets new file mode 100644 index 0000000000000000000000000000000000000000..13f8907a12df6a8b22c6759e008a8856ba5f3f8f --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition24.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 { PI } from "./index.ets"; diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition25.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition25.ets new file mode 100644 index 0000000000000000000000000000000000000000..5dec340b1a8cda536a49bd59007f610630251bb5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition25.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'; + +export interface User { + bar(): void; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition26.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition26.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d9e3d43acec98f7314ff9bc5f0d3f9d19af9cce --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition26.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 type ID = string | number; diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition27.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition27.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3a410f143160f774c1f385da3e904eaf7fee67d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition27.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'; + +export enum Color { + Red, + Green, + Blue +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition28.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition28.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3a410f143160f774c1f385da3e904eaf7fee67d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition28.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'; + +export enum Color { + Red, + Green, + Blue +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition30.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition30.ets new file mode 100644 index 0000000000000000000000000000000000000000..40b338c4ab61067d8efb641a75bf6b797ea08616 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition30.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. + */ + +'use static'; + +export interface Printable { + print(): void; + getTitle(): string; +} + +export class Document implements Printable { + constructor() {} + + print(): void { + } + + getTitle(): string { + return ""; + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.ets new file mode 100644 index 0000000000000000000000000000000000000000..8131d277b7e3f75f6b2ff6cee060e6ff9182e90c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.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'; + +export type Direction = 'up' | 'down' | 'left' | 'right'; +export function move(dir: Direction): void { + let a = 'aaa'; + const b: Direction = 'up'; + let c = true; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.ets new file mode 100644 index 0000000000000000000000000000000000000000..b928f78527150f8db34a364fb2d1af42a9e744fe --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.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. + */ + +'use static'; + +@interface Validate { + +} + +@interface Log { + level: string; +} + +@interface Component1 { + name: string; + version: number; +} + +@interface Deprecated { + +} + +@Component1({name: 'Service', version: 1}) +export class Service { + @Validate + @Log({level: 'info'}) + doSomething() { + } + + @Deprecated + oldMethod() { + } +} + diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.ets new file mode 100644 index 0000000000000000000000000000000000000000..466545ff5721b0daba1babef9f5ebab77308aca3 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.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'; + +export function foo1(p: Promise>): void { + let result: string = await p; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.ets new file mode 100644 index 0000000000000000000000000000000000000000..f375c1d984286b02141aec3b0a11250e79c9a141 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.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. + */ + +'use static'; + +export class Base { + prop1: number = 1; +} + +export class Derived extends Base { + prop2: string = "test"; +} + +export class StaticClass { + static staticMethod() {} +} + +export class PrivateClass { + private privProp: boolean = true; +} + +export class EmptyClass {} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.ets new file mode 100644 index 0000000000000000000000000000000000000000..25f7060f9b11d7d253557900e3dad5f7791cf369 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.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'; + +import { State} from '@ohos.arkui.stateManagement'; + +import hilog from '@ohos.hilog'; + +import * as All from './getDefinitionAtPosition8'; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.ets new file mode 100644 index 0000000000000000000000000000000000000000..daf1b623baccd6578f47d12e0680e77c1ed7262e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.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'; + +const obj = { + prop: 'value' +}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.ets new file mode 100644 index 0000000000000000000000000000000000000000..1eb92a69482f0307e815e02f36628fc4671f976c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.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'; + +export function a() { + return 'hello'; +} +a(); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe9866bdedcba29fcb5832a8ab4407a868323b4f --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.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. + */ + +'use static'; + +export class Parent { + name: string; + constructor(name: string) { + this.name = name; + } +} +export class Child extends Parent { + age: number; + constructor(name: string, age: number) { + super(name); + this.age = age; + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.ets new file mode 100644 index 0000000000000000000000000000000000000000..c774945efcf029fc669a1478501bd3c3bfa72e83 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.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 { PI } from "std/math"; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.ets new file mode 100644 index 0000000000000000000000000000000000000000..ab521e6009c2464ec58a75dfe6fd37cdcb66a247 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.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 function test(){} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition41.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition41.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc696c75a20728356a7b4488614c61dd40341171 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition41.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'; + +export class Person { + name: string; + age: number; + + constructor(name: string, age: number) { + this.name = name; + this.age = age; + } +} +let user: Person = new Person("Alice", 30); +export class Person1 { + name = "Jonn" +} +export function printPerson(p: Person1): void { +} +export type UserList = Array; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition42.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition42.ets new file mode 100644 index 0000000000000000000000000000000000000000..00b72aecd586103cb02fc8db8430ba14afdf4b65 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition42.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. + */ + +'use static'; + +const numbers = [1, 2, 3]; +const moreNumbers = [0, ...numbers, 4, 5]; +const part1 = [1, 2]; +const part2 = [3, 4]; +const combined = [...part1, ...part2, 5]; +const original = [10, 20, 30]; +const copy = [...original]; + +export class Test { + sum(...numbers: number[]): number { + return 0; + } + args = [1.5, 2.5, 3.0]; + result = this.sum(...this.args); + testNums = [1, 2, 3]; + moreTestNums = [0, ...this.testNums, 4, 5]; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/index.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..467a1f191b87bf66c319deafa6eee9b2a19c9288 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/index.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'; + +const PI = 1; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights8.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights8.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d43a149b8b0b52c12d8ee4d06e19b7eac4f5d63 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights8.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights9.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights9.ets new file mode 100644 index 0000000000000000000000000000000000000000..d1093ed3782931d29b8f0293d1df3ef6291c688b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights9.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 { Text } from '@ohos.arkui.component' + +Text() \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets b/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets new file mode 100644 index 0000000000000000000000000000000000000000..119751e901726748feeeb271b61fd5633db5b46b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let a = 1; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getOffsetByColAndLine/getOffsetByColAndLine1.ets b/ets2panda/bindings/test/testcases/getOffsetByColAndLine/getOffsetByColAndLine1.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d9c5f8afa5efa49d6dba9accca728964f091ba3 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOffsetByColAndLine/getOffsetByColAndLine1.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. + */ + +// comment of line + +import { memo, __memo_context_type, __memo_id_type } from '@ohos.arkui.stateManagement' +import { + Entry + Text, + TextAttributes, + Column, + Component, + Button, + ButtonAttribute, + ClickEvent, + UserView +} from '@ohos.arkui.component' +import { State, MutableSate, stateOf, observableProxy } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .onClick(() => { + console.info("hello, :") + console.log(result.toString()) + }) + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_export.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..74b30142ab52eebb5faa67bc75799f27908265ed --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_export.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 function one(): number { return 1; } +class Foo { + name: string = "john"; +} +export default Foo; diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_import.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..c46b16e01946179a8aa36cbd5465b900501f682a --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport1_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 {Foo, one} from './ExtractDefaultImport1_export'; +let foo: Foo = new Foo(); +let a: number = one(); diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_export.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..df813019e403eccab40767cb39c11a56f348d678 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_export.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 Foo { + name: string = "john"; +} +export default Foo; diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_import.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..fbff1565b4e0f1c376d36aa248e3b378456e35ba --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/ExtractDefaultImport2_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 {Foo} from './ExtractDefaultImport2_export'; +let foo: Foo = new Foo(); diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports1.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6e12d394d37ee8f3c5ce72f39a7c30fdcefd54c9 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports1.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. + */ +import { Entry, Text, Column, Component, Button, ClickEvent } from '@ohos.arkui.component' +import { State } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog'; +import {B, C, A} from "./getOrganizeImports2"; +import { X } from "./getOrganizeImports3"; +import Foo from "./getOrganizeImports4"; +const a = B; +const b = C; + +@Entry +@Component +struct My { + @State stateVar: string = '' + build() { + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports2.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ebf6069434d79f032e1d388ea37931dc009c4d43 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports2.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 const A = 1; +export const B = 2; +export const C = 3; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports3.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports3.ets new file mode 100644 index 0000000000000000000000000000000000000000..67d5744275105aeb514a633cd3540351eef48c56 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports3.ets @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 X = 1; diff --git a/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports4.ets b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports4.ets new file mode 100644 index 0000000000000000000000000000000000000000..df813019e403eccab40767cb39c11a56f348d678 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getOrganizeImports/getOrganizeImports4.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 Foo { + name: string = "john"; +} +export default Foo; diff --git a/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition4.ets b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition4.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c76d7275e73210dc679cc43e75c2195a1e1f27 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition4.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); diff --git a/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition5.ets b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition5.ets new file mode 100644 index 0000000000000000000000000000000000000000..c701f3ff4a94596455aad06f87fd5aed30b9c686 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition5.ets @@ -0,0 +1,22 @@ +'use static' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 '@ohos.arkui.component'; + +@Component +struct Index { + build() {} +} diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition6.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition6.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c76d7275e73210dc679cc43e75c2195a1e1f27 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition6.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); diff --git a/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo1.ets b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1986e1b330712c668afd67acde59f9da86f426be --- /dev/null +++ b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo1.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 + 123; +console.log(aaa + ""); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo2.ets b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ab20d0867bc0ad0761ce8eb8dfa34a85a4ad73ed --- /dev/null +++ b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo2.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 map1 = new Map(); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo3.ets b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo3.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c76d7275e73210dc679cc43e75c2195a1e1f27 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getRenameInfo/getRenameInfo3.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); diff --git a/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics3.ets b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics3.ets new file mode 100644 index 0000000000000000000000000000000000000000..705da5d5f5037e3b790f07e04d9b78129b7115ef --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics3.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push("123"); diff --git a/ets2panda/bindings/test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets b/ets2panda/bindings/test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets new file mode 100644 index 0000000000000000000000000000000000000000..d84f944c3985933399d2008023077b5bd5596834 --- /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 add(a: number, b: number): number { + return a + b; +} +add() 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/getSyntacticDiagnostics/getSyntacticDiagnostics3.ets b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics3.ets new file mode 100644 index 0000000000000000000000000000000000000000..116e75a6113e06b17c637343d390e283cd69ddc5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics3.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 {default as stack} frrom '@ohos.util.Stack'; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics4.ets b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics4.ets new file mode 100644 index 0000000000000000000000000000000000000000..e40cd7d11b0d277d686bd07d1645c6468b56eaba --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics4.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 { Entry, Component, Row, Column, Text } from '@ohos.arkui.component'; +import { Track } from '@ohos.arkui.stateManagement'; + +@Track +let A: number = 0; + +@Track +function B() { + +} + +@Track +interface IUser { + name: string; + age: number; +} + +@Entry +@Component +struct Index { + @Track + funA() { + + } + + build() { + Row() { + Text('Hello World') + } + } +} \ 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/provideInlayHints/provideInlayHints2.ets b/ets2panda/bindings/test/testcases/provideInlayHints/provideInlayHints2.ets new file mode 100644 index 0000000000000000000000000000000000000000..24211305cddf28d55724603478ad565a05d9e8cd --- /dev/null +++ b/ets2panda/bindings/test/testcases/provideInlayHints/provideInlayHints2.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 Stack from '@ohos.util.Stack'; +let stk = new Stack(); +stk.push(1); +stk.push(2); + +let map = new Map(); +map.set("a", 1); +let a = map.get("a"); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset2.ets b/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset2.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c76d7275e73210dc679cc43e75c2195a1e1f27 --- /dev/null +++ b/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset2.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 {default as stack} from '@ohos.util.Stack'; +let stk = new stack(); +stk.push(1); +stk.push(2); 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 80e75bf31858d7e801a2a4c16327afc8f310ec1a..3ddb14664f61941fca09872e70ce710dddee9191 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -15,15 +15,25 @@ #include "ETSAnalyzer.h" +#include "checker/ETSchecker.h" +#include "compiler/lowering/util.h" #include "generated/diagnostic.h" #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsTupleType.h" +#include "checker/types/gradualType.h" #include "evaluate/scopedDebugInfoPlugin.h" #include "types/signature.h" #include "compiler/lowering/ets/setJumpTarget.h" #include "checker/types/ets/etsAsyncFuncReturnType.h" +#include "types/type.h" +#include "checker/types/typeError.h" + +#include + namespace ark::es2panda::checker { +static Type *GetAppropriatePreferredType(Type *originalType, std::function const &predicate); + ETSChecker *ETSAnalyzer::GetETSChecker() const { return static_cast(GetChecker()); @@ -53,8 +63,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); } @@ -84,15 +105,27 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const ETSChecker *checker = GetETSChecker(); if (st->Id()->Variable() == nullptr) { - st->Id()->Check(checker); + // Now invalid or dummy nodes obtaining after parsing don't have associated variables at all, that leads to + // incorrect AST and multiple reported errors in AST verifier. Need to create and bind [special]? variables for + // them with default TypeError set[?]. Why can't we directly check the 'Id'? During the process of + // resolveIdentifier, we might obtain the wrong variable, which breaks the consistency between the variable and + // its tsType. see wrong_variable_binding.ets for more details. + auto ident = st->Id(); + auto [decl, var] = checker->VarBinder()->NewVarDecl( + ident->Start(), compiler::GenName(checker->ProgramAllocator()).View()); + var->SetScope(checker->VarBinder()->GetScope()); + ident->SetVariable(var); + decl->BindNode(ident); + ident->SetTsType(var->SetTsType(checker->GlobalTypeError())); } ES2PANDA_ASSERT(st->Id()->Variable() != nullptr); - checker->CheckAnnotations(st->Annotations()); + checker->CheckAnnotations(st); if (st->TypeAnnotation() != nullptr) { st->TypeAnnotation()->Check(checker); } + checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass(), checker->Context().ContainingSignature()); @@ -104,7 +137,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 @@ -125,6 +164,11 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const } else { st->SetTsType(checker->BuildMethodType(func)); } + + if (!func->HasBody() || (func->IsExternal() && !func->IsExternalOverload())) { + return st->TsType(); + } + checker::ScopeContext scopeCtx(checker, func->Scope()); checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass()); @@ -137,15 +181,11 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node) { auto *scriptFunc = node->Function(); - if (node->IsNative() && !node->IsConstructor() && !scriptFunc->IsSetter()) { - if (scriptFunc->ReturnTypeAnnotation() == nullptr) { - checker->LogError(diagnostic::NATIVE_WITHOUT_RETURN, {}, scriptFunc->Start()); - node->SetTsType(checker->GlobalTypeError()); - } - } + ES2PANDA_ASSERT(scriptFunc != nullptr); if (util::Helpers::IsAsyncMethod(node)) { - if (scriptFunc->ReturnTypeAnnotation() != nullptr) { + if (scriptFunc->ReturnTypeAnnotation() != nullptr && !scriptFunc->ReturnTypeAnnotation()->IsOpaqueTypeNode() && + scriptFunc->Signature() != nullptr) { auto *asyncFuncReturnType = scriptFunc->Signature()->ReturnType(); if (!asyncFuncReturnType->IsETSObjectType() || @@ -174,6 +214,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(); @@ -185,11 +231,7 @@ checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const return node->TsType(); }; - if (scriptFunc == nullptr) { - checker->LogError(diagnostic::FUNC_EXPR_INVALID, {}, node->Start()); - return returnErrorType(); - } - checker->CheckAnnotations(scriptFunc->Annotations()); + checker->CheckAnnotations(scriptFunc); checker->CheckFunctionSignatureAnnotations(scriptFunc->Params(), scriptFunc->TypeParams(), scriptFunc->ReturnTypeAnnotation()); @@ -219,6 +261,14 @@ 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); + } + + if (node->TsType() != nullptr && node->TsType()->IsTypeError()) { + return node->TsType(); + } + this->CheckMethodModifiers(node); HandleNativeAndAsyncMethods(checker, node); DoBodyTypeChecking(checker, node, scriptFunc); @@ -242,12 +292,6 @@ void ETSAnalyzer::CheckMethodModifiers(ir::MethodDefinition *node) const return; } - if (node->Function() == nullptr) { - checker->LogError(diagnostic::FUNC_EXPR_INVALID, {}, node->Start()); - node->SetTsType(checker->GlobalTypeError()); - return; - } - if ((node->IsAbstract() || (!node->Function()->HasBody() && !node->IsNative() && !node->IsDeclare())) && !(checker->HasStatus(checker::CheckerStatus::IN_ABSTRACT) || checker->HasStatus(checker::CheckerStatus::IN_INTERFACE))) { @@ -270,6 +314,92 @@ void ETSAnalyzer::CheckMethodModifiers(ir::MethodDefinition *node) const } } +static void CheckDuplicationInOverloadDeclaration(ETSChecker *const checker, ir::OverloadDeclaration *const node) +{ + auto overloadedNameSet = ArenaSet(checker->ProgramAllocator()->Adapter()); + for (ir::Expression *const overloadedName : node->OverloadedList()) { + bool isQualifiedName = true; + std::function getFullOverloadedName = + [&isQualifiedName, &getFullOverloadedName](ir::Expression *const expr) -> std::string { + if (!isQualifiedName) { + return ""; + } + if (expr->IsIdentifier()) { + return expr->AsIdentifier()->Name().Mutf8(); + } + if (expr->IsMemberExpression()) { + return getFullOverloadedName(expr->AsMemberExpression()->Object()) + "." + + getFullOverloadedName(expr->AsMemberExpression()->Property()); + } + isQualifiedName = false; + return ""; + }; + std::string fullOverloadedName = getFullOverloadedName(overloadedName); + if (!isQualifiedName) { + continue; + } + if (overloadedNameSet.find(fullOverloadedName) != overloadedNameSet.end()) { + checker->LogError(diagnostic::DUPLICATE_OVERLOADED_NAME, overloadedName->Start()); + continue; + } + overloadedNameSet.insert(fullOverloadedName); + } +} + +static void CheckOverloadSameNameMethod(ETSChecker *const checker, ir::OverloadDeclaration *const overloadDecl) +{ + Type *objectType = overloadDecl->Parent()->IsClassDefinition() + ? overloadDecl->Parent()->AsClassDefinition()->Check(checker) + : overloadDecl->Parent()->Parent()->AsTSInterfaceDeclaration()->Check(checker); + ES2PANDA_ASSERT(objectType->IsETSObjectType()); + + PropertySearchFlags searchFlags = PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION | + (overloadDecl->IsStatic() ? PropertySearchFlags::SEARCH_STATIC_METHOD + : PropertySearchFlags::SEARCH_INSTANCE_METHOD); + auto *sameNameMethod = objectType->AsETSObjectType()->GetProperty(overloadDecl->Id()->Name(), searchFlags); + if (sameNameMethod == nullptr) { + return; + } + + auto serachName = overloadDecl->Id()->Name().Mutf8(); + auto hasSameNameMethod = + std::find_if(overloadDecl->OverloadedList().begin(), overloadDecl->OverloadedList().end(), + [serachName](ir::Expression *overloadId) { + return overloadId->IsIdentifier() && overloadId->AsIdentifier()->Name().Is(serachName); + }); + if (hasSameNameMethod == overloadDecl->OverloadedList().end()) { + checker->LogError(diagnostic::OVERLOAD_SAME_NAME_METHOD, {serachName}, overloadDecl->Start()); + } +} + +checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const +{ + ETSChecker *checker = GetETSChecker(); + ES2PANDA_ASSERT(node != nullptr); + ES2PANDA_ASSERT(node->Key()); + + CheckDuplicationInOverloadDeclaration(checker, node); + CheckOverloadSameNameMethod(checker, node); + + if (node->IsConstructorOverloadDeclaration()) { + ES2PANDA_ASSERT(node->Parent()->IsClassDefinition()); + checker->CheckConstructorOverloadDeclaration(checker, node); + } else if (node->IsFunctionOverloadDeclaration()) { + ES2PANDA_ASSERT( + node->Parent()->IsClassDefinition() && + (compiler::HasGlobalClassParent(node) || node->Parent()->AsClassDefinition()->IsNamespaceTransformed())); + checker->CheckFunctionOverloadDeclaration(checker, node); + } else if (node->IsClassMethodOverloadDeclaration()) { + ES2PANDA_ASSERT(node->Parent()->IsClassDefinition()); + checker->CheckClassMethodOverloadDeclaration(checker, node); + } else if (node->IsInterfaceMethodOverloadDeclaration()) { + ES2PANDA_ASSERT(node->Parent()->Parent()->IsTSInterfaceDeclaration()); + checker->CheckInterfaceMethodOverloadDeclaration(checker, node); + } + + return checker->CreateSyntheticTypeFromOverload(node->Id()->Variable()); +} + checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const { ETSChecker *checker = GetETSChecker(); @@ -283,13 +413,17 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const } ETSChecker *checker = GetETSChecker(); - Type *exprType = expr->AsSpreadElement()->Argument()->Check(checker); + if (expr->PreferredType() != nullptr) { + expr->Argument()->SetPreferredType(expr->PreferredType()); + } + auto type = expr->Argument()->Check(checker); + Type *exprType = type->MaybeBaseTypeOfGradualType(); if (exprType->IsETSResizableArrayType()) { return expr->SetTsType(exprType->AsETSObjectType()->TypeArguments().front()); } - if (!exprType->IsETSArrayType() && !exprType->IsETSTupleType()) { + if (!exprType->IsETSArrayType() && !exprType->IsETSTupleType() && !exprType->IsETSReadonlyArrayType()) { if (!exprType->IsTypeError()) { // Don't duplicate error messages for the same error checker->LogError(diagnostic::SPREAD_OF_INVALID_TYPE, {exprType}, expr->Start()); @@ -297,8 +431,7 @@ checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const return checker->InvalidateType(expr); } - checker::Type *const elementType = - exprType->IsETSArrayType() ? exprType->AsETSArrayType()->ElementType() : exprType; + checker::Type *const elementType = exprType->IsETSTupleType() ? type : checker->GetElementTypeOfArray(exprType); return expr->SetTsType(elementType); } @@ -325,7 +458,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), @@ -335,17 +468,29 @@ checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const return expr->TsType(); } +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSIntrinsicNode *node) const +{ + ES2PANDA_UNREACHABLE(); +} + checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const { if (node->TsType() != nullptr) { return node->TsType(); } ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(node->Annotations()); + checker->CheckAnnotations(node); checker->CheckFunctionSignatureAnnotations(node->Params(), node->TypeParams(), node->ReturnType()); auto *signatureInfo = checker->ComposeSignatureInfo(node->TypeParams(), node->Params()); - auto *returnType = checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); + if (signatureInfo == nullptr) { + ES2PANDA_ASSERT(GetChecker()->IsAnyError()); + return node->SetTsType(checker->GlobalTypeError()); + } + auto *returnType = node->IsExtensionFunction() && node->ReturnType()->IsTSThisType() + ? signatureInfo->params.front()->TsType() + : checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); + auto *const signature = checker->CreateSignature(signatureInfo, returnType, node->Flags(), node->IsExtensionFunction()); if (signature == nullptr) { // #23134 @@ -358,33 +503,14 @@ 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) { ES2PANDA_ASSERT(checker != nullptr); ES2PANDA_ASSERT(newArrayInstanceExpr != nullptr); - checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker); + checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker)->MaybeBaseTypeOfGradualType(); + ES2PANDA_ASSERT(elementType != nullptr); if (elementType->IsETSPrimitiveType()) { return true; } @@ -417,26 +543,46 @@ 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 { + if (expr->TsType() != nullptr) { + return expr->TsType(); + } + ETSChecker *checker = GetETSChecker(); auto *elementType = expr->TypeReference()->GetType(checker); checker->ValidateArrayIndex(expr->Dimension(), true); CheckArrayElementType(checker, expr); - expr->SetTsType(checker->CreateETSArrayType(elementType)); - checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + auto *preferredType = GetAppropriatePreferredType( + expr->PreferredType(), [](Type *tp) -> bool { return tp->IsETSArrayType() || tp->IsETSResizableArrayType(); }); + + if (NeedCreateETSResizableArrayType(checker, expr->PreferredType()) || preferredType == nullptr || + 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(); } static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewClassInstanceExpression *expr) { - checker::Type *calleeType = expr->GetTypeRef()->Check(checker); - if (calleeType->IsTypeError()) { - return checker->InvalidateType(expr->GetTypeRef()); - } + checker::Type *res = expr->GetTypeRef()->Check(checker); + auto calleeType = res->MaybeBaseTypeOfGradualType(); + FORWARD_TYPE_ERROR(checker, calleeType, expr->GetTypeRef()); + if (calleeType->IsETSUnionType()) { return checker->TypeError(expr->GetTypeRef(), diagnostic::UNION_NONCONSTRUCTIBLE, expr->Start()); } @@ -464,7 +610,7 @@ static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewCl return checker->GlobalTypeError(); } - return calleeType; + return res; } checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const @@ -472,55 +618,57 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const if (expr->TsType() != nullptr) { return expr->TsType(); } + ETSChecker *checker = GetETSChecker(); auto *calleeType = CheckInstantiatedNewType(checker, expr); - if (calleeType->IsTypeError()) { - return checker->InvalidateType(expr); - } - auto *calleeObj = calleeType->AsETSObjectType(); - expr->SetTsType(calleeObj); + FORWARD_TYPE_ERROR(checker, calleeType, expr); - if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { - auto lang = calleeType->AsETSDynamicType()->Language(); - expr->SetSignature(checker->ResolveDynamicCallExpression(expr->GetTypeRef(), expr->GetArguments(), lang, true)); - } else { - auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start()); + auto *calleeObj = calleeType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + expr->SetTsType(calleeType); - if (signature == nullptr) { - return checker->InvalidateType(expr); - } + auto *signature = checker->ResolveConstructExpression(calleeObj, expr->GetArguments(), expr->Start()); - checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); + if (signature == nullptr) { + return checker->InvalidateType(expr); + } - checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); + checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); - if (calleeType->IsETSDynamicType()) { - ES2PANDA_ASSERT(signature->Function()->IsDynamic()); - auto lang = calleeType->AsETSDynamicType()->Language(); - expr->SetSignature( - checker->ResolveDynamicCallExpression(expr->GetTypeRef(), signature->Params(), lang, true)); - } else { - expr->SetSignature(signature); - } - } + checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); + + expr->SetSignature(signature); return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *expr) const { + if (expr->TsType() != nullptr) { + return expr->TsType(); + } ETSChecker *checker = GetETSChecker(); 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); + } + auto *preferredType = GetAppropriatePreferredType( + expr->PreferredType(), [](Type *tp) -> bool { return tp->IsETSArrayType() || tp->IsETSResizableArrayType(); }); + + if (NeedCreateETSResizableArrayType(checker, preferredType) || 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(); } @@ -566,7 +714,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSStructDeclaration *node) const checker::Type *ETSAnalyzer::Check(ir::ETSTypeReference *node) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(node->Annotations()); + checker->CheckAnnotations(node); return node->GetType(checker); } @@ -576,18 +724,27 @@ 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(); + return node->SetTsType(checker->GetNonNullishType(node->GetTypeNode()->Check(checker))); +} + checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(node->Annotations()); - return checker->GlobalETSNullType(); + checker->CheckAnnotations(node); + 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(); + checker->CheckAnnotations(node); + return node->SetTsType(checker->GlobalETSUndefinedType()); } checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const @@ -599,7 +756,7 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const checker::Type *ETSAnalyzer::Check(ir::ETSStringLiteralType *node) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(node->Annotations()); + checker->CheckAnnotations(node); return node->GetType(checker); } @@ -611,11 +768,6 @@ checker::Type *ETSAnalyzer::Check(ir::ETSKeyofType *node) const // compile methods for EXPRESSIONS in alphabetical order -checker::Type *ETSAnalyzer::GetPreferredType(ir::ArrayExpression *expr) const -{ - return expr->preferredType_; -} - static void AddSpreadElementTypes(ETSChecker *checker, ir::SpreadElement *const element, ArenaVector> &elementTypes) { @@ -626,7 +778,7 @@ static void AddSpreadElementTypes(ETSChecker *checker, ir::SpreadElement *const return; } - Type *const spreadArgumentType = element->Argument()->TsType(); + Type *const spreadArgumentType = element->Argument()->TsType()->MaybeBaseTypeOfGradualType(); if (spreadArgumentType->IsETSTupleType()) { for (Type *type : spreadArgumentType->AsETSTupleType()->GetTupleTypesList()) { @@ -653,39 +805,47 @@ static bool ValidArrayExprSizeForTupleSize(ETSChecker *checker, Type *possibleTu static ArenaVector> GetElementTypes(ETSChecker *checker, ir::ArrayExpression *expr) { - ArenaVector> elementTypes(checker->Allocator()->Adapter()); + ArenaVector> elementTypes(checker->ProgramAllocator()->Adapter()); + + auto *const exprPreferredType = expr->PreferredType(); + auto *const exprTupleType = exprPreferredType->IsETSTupleType() ? exprPreferredType->AsETSTupleType() : nullptr; + checker::Type *elemPreferredType = + exprPreferredType->IsETSTupleType() ? nullptr : checker->GetElementTypeOfArray(exprPreferredType); - for (std::size_t idx = 0; idx < expr->Elements().size(); ++idx) { + for (std::size_t idx = 0U; idx < expr->Elements().size(); ++idx) { ir::Expression *const element = expr->Elements()[idx]; if (element->IsSpreadElement()) { + element->SetPreferredType(exprPreferredType); AddSpreadElementTypes(checker, element->AsSpreadElement(), elementTypes); continue; } - 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->IsArrayExpression() || element->IsObjectExpression()) { - auto *const targetPreferredType = exprPreferredType->IsETSTupleType() - ? exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx) - : exprPreferredType->AsETSArrayType()->ElementType(); - ETSChecker::SetPreferredTypeIfPossible(element, targetPreferredType); + if (exprTupleType != nullptr && exprPreferredType->IsETSTupleType()) { + if (idx >= exprTupleType->GetTupleSize() || + !ValidArrayExprSizeForTupleSize(checker, exprTupleType->GetTypeAtIndex(idx), element)) { + elementTypes.emplace_back(element->SetTsType(checker->GlobalTypeError()), element); + continue; + } + elemPreferredType = exprTupleType->GetTypeAtIndex(idx); } + element->SetPreferredType(elemPreferredType); elementTypes.emplace_back(element->Check(checker), element); } return elementTypes; } +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) { @@ -723,7 +883,7 @@ static bool CheckElement(ETSChecker *checker, Type *const preferredType, targetType = compareType; } else { - targetType = preferredType->AsETSArrayType()->ElementType(); + targetType = GetArrayElementType(checker, preferredType); } auto ctx = AssignmentContext(checker->Relation(), currentElement, elementType, targetType, currentElement->Start(), @@ -737,9 +897,9 @@ static bool CheckElement(ETSChecker *checker, Type *const preferredType, return true; } -static ETSArrayType *InferPreferredTypeFromElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) +static Type *InferPreferredTypeFromElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) { - ArenaVector arrayExpressionElementTypes(checker->Allocator()->Adapter()); + ArenaVector arrayExpressionElementTypes(checker->ProgramAllocator()->Adapter()); for (auto *const element : arrayExpr->Elements()) { auto *elementType = *element->Check(checker); if (element->IsSpreadElement() && elementType->IsETSTupleType()) { @@ -762,13 +922,13 @@ static ETSArrayType *InferPreferredTypeFromElements(ETSChecker *checker, ir::Arr // 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->CreateETSArrayType(checker->GetNonConstantType( + 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->CreateETSArrayType( + return checker->CreateETSResizableArrayType( checker->GetNonConstantType(checker->CreateETSUnionType(std::move(arrayExpressionElementTypes)))); } @@ -780,27 +940,112 @@ static bool CheckArrayExpressionElements(ETSChecker *checker, ir::ArrayExpressio [](auto &pair) { return pair.first->IsTypeError(); }); for (std::size_t idx = 0; idx < arrayExprElementTypes.size(); ++idx) { - allElementsAssignable &= CheckElement(checker, arrayExpr->GetPreferredType(), arrayExprElementTypes, idx); + allElementsAssignable &= CheckElement(checker, arrayExpr->PreferredType(), arrayExprElementTypes, idx); } return allElementsAssignable; } -void ETSAnalyzer::GetUnionPreferredType(ir::ArrayExpression *expr) const +static Type *GetAppropriatePreferredType(Type *originalType, std::function const &predicate) { - ES2PANDA_ASSERT(expr->preferredType_->IsETSUnionType()); - checker::Type *preferredType = nullptr; - for (auto &type : expr->preferredType_->AsETSUnionType()->ConstituentTypes()) { - if (type->IsETSArrayType() || type->IsETSTupleType()) { + if (originalType == nullptr) { + return nullptr; + } + + while (originalType->IsETSTypeAliasType()) { + if (predicate(originalType)) { + return originalType; + } + originalType = originalType->AsETSTypeAliasType()->GetTargetType(); + } + + if (predicate(originalType)) { + return originalType; + } + + if (!originalType->IsETSUnionType()) { + return nullptr; + } + + Type *preferredType = nullptr; + for (auto &type : originalType->AsETSUnionType()->ConstituentTypes()) { + if (predicate(type)) { if (preferredType != nullptr) { - preferredType = nullptr; - break; + return nullptr; // ambiguity } preferredType = type; } } + return preferredType; +} + +static inline checker::Type *CheckElemUnder(checker::ETSChecker *checker, ir::Expression *node, + checker::Type *preferElem) +{ + auto *oldPref = node->PreferredType(); + node->SetPreferredType(preferElem); + checker::Type *t = node->Check(checker); + node->SetPreferredType(oldPref); + return t; +} + +static Type *SelectArrayPreferredTypeForLiteral(ETSChecker *checker, ir::ArrayExpression *arrayLiteral, + Type *contextualType) +{ + ES2PANDA_ASSERT(checker != nullptr); + ES2PANDA_ASSERT(arrayLiteral != nullptr); + ES2PANDA_ASSERT(contextualType != nullptr && contextualType->IsETSUnionType()); + + auto &alts = contextualType->AsETSUnionType()->ConstituentTypes(); + + for (auto *el : arrayLiteral->Elements()) { + ES2PANDA_ASSERT(el != nullptr); + if (el->IsSpreadElement() || el->IsBrokenExpression()) { + return nullptr; + } + } + + Type *selected = nullptr; + Type *selectedElem = nullptr; + + for (Type *candidate : alts) { + if (!candidate->IsETSArrayType() && !candidate->IsETSResizableArrayType()) { + continue; + } + + Type *candElem = checker->GetElementTypeOfArray(candidate); + ES2PANDA_ASSERT(candElem != nullptr); + + bool ok = true; + for (auto *el : arrayLiteral->Elements()) { + Type *elTy = CheckElemUnder(checker, el, candElem); + if (elTy == nullptr || !checker->Relation()->IsAssignableTo(elTy, candElem)) { + ok = false; + break; + } + } + if (!ok) { + continue; + } + + if (selected == nullptr) { + selected = candidate; + selectedElem = candElem; + continue; + } + + auto *relation = checker->Relation(); + const bool candMoreSpecific = relation->IsSupertypeOf(selectedElem, candElem); + const bool selMoreSpecific = relation->IsSupertypeOf(candElem, selectedElem); + if (candMoreSpecific && !selMoreSpecific) { + selected = candidate; + selectedElem = candElem; + } else if (!candMoreSpecific && !selMoreSpecific && !relation->IsIdenticalTo(selected, candidate)) { + return nullptr; + } + } - expr->preferredType_ = preferredType; + return selected; } checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const @@ -810,43 +1055,48 @@ checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const return expr->TsType(); } - if (expr->GetPreferredType() != nullptr) { - if (expr->GetPreferredType()->IsETSTypeAliasType()) { - expr->SetPreferredType(expr->GetPreferredType()->AsETSTypeAliasType()->GetTargetType()); - } + auto *preferredType = GetAppropriatePreferredType(expr->PreferredType(), &Type::IsAnyETSArrayOrTupleType); - if (expr->GetPreferredType()->IsETSUnionType()) { - GetUnionPreferredType(expr); + if (expr->PreferredType() != nullptr && expr->PreferredType()->IsETSUnionType()) { + if (auto *picked = SelectArrayPreferredTypeForLiteral(checker, expr, expr->PreferredType())) { + preferredType = picked; + expr->SetPreferredType(preferredType); } } - if (!IsArrayExpressionValidInitializerForType(checker, expr->GetPreferredType())) { - checker->LogError(diagnostic::UNEXPECTED_ARRAY, {expr->GetPreferredType()}, expr->Start()); + if (preferredType != nullptr && preferredType->IsETSReadonlyArrayType()) { + const auto elementType = preferredType->AsETSObjectType()->TypeArguments().front(); + preferredType = checker->CreateETSResizableArrayType(elementType); + } + + if (!IsArrayExpressionValidInitializerForType(checker, preferredType)) { + checker->LogError(diagnostic::UNEXPECTED_ARRAY, {expr->PreferredType()}, expr->Start()); return checker->InvalidateType(expr); } if (!expr->Elements().empty()) { - if (expr->GetPreferredType() == nullptr || expr->GetPreferredType() == checker->GlobalETSObjectType()) { - expr->SetPreferredType(InferPreferredTypeFromElements(checker, expr)); + if (preferredType == nullptr || preferredType == checker->GlobalETSObjectType()) { + preferredType = InferPreferredTypeFromElements(checker, expr); } - if (!CheckArrayExpressionElements(checker, expr)) { - return checker->InvalidateType(expr); - } + expr->SetPreferredType(preferredType); } - if (expr->GetPreferredType() == nullptr) { + if (preferredType == nullptr) { return checker->TypeError(expr, diagnostic::UNRESOLVABLE_ARRAY, expr->Start()); } - expr->SetTsType(expr->GetPreferredType()); + if (!ValidArrayExprSizeForTupleSize(checker, preferredType, expr) || + (!expr->Elements().empty() && !CheckArrayExpressionElements(checker, expr))) { + return checker->InvalidateType(expr); + } - if (!expr->TsType()->IsETSTupleType()) { - ES2PANDA_ASSERT(expr->TsType()->IsETSArrayType()); - const auto *const arrayType = expr->TsType()->AsETSArrayType(); + expr->SetTsType(preferredType); + if (!preferredType->IsETSResizableArrayType() && !preferredType->IsETSTupleType()) { + ES2PANDA_ASSERT(preferredType->IsETSArrayType()); + const auto *const arrayType = preferredType->AsETSArrayType(); checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); } - return expr->TsType(); } @@ -876,7 +1126,7 @@ void TryInferPreferredType(ir::ArrowFunctionExpression *expr, checker::Type *pre checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(expr->Annotations()); + checker->CheckAnnotations(expr); if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -931,19 +1181,23 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const checker->Context().SetContainingSignature(signature); expr->Function()->Body()->Check(checker); + if (expr->Function()->ReturnTypeAnnotation() == nullptr) { + if (expr->Function()->IsAsyncFunc()) { + auto *retType = signature->ReturnType(); + if (!retType->IsETSObjectType() || + retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { + auto returnType = checker->CreateETSAsyncFuncReturnTypeFromBaseType(signature->ReturnType()); + ES2PANDA_ASSERT(returnType != nullptr); + expr->Function()->Signature()->SetReturnType(returnType->PromiseType()); + for (auto &returnStatement : expr->Function()->ReturnStatements()) { + returnStatement->SetReturnType(checker, returnType); + } + } + } + } auto *funcType = checker->CreateETSArrowType(signature); checker->Context().SetContainingSignature(nullptr); - - if (expr->Function()->IsAsyncFunc()) { - auto *retType = signature->ReturnType(); - if (!retType->IsETSObjectType() || - retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { - checker->LogError(diagnostic::ASYNC_DOESNT_PROMISE, {}, expr->Function()->Start()); - expr->SetTsType(checker->GlobalTypeError()); - return expr->TsType(); - } - } expr->SetTsType(funcType); return expr->TsType(); } @@ -981,7 +1235,10 @@ checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker if (expr->Left()->IsIdentifier() && expr->Target() != nullptr) { // Now try to define the actual type of Identifier so that smart cast can be used in further checker // processing - smartType = checker->ResolveSmartType(rightType, leftType); + auto const value = expr->Right()->IsNumberLiteral() + ? std::make_optional(expr->Right()->AsNumberLiteral()->Number().GetDouble()) + : std::nullopt; + smartType = checker->ResolveSmartType(rightType, leftType, value); auto const *const variable = expr->Target(); // Add/Remove/Modify smart cast for identifier @@ -1002,6 +1259,89 @@ checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker return smartType; } +static ir::MethodDefinition const *ResolveMethodDefinition(const ir::Expression *const expression, ETSChecker *checker) +{ + if (!expression->IsMemberExpression()) { + return nullptr; + } + + auto const *memberExpression = expression->AsMemberExpression(); + if (memberExpression->Kind() != ir::MemberExpressionKind::PROPERTY_ACCESS || + memberExpression->Property() == nullptr || !memberExpression->Property()->IsIdentifier()) { + return nullptr; + } + + auto const *variable = memberExpression->Property()->Variable(); + if (variable == nullptr) { + if (auto const *objectType = memberExpression->Object()->TsType(); + objectType != nullptr && objectType->IsETSObjectType()) { + // Process possible case of the same name method with receiver defined + auto resolved = checker->ResolveMemberReference(memberExpression, objectType->AsETSObjectType()); + if (resolved.size() == 2U && resolved[1]->Kind() == checker::ResolvedKind::PROPERTY) { + variable = resolved[1U]->Variable()->AsLocalVariable(); + } + } + } + + if (variable != nullptr) { + if (variable->Declaration() != nullptr && variable->Declaration()->Node()->IsMethodDefinition()) { + return variable->Declaration()->Node()->AsMethodDefinition(); + } + } + + return nullptr; +} + +static bool IsInvalidMethodAssignment(const ir::AssignmentExpression *const expr, ETSChecker *checker) +{ + auto left = expr->Left(); + if (auto const *methodDefinition = ResolveMethodDefinition(left, checker); methodDefinition != nullptr) { + if (!methodDefinition->IsSetter() && + std::none_of(methodDefinition->Overloads().cbegin(), methodDefinition->Overloads().cend(), + [](const auto *overload) { return overload->IsSetter(); })) { + checker->LogError(diagnostic::METHOD_ASSIGNMENT, left->Start()); + return true; + } + } + return false; +} + +// In assignment expression or object literal, we need the type of the setter instead of the type of the getter +static checker::Type *GetSetterType(varbinder::Variable *const var, ETSChecker *checker) +{ + if (var == nullptr || !checker->IsVariableGetterSetter(var)) { + return nullptr; + } + + if (var->TsType()->IsETSFunctionType()) { + auto *funcType = var->TsType()->AsETSFunctionType(); + if (funcType->HasTypeFlag(checker::TypeFlag::SETTER)) { + auto *setter = funcType->FindSetter(); + ES2PANDA_ASSERT(setter != nullptr && setter->Params().size() == 1); + return setter->Params()[0]->TsType(); + } + } + + return nullptr; +} + +// Helper to set the target of assignment expression +bool ETSAnalyzer::SetAssignmentExpressionTarget(ir::AssignmentExpression *const expr, ETSChecker *checker) 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 { + return false; + } + return true; +} + checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const { if (expr->TsType() != nullptr) { @@ -1014,25 +1354,28 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const checker->WarnForEndlessLoopInGetterSetter(expr->Left()->AsMemberExpression()); } - const auto leftType = expr->Left()->Check(checker); + checker::Type *leftType = expr->Left()->Check(checker); - if (IsInvalidArrayMemberAssignment(expr, checker)) { + if (IsInvalidArrayMemberAssignment(expr, checker) || IsInvalidMethodAssignment(expr, checker)) { expr->SetTsType(checker->GlobalTypeError()); return expr->TsType(); } - if (expr->Left()->IsIdentifier()) { - expr->target_ = expr->Left()->AsIdentifier()->Variable(); - } else if (expr->Left()->IsMemberExpression()) { - expr->target_ = expr->Left()->AsMemberExpression()->PropVar(); - } else { + if (!SetAssignmentExpressionTarget(expr, checker)) { checker->LogError(diagnostic::ASSIGNMENT_INVALID_LHS, {}, expr->Left()->Start()); expr->SetTsType(checker->GlobalTypeError()); return expr->TsType(); } if (expr->target_ != nullptr && !expr->IsIgnoreConstAssign()) { - checker->ValidateUnaryOperatorOperand(expr->target_); + checker->ValidateUnaryOperatorOperand(expr->target_, expr); + } + + checker->InferLambdaInAssignmentExpression(expr); + + if (auto setterType = GetSetterType(expr->target_, checker); setterType != nullptr) { + leftType = setterType; + expr->Left()->SetTsType(leftType); } auto [rightType, relationNode] = CheckAssignmentExprOperatorType(expr, leftType); @@ -1043,7 +1386,10 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const CastPossibleTupleOnRHS(checker, expr); checker::Type *smartType = rightType; - if (!leftType->IsTypeError()) { + auto isLazyImportObject = + leftType->MaybeBaseTypeOfGradualType()->IsETSObjectType() && + leftType->MaybeBaseTypeOfGradualType()->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::LAZY_IMPORT_OBJECT); + if (!leftType->IsTypeError() && !isLazyImportObject) { if (const auto ctx = checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(), {{diagnostic::INVALID_ASSIGNMNENT, {rightType, leftType}}}); @@ -1061,22 +1407,22 @@ static checker::Type *HandleSubstitution(ETSChecker *checker, ir::AssignmentExpr 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()) { + } else if (expr->Right()->IsArrowFunctionExpression() && + (leftType->IsETSArrowType() || leftType->IsETSUnionType())) { + if (auto *preferredType = GetAppropriatePreferredType(leftType, [](Type *tp) { return tp->IsETSArrowType(); }); + preferredType != nullptr) { + checker->TryInferTypeForLambdaTypeAlias(expr->Right()->AsArrowFunctionExpression(), + preferredType->AsETSFunctionType()); + } + } else if (expr->Right()->IsObjectExpression()) { + if (leftType->IsETSObjectType() && leftType->IsGradualType() && + (leftType->HasTypeFlag(TypeFlag::READONLY) || + leftType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::REQUIRED))) { + checker->LogError(diagnostic::DYMANIC_INIT_WITH_OBJEXPR, {leftType}, expr->Right()->Start()); + } expr->Right()->AsObjectExpression()->SetPreferredType(leftType); - } - - if (expr->Right()->IsArrowFunctionExpression() && (leftType->IsETSArrowType() || leftType->IsETSUnionType())) { - expr->Right()->AsArrowFunctionExpression()->SetPreferredType(leftType); + } else { + expr->Right()->SetPreferredType(leftType); } return expr->Right()->Check(checker); @@ -1103,10 +1449,7 @@ std::tuple ETSAnalyzer::CheckAssignmentExprOperatorTyp case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { std::tie(std::ignore, expr->operationType_) = checker->CheckBinaryOperator( expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start(), true); - - auto unboxedLeft = checker->MaybeUnboxInRelation(leftType); - sourceType = unboxedLeft == nullptr ? leftType : unboxedLeft; - + sourceType = leftType; relationNode = expr; break; } @@ -1123,12 +1466,6 @@ 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(); @@ -1136,59 +1473,9 @@ checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const return expr->TsType(); } - checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker)); - ArenaVector awaitedTypes(checker->Allocator()->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)); - } - - expr->SetTsType(argType->IsETSUnionType() ? checker->CreateETSUnionType(std::move(awaitedTypes)) : awaitedTypes[0]); - return expr->TsType(); -} - -checker::Type *ETSAnalyzer::UnwrapPromiseType(checker::Type *type) const -{ - ETSChecker *checker = GetETSChecker(); - checker::Type *promiseType = checker->GlobalBuiltinPromiseType(); - while (type->IsETSObjectType() && type->AsETSObjectType()->GetOriginalBaseType() == promiseType) { - type = type->AsETSObjectType()->TypeArguments().at(0); - } - if (!type->IsETSUnionType()) { - return type; - } - const auto &ctypes = type->AsETSUnionType()->ConstituentTypes(); - auto it = std::find_if(ctypes.begin(), ctypes.end(), [promiseType](checker::Type *t) { - return t == promiseType || (t->IsETSObjectType() && t->AsETSObjectType()->GetBaseType() == promiseType); - }); - if (it == ctypes.end()) { - return type; - } - ArenaVector newCTypes(ctypes); - do { - size_t index = it - ctypes.begin(); - newCTypes[index] = UnwrapPromiseType(ctypes[index]); - ++it; - it = std::find_if(it, ctypes.end(), [promiseType](checker::Type *t) { - return t == promiseType || t->AsETSObjectType()->GetBaseType() == promiseType; - }); - } while (it != ctypes.end()); - return checker->CreateETSUnionType(std::move(newCTypes)); -} + expr->SetTsType(checker->HandleAwaitExpression(expr->argument_->Check(checker), expr)); + return expr->TsType(); +} checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const { @@ -1197,13 +1484,37 @@ checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const } ETSChecker *checker = GetETSChecker(); - checker::Type *newTsType {nullptr}; - std::tie(newTsType, expr->operationType_) = + + 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; + } + } + + auto [newTsType, operationType] = checker->CheckBinaryOperator(expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start()); - expr->SetTsType(newTsType); + expr->SetTsType(checker->MaybeBoxType(newTsType)); + expr->SetOperationType(checker->MaybeBoxType(operationType)); checker->Context().CheckBinarySmartCastCondition(expr); + if (inSmartExpr) { + checker->Context().ExitTestExpression(); + } + return expr->TsType(); } @@ -1227,28 +1538,67 @@ checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const return st->TsType(); } -checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, - checker::Type *calleeType) const +static bool LambdaIsField(ir::CallExpression *expr) +{ + if (!expr->Callee()->IsMemberExpression()) { + return false; + } + auto *me = expr->Callee()->AsMemberExpression(); + return me->PropVar() != nullptr; +} + +static bool OverloadDeclaration(ir::Expression *expr) +{ + while (expr->IsMemberExpression()) { + expr = expr->AsMemberExpression()->Property(); + } + + if (expr->IsIdentifier() && expr->AsIdentifier()->Variable() != nullptr) { + return expr->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::OVERLOAD); + } + return false; +} + +static Signature *CreateRelaxedAnySyntheticCallSignature(ETSChecker *checker) +{ + auto *info = checker->CreateSignatureInfo(); + info->minArgCount = 0; + + auto *paramVar = + varbinder::Scope::CreateVar(checker->ProgramAllocator(), "args", varbinder::VariableFlags::NONE, nullptr); + paramVar->SetTsType(checker->CreateETSArrayType(checker->GlobalETSRelaxedAnyType())); + info->restVar = paramVar; + // owner is not set + + return checker->CreateSignature(info, checker->GlobalETSRelaxedAnyType(), ir::ScriptFunctionFlags::NONE, false); +} + +static checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, checker::Type *calleeType) { if (calleeType->IsETSFunctionType() && calleeType->AsETSFunctionType()->HasHelperSignature() && 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()); } + if (calleeType->IsETSFunctionType() && OverloadDeclaration(expr->Callee())) { + return checker->FirstMatchSignatures(expr, calleeType); + } + if (calleeType->IsETSExtensionFuncHelperType()) { auto *signature = ResolveCallForETSExtensionFuncHelperType(calleeType->AsETSExtensionFuncHelperType(), checker, expr); - GetChecker()->AsETSChecker()->UpdateDeclarationFromSignature(expr, signature); + checker->AsETSChecker()->UpdateDeclarationFromSignature(expr, signature); 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)) { @@ -1257,8 +1607,16 @@ checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallE } return signature; } + + auto noSignatures = ArenaVector {checker->Allocator()->Adapter()}; + if (calleeType->IsETSRelaxedAnyType()) { + noSignatures.push_back(CreateRelaxedAnySyntheticCallSignature(checker)); + } + auto &signatures = expr->IsETSConstructorCall() ? calleeType->AsETSObjectType()->ConstructSignatures() - : calleeType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow(); + : calleeType->IsETSRelaxedAnyType() + ? noSignatures + : calleeType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow(); return checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, expr->Start()); } @@ -1266,7 +1624,7 @@ checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallE static ETSObjectType *GetCallExpressionCalleeObject(ETSChecker *checker, ir::CallExpression *expr, Type *calleeType) { if (expr->IsETSConstructorCall()) { - return calleeType->AsETSObjectType(); + return calleeType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); } auto callee = expr->Callee(); if (callee->IsMemberExpression()) { @@ -1276,21 +1634,20 @@ static ETSObjectType *GetCallExpressionCalleeObject(ETSChecker *checker, ir::Cal return checker->Context().ContainingClass(); } -Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, Type *calleeType) const +static Type *GetReturnType(ETSChecker *checker, ir::CallExpression *expr, Type *calleeType) { - ETSChecker *checker = GetETSChecker(); - if (calleeType->IsTypeError()) { return checker->GlobalTypeError(); } if (!calleeType->IsETSFunctionType() && !expr->IsETSConstructorCall() && - !calleeType->IsETSExtensionFuncHelperType()) { + !calleeType->IsETSExtensionFuncHelperType() && !calleeType->IsETSRelaxedAnyType()) { checker->LogError(diagnostic::NO_CALL_SIGNATURE, {calleeType}, expr->Start()); return checker->GlobalTypeError(); } Signature *const signature = ResolveSignature(checker, expr, calleeType); + if (signature == nullptr) { return checker->GlobalTypeError(); } @@ -1302,13 +1659,7 @@ Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, Type *calleeType) con checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); } - if (calleeType->IsETSMethodType() && signature->Function()->IsDynamic()) { - ES2PANDA_ASSERT(signature->Function()->IsDynamic()); - auto lang = signature->Function()->Language(); - expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), signature->Params(), lang, false)); - } else { - expr->SetSignature(signature); - } + expr->SetSignature(signature); // #22951: this type should not be encoded as a signature flag if (signature->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { @@ -1335,10 +1686,15 @@ static void CheckAbstractCall(ETSChecker *checker, ir::CallExpression *expr) static void CheckCallee(ETSChecker *checker, ir::CallExpression *expr) { checker->CheckNonNullish(expr->Callee()); - if (expr->Callee()->IsMemberExpression() && expr->Callee()->AsMemberExpression()->Object() != nullptr && - expr->Callee()->AsMemberExpression()->Object()->TsType()->IsETSObjectType() && - expr->Callee()->AsMemberExpression()->Object()->TsType()->AsETSObjectType()->HasObjectFlag( - ETSObjectFlags::READONLY)) { + if (!expr->Callee()->IsMemberExpression()) { + return; + } + auto memberExpr = expr->Callee()->AsMemberExpression(); + if (memberExpr->Object() == nullptr) { + return; + } + auto baseType = memberExpr->Object()->TsType()->MaybeBaseTypeOfGradualType(); + if (baseType->IsETSObjectType() && baseType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::READONLY)) { checker->LogError(diagnostic::READONLY_CALL, {}, expr->Start()); expr->SetTsType(checker->GlobalTypeError()); } @@ -1362,19 +1718,10 @@ static checker::SavedCheckerContext ReconstructOwnerClassContext(ETSChecker *che return SavedCheckerContext(checker, status, owner); } -checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *calleeType) const +static checker::Type *GetCallExpressionReturnType(ETSChecker *checker, ir::CallExpression *expr, + checker::Type *calleeType) { - ETSChecker *checker = GetETSChecker(); - checker::Type *returnType = nullptr; - if (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(); - expr->SetSignature(checker->ResolveDynamicCallExpression(expr->Callee(), expr->Arguments(), lang, false)); - returnType = expr->Signature()->ReturnType(); - } else { - returnType = GetReturnType(expr, calleeType); - } + checker::Type *returnType = GetReturnType(checker, expr, calleeType); if (returnType->IsTypeError()) { return checker->GlobalTypeError(); @@ -1392,6 +1739,10 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr return returnType; } + if (!signature->HasFunction()) { + return checker->GlobalTypeError(); + } + auto owner = const_cast(util::Helpers::GetContainingObjectType(signature->Function())); SavedCheckerContext savedCtx(ReconstructOwnerClassContext(checker, owner)); @@ -1417,6 +1768,25 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr // NOTE(vpukhov): #14902 substituted signature is not updated } +static void CheckOverloadCall(ETSChecker *checker, ir::CallExpression *expr) +{ + if (!expr->Callee()->IsMemberExpression() || !OverloadDeclaration(expr->Callee())) { + return; + } + + auto *sig = expr->Signature(); + auto *functionNode = sig->OwnerVar()->Declaration()->Node(); + ir::AstNode *parent = functionNode->Parent(); + + bool isExported = functionNode->IsExported() || functionNode->IsDefaultExported(); + if (parent != nullptr && parent->IsClassDefinition() && parent->AsClassDefinition()->IsNamespaceTransformed() && + !parent->AsClassDefinition()->IsDeclare() && !isExported) { + checker->LogError(diagnostic::NOT_EXPORTED, + {sig->OwnerVar()->Declaration()->Name(), parent->AsClassDefinition()->Ident()->Name()}, + expr->Start()); + } +} + checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -1439,14 +1809,17 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const CheckCallee(checker, expr); - checker::Type *const returnType = GetCallExpressionReturnType(expr, calleeType); + checker::TypeStackElement tse(checker, expr, {{diagnostic::CYCLIC_CALLEE, {}}}, expr->Start()); + ERROR_SANITY_CHECK(checker, !tse.HasTypeError(), return expr->SetTsType(checker->GlobalTypeError())); + + checker::Type *const returnType = GetCallExpressionReturnType(checker, expr, calleeType); expr->SetTsType(returnType); if (returnType->IsTypeError()) { return returnType; } - if (calleeType->IsETSArrowType()) { + if (calleeType->IsETSArrowType() || calleeType->IsETSRelaxedAnyType()) { expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCast( - checker->GlobalETSNullishObjectType(), checker->MaybeBoxType(expr->Signature()->ReturnType()))); + checker->GlobalETSAnyType(), checker->MaybeBoxType(expr->Signature()->ReturnType()))); } else { expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature())); } @@ -1456,16 +1829,51 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const checker->ComputeApparentType(returnType); } - if (returnType->IsTypeError()) { - expr->SetTsType(returnType); - return expr->TsType(); - } - + CheckOverloadCall(checker, expr); CheckVoidTypeExpression(checker, expr); CheckAbstractCall(checker, expr); return expr->TsType(); } +static bool IsNumericType(ETSChecker *checker, Type *type) +{ + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type); +} + +static Type *BiggerNumericType(ETSChecker *checker, Type *t1, Type *t2) +{ + ES2PANDA_ASSERT(IsNumericType(checker, t1)); + ES2PANDA_ASSERT(IsNumericType(checker, t2)); + + auto *rel = checker->Relation(); + + if (rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t2)) { + return checker->GlobalDoubleBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t2)) { + return checker->GlobalFloatBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t2)) { + return checker->GlobalLongBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t2)) { + return checker->GlobalIntBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t2)) { + return checker->GlobalShortBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t2)) { + return checker->GlobalByteBuiltinType(); + } + ES2PANDA_UNREACHABLE(); +} + checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const { if (expr->TsType() != nullptr) { @@ -1502,24 +1910,16 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const checker->Context().CombineSmartCasts(consequentSmartCasts); if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { - expr->SetTsType(checker->GetNonConstantType(consequentType)); + expr->SetTsType(consequentType); + } else if (IsNumericType(GetETSChecker(), consequentType) && IsNumericType(GetETSChecker(), alternateType)) { + expr->SetTsType(BiggerNumericType(GetETSChecker(), consequentType, alternateType)); } else { - // If possible and required update number literal type to the proper value (identical to left-side type) - if (alternate->IsNumberLiteral() && - checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) { - expr->SetTsType(consequentType); - } else if (consequent->IsNumberLiteral() && - checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) { - expr->SetTsType(alternateType); - } else { - expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); - if (expr->TsType()->IsETSReferenceType()) { - checker->MaybeBoxExpression(expr->Consequent()); - checker->MaybeBoxExpression(expr->Alternate()); - } - } + expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); } + // Restore smart casts to initial state. + checker->Context().RestoreSmartCasts(smartCasts); + return expr->TsType(); } @@ -1528,6 +1928,9 @@ static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression { ES2PANDA_ASSERT(use->IsIdentifier() || use->IsMemberExpression()); if (!type->IsETSMethodType()) { + if (use->Parent()->IsCallExpression() && type->IsETSObjectType() && use->IsMemberExpression()) { + checker->ValidateCallExpressionIdentifier(use->AsMemberExpression()->Property()->AsIdentifier(), type); + } return type; } auto const getUseSite = [use]() { @@ -1535,23 +1938,45 @@ static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression }; ir::Expression *expr = use; - while (expr->Parent()->IsMemberExpression() && expr->Parent()->AsMemberExpression()->Property() == expr) { + while (expr->Parent()->IsMemberExpression() && !expr->Parent()->AsMemberExpression()->IsComputed() && + expr->Parent()->AsMemberExpression()->Property() == expr) { expr = expr->Parent()->AsMemberExpression(); } if (expr->Parent()->IsCallExpression() && expr->Parent()->AsCallExpression()->Callee() == expr) { return type; // type is actually used as method } + if (expr->Parent()->IsOverloadDeclaration()) { + return type; // Don't trans overloaded name to arrow type. + } + + auto *const functionType = type->AsETSFunctionType(); + auto &signatures = functionType->CallSignatures(); - if (type->AsETSFunctionType()->CallSignatures().at(0)->HasSignatureFlag(SignatureFlags::PRIVATE)) { - checker->LogError(diagnostic::PRIVATE_METHOD_AS_VALUE, getUseSite()); + if (signatures.at(0)->HasSignatureFlag(SignatureFlags::PRIVATE)) { + checker->LogError(diagnostic::PRIVATE_OR_PROTECTED_METHOD_AS_VALUE, {"Private"}, getUseSite()); + return checker->GlobalTypeError(); + } + if (signatures.at(0)->HasSignatureFlag(SignatureFlags::PROTECTED)) { + checker->LogError(diagnostic::PRIVATE_OR_PROTECTED_METHOD_AS_VALUE, {"Protected"}, getUseSite()); return checker->GlobalTypeError(); } - if (type->AsETSFunctionType()->CallSignatures().size() > 1) { + auto it = signatures.begin(); + while (it != signatures.end()) { + if ((*it)->HasSignatureFlag(SignatureFlags::ABSTRACT) && + !(*it)->Owner()->GetDeclNode()->IsTSInterfaceDeclaration()) { + it = signatures.erase(it); + } else { + ++it; + } + } + + if (signatures.size() > 1U) { checker->LogError(diagnostic::OVERLOADED_METHOD_AS_VALUE, getUseSite()); return checker->GlobalTypeError(); } - return type->AsETSFunctionType()->MethodToArrow(checker); + auto *otherFuncType = functionType->MethodToArrow(checker); + return otherFuncType == nullptr ? checker->GlobalTypeError() : otherFuncType; } checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const @@ -1564,6 +1989,9 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const auto *identType = TransformTypeForMethodReference(checker, expr, checker->ResolveIdentifier(expr)); + if (expr->TsType() != nullptr && expr->TsType()->IsTypeError()) { + return expr->TsType(); + } ES2PANDA_ASSERT(expr->Variable() != nullptr); if (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpression() || expr != expr->Parent()->AsAssignmentExpression()->Left()) { @@ -1574,6 +2002,7 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const } expr->SetTsType(identType); + ES2PANDA_ASSERT(identType != nullptr); if (!identType->IsTypeError()) { checker->Context().CheckIdentifierSmartCastCondition(expr); } @@ -1581,7 +2010,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 {}; @@ -1597,148 +2026,535 @@ std::pair SearchReExportsType(ETSObjectType * expr->SetTsType(checker->GlobalTypeError()); return ret; } - ret = {item, name}; + ret = {item, name}; + } + + if (auto reExportType = SearchReExportsType(item, expr, name, checker); reExportType.first != nullptr) { + return reExportType; + } + } + + return ret; +} + +static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType, + checker::ETSChecker *checker) +{ + 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, + ir::MemberExpression *expr) const +{ + if (baseType->IsTypeError()) { + return checker->InvalidateType(expr); + } + + if (baseType->IsETSRelaxedAnyType()) { + return expr->AdjustType(checker, checker->GlobalETSRelaxedAnyType()); + } + + if (baseType->IsGradualType()) { + return ResolveMemberExpressionByBaseType(checker, baseType->AsGradualType()->GetBaseType(), expr); + } + + if (baseType->IsETSArrayType()) { + if (expr->Property()->AsIdentifier()->Name().Is("length")) { + return expr->AdjustType(checker, checker->GlobalIntBuiltinType()); + } + + return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); + } + + 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( + checker, expr, expr->SetAndAdjustType(checker, baseType->AsETSObjectType()))); + } + + 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 res = std::find(castMethods.begin(), castMethods.end(), expr->Property()->AsIdentifier()->Name().Utf8()); + 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(); +} + +checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const +{ + if (expr->TsType() != nullptr) { + return expr->TsType(); + } + ES2PANDA_ASSERT(!expr->IsOptional()); + ETSChecker *checker = GetETSChecker(); + auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checker))); + // Note: don't use possible smart cast to null-like types. + // Such situation should be correctly resolved in the subsequent lowering. + ES2PANDA_ASSERT(baseType != nullptr); + if (baseType->DefinitelyETSNullish() && expr->Object()->IsIdentifier()) { + baseType = expr->Object()->AsIdentifier()->Variable()->TsType(); + } + + if (baseType->IsETSObjectType() && !baseType->AsETSObjectType()->ReExports().empty() && + baseType->AsETSObjectType()->GetProperty(expr->Property()->AsIdentifier()->Name(), + PropertySearchFlags::SEARCH_ALL) == nullptr) { + if (auto reExportType = SearchReExportsType(baseType->AsETSObjectType(), expr, + expr->Property()->AsIdentifier()->Name(), checker); + reExportType.first != nullptr) { + baseType = reExportType.first; + expr->object_->SetTsType(baseType); + expr->property_->AsIdentifier()->SetName(reExportType.second); + } + } + if (!checker->CheckNonNullish(expr->Object())) { + auto *invalidType = checker->HasStatus(checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK) + ? checker->GlobalETSUnionUndefinedNull() + : checker->InvalidateType(expr); + return invalidType; + } + + if (expr->IsComputed()) { + return expr->AdjustType(checker, expr->CheckComputed(checker, baseType)); + } + + return ResolveMemberExpressionByBaseType(checker, baseType, expr); +} + +checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const +{ + ETSChecker *checker = GetETSChecker(); + for (ir::Expression *propExpr : expr->Properties()) { + ES2PANDA_ASSERT(propExpr->IsProperty()); + ir::Property *prop = propExpr->AsProperty(); + ir::Expression *value = prop->Value(); + value->Check(checker); + ES2PANDA_ASSERT(value->TsType()); + } + + expr->SetTsType(expr->PreferredType()); + return expr->PreferredType(); +} + +static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) +{ + auto preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); + if (preferredType == nullptr) { + checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); + return false; + } + + if (preferredType->IsTypeError()) { + // Don't need to duplicate error message for a single error. + return false; + } + + if (!preferredType->IsETSObjectType()) { + checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {preferredType}, expr->Start()); + return false; + } + + return true; +} + +static void SetTypeforRecordProperties(const ir::ObjectExpression *expr, checker::ETSObjectType *objType, + ETSChecker *checker) +{ + const auto &recordProperties = expr->Properties(); + auto typeArguments = objType->TypeArguments(); + auto *const valueType = typeArguments[1]; // Record type arguments + + for (auto *const recordProperty : recordProperties) { + ir::Expression *recordPropertyExpr = nullptr; + if (recordProperty->IsProperty()) { + recordPropertyExpr = recordProperty->AsProperty()->Value(); + } else if (recordProperty->IsSpreadElement()) { + recordPropertyExpr = recordProperty->AsSpreadElement()->Argument(); + } else if (recordProperty->IsIdentifier() && recordProperty->AsIdentifier()->IsErrorPlaceHolder()) { + ES2PANDA_ASSERT(checker->IsAnyError()); + continue; + } else { + ES2PANDA_UNREACHABLE(); + } + + recordPropertyExpr->SetPreferredType(valueType); + recordPropertyExpr->Check(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(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; } + } - if (auto reExportType = SearchReExportsType(item, expr, name, checker); reExportType.first != nullptr) { - return reExportType; + // Check that all required interface properties are satisfied + for (auto *property : allProperties) { + 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(property->Name().Utf8()) != 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 ret; + return true; // All required properties are satisfied } -static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType, - checker::ETSChecker *checker) +static bool IsObjectTypeCompatibleWithLiteral(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSObjectType *potentialObjType) { - std::ignore = checker->TypeError(expr, diagnostic::PROPERTY_NONEXISTENT, - {expr->Property()->AsIdentifier()->Name(), baseType}, expr->Object()->Start()); -} + // Split record/map types, class types and interfaces as requested by reviewer -checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checker, checker::Type *baseType, - ir::MemberExpression *expr) const -{ - if (baseType->IsTypeError()) { - return checker->InvalidateType(expr); + 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; } - if (baseType->IsETSArrayType()) { - if (expr->Property()->AsIdentifier()->Name().Is("length")) { - return expr->AdjustType(checker, checker->GlobalIntType()); + // 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; + } } - return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); + // Check all required interface properties are satisfied + return AreAllRequiredInterfacePropertiesSatisfied(expr, potentialObjType, checker); } - if (baseType->IsETSFunctionType() || baseType->IsETSTupleType()) { - return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); - } + // 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 (baseType->IsETSObjectType()) { - checker->ETSObjectTypeDeclNode(checker, baseType->AsETSObjectType()); - return expr->SetTsType(TransformTypeForMethodReference( - checker, expr, expr->SetAndAdjustType(checker, baseType->AsETSObjectType()))); + if (!HasParameterlessConstructor(potentialObjType, checker, expr->Start())) { + return false; } - if (baseType->IsETSUnionType()) { - return expr->AdjustType(checker, expr->CheckUnionMember(checker, baseType)); - } - TypeErrorOnMissingProperty(expr, baseType, checker); - return expr->TsType(); + // Check that all properties in literal exist in class + return CheckObjectLiteralCompatibility(expr, potentialObjType); } -checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const +checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSUnionType *unionType) { - if (expr->TsType() != nullptr) { - return expr->TsType(); - } - ES2PANDA_ASSERT(!expr->IsOptional()); - ETSChecker *checker = GetETSChecker(); - auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checker))); - // Note: don't use possible smart cast to null-like types. - // Such situation should be correctly resolved in the subsequent lowering. - if (baseType->DefinitelyETSNullish() && expr->Object()->IsIdentifier()) { - baseType = expr->Object()->AsIdentifier()->Variable()->TsType(); + std::vector candidateObjectTypes; + // Phase 1: Gather all ETSObjectTypes from the union + for (auto *constituentType : unionType->ConstituentTypes()) { + auto type = constituentType->MaybeBaseTypeOfGradualType(); + if (type->IsETSObjectType()) { + candidateObjectTypes.push_back(type->AsETSObjectType()); + } } - if (baseType->IsETSObjectType() && !baseType->AsETSObjectType()->ReExports().empty() && - baseType->AsETSObjectType()->GetProperty(expr->Property()->AsIdentifier()->Name(), - PropertySearchFlags::SEARCH_ALL) == nullptr) { - if (auto reExportType = SearchReExportsType(baseType->AsETSObjectType(), expr, - expr->Property()->AsIdentifier()->Name(), checker); - reExportType.first != nullptr) { - baseType = reExportType.first; - expr->object_->AsIdentifier()->SetTsType(baseType); - expr->property_->AsIdentifier()->SetName(reExportType.second); + std::vector matchingObjectTypes; + // Phase 2: Filter candidates using the helper function + for (auto *potentialObjType : candidateObjectTypes) { + if (IsObjectTypeCompatibleWithLiteral(checker, expr, potentialObjType)) { + matchingObjectTypes.push_back(potentialObjType); } } - if (!checker->CheckNonNullish(expr->Object())) { - auto *invalidType = checker->HasStatus(checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK) - ? checker->GlobalETSNullishType() - : checker->InvalidateType(expr); - return invalidType; - } - if (expr->IsComputed()) { - return expr->AdjustType(checker, expr->CheckComputed(checker, baseType)); + // Phase 3: Decide based on number of matches + if (matchingObjectTypes.size() == 1) { + return matchingObjectTypes.front(); } - - return ResolveMemberExpressionByBaseType(checker, baseType, expr); -} - -checker::Type *ETSAnalyzer::PreferredType(ir::ObjectExpression *expr) const -{ - return expr->preferredType_; -} - -checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const -{ - ETSChecker *checker = GetETSChecker(); - for (ir::Expression *propExpr : expr->Properties()) { - ES2PANDA_ASSERT(propExpr->IsProperty()); - ir::Property *prop = propExpr->AsProperty(); - ir::Expression *value = prop->Value(); - value->Check(checker); - ES2PANDA_ASSERT(value->TsType()); + 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; } - - expr->SetTsType(expr->PreferredType()); - return expr->PreferredType(); + // Ambiguous + checker->LogError(diagnostic::AMBIGUOUS_REFERENCE, {expr->PreferredType()->ToString()}, expr->Start()); + return nullptr; } -static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) +static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { - auto preferredType = expr->PreferredType(); - if (preferredType == nullptr) { - checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); - return false; + // Assume not null, checked by caller in Check() + checker::Type *preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); + + if (preferredType->IsETSAsyncFuncReturnType()) { + preferredType = preferredType->AsETSAsyncFuncReturnType()->GetPromiseTypeArg(); } - if (preferredType->IsTypeError()) { - // Don't need to duplicate error message for a single error. - return false; + if (preferredType->IsETSUnionType()) { + return ResolveUnionObjectTypeForObjectLiteral(checker, expr, preferredType->AsETSUnionType()); } - if (!preferredType->IsETSObjectType()) { - checker->LogError(diagnostic::CKASS_COMPOSITE_INVALID_TARGET, {preferredType}, expr->Start()); - return false; + if (preferredType->IsETSObjectType()) { + return preferredType->AsETSObjectType(); } - return true; + return nullptr; } -static void SetTypeforRecordProperties(const ir::ObjectExpression *expr, checker::ETSObjectType *objType, - ETSChecker *checker) +// Helper to handle interface type objects +static checker::Type *HandleInterfaceType(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSObjectType *objType) { - const auto &recordProperties = expr->Properties(); - auto typeArguments = objType->TypeArguments(); - auto *const valueType = typeArguments[1]; // Record type arguments + 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; +} - for (auto *const recordProperty : recordProperties) { - auto *const recordPropertyExpr = recordProperty->AsProperty()->Value(); - ETSChecker::SetPreferredTypeIfPossible(recordPropertyExpr, valueType); - recordPropertyExpr->Check(checker); - } +// 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 @@ -1748,63 +2564,87 @@ checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const return expr->TsType(); } - if (!ValidatePreferredType(checker, expr)) { + if (expr->PreferredType() == nullptr) { + checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); expr->SetTsType(checker->GlobalTypeError()); return expr->TsType(); } - if (expr->PreferredType()->IsETSDynamicType()) { - return CheckDynamic(expr); + if (!expr->PreferredType()->IsETSUnionType() && !ValidatePreferredType(checker, expr)) { + expr->SetTsType(checker->GlobalTypeError()); + return expr->TsType(); } - 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, 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 (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 (!haveEmptyConstructor) { - return checker->TypeError(expr, diagnostic::NO_PARAMLESS_CTOR, {objType->Name()}, expr->Start()); + + // 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::CollectNonOptionalProperty(const ETSObjectType *objType, + std::unordered_map &props) const { ETSChecker *checker = GetETSChecker(); - checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType(); + // Note: all the properties of an interface will be lowered as accessor before checker. + auto const &methodMap = objType->InstanceMethods(); + for (const auto &[propName, var] : methodMap) { + if (!checker->IsVariableGetterSetter(var)) { + continue; + } + + auto propertyType = checker->GetTypeOfVariable(var); + if (propertyType->IsTypeError()) { + // Note: error handle later. + continue; + } + + if (checker->Relation()->IsSupertypeOf(propertyType, checker->GlobalETSUndefinedType())) { + // non-optional properties + continue; + } + props.insert({propName, const_cast(objType)}); + } + + for (auto const *superInterface : objType->Interfaces()) { + CollectNonOptionalProperty(superInterface, props); + } +} +void ETSAnalyzer::CheckObjectExprPropsHelper(const ir::ObjectExpression *expr, checker::ETSObjectType *objType, + checker::PropertySearchFlags searchFlags, + std::unordered_map &properties) const +{ + ETSChecker *checker = GetETSChecker(); for (ir::Expression *propExpr : expr->Properties()) { if (!propExpr->IsProperty()) { checker->LogError(diagnostic::OBJECT_LITERAL_NOT_KV, {}, expr->Start()); @@ -1835,16 +2675,51 @@ void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, checker auto *propType = checker->GetTypeOfVariable(lv); if (propType->IsETSMethodType()) { - checker->LogError(diagnostic::OBJECT_LITERAL_METHOD_KEY, {pname}, propExpr->Start()); + checker->LogError(diagnostic::OBJECT_LITERAL_METHOD_KEY, {}, propExpr->Start()); return; } - ETSChecker::SetPreferredTypeIfPossible(value, propType); + if (auto setterType = GetSetterType(lv, checker); setterType != nullptr) { + propType = setterType; + } + + value->SetPreferredType(propType); + propExpr->SetTsType(propType); key->SetTsType(propType); value->SetTsType(value->Check(checker)); checker::AssignmentContext(checker->Relation(), value, value->TsType(), propType, value->Start(), {{diagnostic::PROP_INCOMPAT, {value->TsType(), propType, pname}}}); + if (properties.find(pname) != properties.end()) { + properties.erase(pname); + } + } +} + +void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, + checker::ETSObjectType *objectTypeForProperties, + checker::PropertySearchFlags searchFlags) const +{ + ETSChecker *checker = GetETSChecker(); + checker::ETSObjectType *objType = objectTypeForProperties; + if (objType->IsGlobalETSObjectType() && !expr->Properties().empty()) { + checker->LogError(diagnostic::ERROR_ARKTS_NO_UNTYPED_OBJ_LITERALS, expr->Start()); + } + + std::unordered_map propertyWithNonOptionalType; + if (objType->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + CollectNonOptionalProperty(objType, propertyWithNonOptionalType); + } + + CheckObjectExprPropsHelper(expr, objType, searchFlags, propertyWithNonOptionalType); + + for (const auto &[propName, ownerType] : propertyWithNonOptionalType) { + if (objType == ownerType) { + checker->LogError(diagnostic::OBJECT_LITERAL_NON_OPTIONAL_PROP_LOST, {propName, objType}, expr->Start()); + } else { + checker->LogError(diagnostic::OBJECT_LITERAL_NON_OPTIONAL_PROP_OF_SUPER_LOST, + {propName, ownerType, objType}, expr->Start()); + } } if (objType->HasObjectFlag(ETSObjectFlags::REQUIRED)) { @@ -1891,6 +2766,11 @@ checker::Type *ETSAnalyzer::Check(ir::SuperExpression *expr) const checker::Type *ETSAnalyzer::Check(ir::TemplateLiteral *expr) const { ETSChecker *checker = GetETSChecker(); + + for (auto *it : expr->Expressions()) { + it->Check(checker); + } + if (expr->TsType() != nullptr) { return expr->TsType(); } @@ -1901,10 +2781,6 @@ checker::Type *ETSAnalyzer::Check(ir::TemplateLiteral *expr) const return expr->TsType(); } - for (auto *it : expr->Expressions()) { - it->Check(checker); - } - for (auto *it : expr->Quasis()) { it->Check(checker); } @@ -1974,7 +2850,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()) { @@ -1998,7 +2874,8 @@ 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()); + ES2PANDA_ASSERT(argType != nullptr); if (argType->IsETSUnionType()) { for (auto *it : argType->AsETSUnionType()->ConstituentTypes()) { checker::Type *elType = ComputeTypeOfType(checker, it); @@ -2033,16 +2910,14 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const auto argType = expr->argument_->Check(checker); const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; - checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); - auto unboxedOperandType = - isCondExpr ? checker->MaybeUnboxConditionalInRelation(argType) : checker->MaybeUnboxInRelation(argType); - + checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(expr->argument_, argType, isCondExpr); if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { switch (expr->OperatorType()) { case lexer::TokenType::PUNCTUATOR_MINUS: { checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); // We do not need this const anymore as we are negating the bigint object in runtime + ES2PANDA_ASSERT(type != nullptr); type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); expr->argument_->SetTsType(type); expr->SetTsType(type); @@ -2068,11 +2943,6 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const } } - if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && - unboxedOperandType->IsETSPrimitiveType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); - } - SetTsTypeForUnaryExpression(checker, expr, operandType); checker->Context().CheckUnarySmartCastCondition(expr); @@ -2088,25 +2958,23 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const } checker::Type *operandType = expr->argument_->Check(checker); - if (operandType->IsTypeError()) { - return checker->InvalidateType(expr); - } + FORWARD_TYPE_ERROR(checker, operandType, expr); if (expr->Argument()->IsIdentifier()) { - checker->ValidateUnaryOperatorOperand(expr->Argument()->AsIdentifier()->Variable()); + checker->ValidateUnaryOperatorOperand(expr->Argument()->AsIdentifier()->Variable(), expr); } else if (expr->Argument()->IsTSAsExpression()) { if (auto *const asExprVar = expr->Argument()->AsTSAsExpression()->Variable(); asExprVar != nullptr) { - checker->ValidateUnaryOperatorOperand(asExprVar); + checker->ValidateUnaryOperatorOperand(asExprVar, expr); } } else if (expr->Argument()->IsTSNonNullExpression()) { if (auto *const nonNullExprVar = expr->Argument()->AsTSNonNullExpression()->Variable(); nonNullExprVar != nullptr) { - checker->ValidateUnaryOperatorOperand(nonNullExprVar); + checker->ValidateUnaryOperatorOperand(nonNullExprVar, expr); } } else if (expr->Argument()->IsMemberExpression()) { varbinder::LocalVariable *propVar = expr->argument_->AsMemberExpression()->PropVar(); if (propVar != nullptr) { - checker->ValidateUnaryOperatorOperand(propVar); + checker->ValidateUnaryOperatorOperand(propVar, expr); } } else { ES2PANDA_ASSERT(checker->IsAnyError()); @@ -2124,11 +2992,6 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const return expr->SetTsType(checker->GlobalTypeError()); } - if (operandType->IsETSObjectType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) | - checker->GetBoxingFlag(unboxedType)); - } - return expr->SetTsType(operandType); } @@ -2144,7 +3007,9 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->CreateETSBooleanType(expr->Value())); + auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2153,7 +3018,9 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->Allocator()->New(expr->Char())); + auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2167,26 +3034,74 @@ checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const return expr->TsType(); } -checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const +static bool CheckIfLiteralValueIsAppropriate(ETSChecker *checker, Type *type, ir::NumberLiteral *expr) { - ETSChecker *checker = GetETSChecker(); - if (expr->Number().IsInt()) { - expr->SetTsType(checker->CreateIntType(expr->Number().GetInt())); - return expr->TsType(); + auto number = expr->Number(); + auto relation = checker->Relation(); + if (relation->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalIntegralBuiltinType(), type)) { + if (number.IsReal()) { + return false; + } + auto val = number.GetValueAndCastTo(); + if (relation->IsIdenticalTo(type, checker->GlobalByteBuiltinType())) { + return val >= std::numeric_limits::min() && val <= std::numeric_limits::max(); + } + if (relation->IsIdenticalTo(type, checker->GlobalShortBuiltinType())) { + return val >= std::numeric_limits::min() && val <= std::numeric_limits::max(); + } + if (relation->IsIdenticalTo(type, checker->GlobalIntBuiltinType())) { + return val >= std::numeric_limits::min() && val <= std::numeric_limits::max(); + } + } else if (relation->IsIdenticalTo(type, checker->GlobalCharBuiltinType())) { + auto val = number.GetValueAndCastTo(); + return !number.IsReal() && val >= std::numeric_limits::min() && + val <= std::numeric_limits::max(); + } else if (number.IsDouble()) { + if (relation->IsIdenticalTo(type, checker->GlobalFloatBuiltinType())) { + auto doubleVal = number.GetDouble(); + if (doubleVal < std::numeric_limits::min() || doubleVal > std::numeric_limits::max()) { + return false; + } + auto floatVal = static_cast(doubleVal); + return static_cast(floatVal) == doubleVal; + } + return relation->IsIdenticalTo(checker->GlobalDoubleBuiltinType(), type); } + return true; +} - if (expr->Number().IsLong()) { - expr->SetTsType(checker->CreateLongType(expr->Number().GetLong())); +checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const +{ + if (expr->TsType() != nullptr) { return expr->TsType(); } - if (expr->Number().IsFloat()) { - expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat())); - return expr->TsType(); + ETSChecker *checker = GetETSChecker(); + Type *type; + + if (auto *preferredType = + GetAppropriatePreferredType(expr->PreferredType(), [&](Type *tp) { return checker->CheckIfNumeric(tp); }); + preferredType != nullptr && !expr->IsFolded() && + CheckIfLiteralValueIsAppropriate(checker, preferredType, expr)) { + type = preferredType->Clone(checker); + } else if (expr->Number().IsDouble()) { + type = checker->GlobalDoubleBuiltinType()->Clone(checker); + } else if (expr->Number().IsFloat()) { + type = checker->GlobalFloatBuiltinType()->Clone(checker); + } else if (expr->Number().IsLong()) { + type = checker->GlobalLongBuiltinType()->Clone(checker); + } else if (expr->Number().IsInt()) { + type = checker->GlobalIntBuiltinType()->Clone(checker); + } else if (expr->Number().IsShort()) { + type = checker->GlobalShortBuiltinType()->Clone(checker); + } else if (expr->Number().IsByte()) { + type = checker->GlobalByteBuiltinType()->Clone(checker); + } else { + return checker->GlobalTypeError(); } - expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble())); - return expr->TsType(); + type->AddTypeFlag(TypeFlag::CONSTANT); + return expr->SetTsType(type); } checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const @@ -2222,10 +3137,17 @@ 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()); + auto *type = checker->GetImportSpecifierObjectType(importDecl, st->Local()->AsIdentifier())->AsETSObjectType(); checker->SetrModuleObjectTsType(st->Local(), type); return type; } @@ -2252,10 +3174,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; } } @@ -2283,6 +3204,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); } @@ -2318,9 +3244,11 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - for (auto *anno : st->Annotations()) { - checker->CheckStandardAnnotation(anno); - anno->Check(checker); + if (st->HasAnnotations()) { + for (auto *anno : st->Annotations()) { + checker->CheckStandardAnnotation(anno); + anno->Check(checker); + } } ScopeContext scopeCtx(checker, st->Scope()); @@ -2331,14 +3259,32 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const } } - auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); - if (annoDecl != st && annoDecl->IsDeclare()) { - checker->CheckAmbientAnnotation(st, annoDecl); + auto baseName = st->GetBaseName(); + if (!baseName->IsErrorPlaceHolder() && baseName->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + auto *annoDecl = baseName->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); + if (annoDecl != st && annoDecl->IsDeclare()) { + checker->CheckAmbientAnnotation(st, annoDecl); + } } return ReturnTypeForStatement(st); } +static void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, + ir::AnnotationUsage *st, ETSChecker *checker) +{ + for (const auto &entry : fieldMap) { + if (entry.second->Value() == nullptr) { + checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); + continue; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *clone = entry.second->Clone(checker->Allocator(), st); + st->AddProperty(clone); + clone->Check(checker); + } +} + checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const { if (st->Expr()->TsType() != nullptr) { @@ -2347,18 +3293,23 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - if (st->GetBaseName()->Variable() == nullptr || - !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { - checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->Start()); + auto *baseName = st->GetBaseName(); + if (baseName->Variable() == nullptr || !baseName->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + if (!baseName->IsErrorPlaceHolder()) { + checker->LogError(diagnostic::NOT_AN_ANNOTATION, {baseName->Name()}, baseName->Start()); + } + + ES2PANDA_ASSERT(checker->IsAnyError()); return ReturnTypeForStatement(st); } - auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); + auto *annoDecl = baseName->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(); + ES2PANDA_ASSERT(field->Id() != nullptr); fieldMap.insert(std::make_pair(field->Id()->Name(), field)); } @@ -2367,15 +3318,15 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const return ReturnTypeForStatement(st); } - if (st->Properties().size() == 1 && + if (st->Properties().size() == 1 && st->Properties().at(0)->AsClassProperty()->Id() != nullptr && st->Properties().at(0)->AsClassProperty()->Id()->Name() == compiler::Signatures::ANNOTATION_KEY_VALUE) { checker->CheckSinglePropertyAnnotation(st, annoDecl); fieldMap.clear(); } else { - checker->CheckMultiplePropertiesAnnotation(st, st->GetBaseName()->Name(), fieldMap); + checker->CheckMultiplePropertiesAnnotation(st, baseName->Name(), fieldMap); } - checker->ProcessRequiredFields(fieldMap, st, checker); + ProcessRequiredFields(fieldMap, st, checker); return ReturnTypeForStatement(st); } @@ -2392,6 +3343,19 @@ checker::Type *ETSAnalyzer::Check(ir::ContinueStatement *st) const return checker->GlobalTypeError(); } + // CTE if target is outside the function + auto getEnclosingMethod = [](const ir::AstNode *node) { + const ir::AstNode *enclosingMethod = node->Parent(); + while (enclosingMethod != nullptr && !enclosingMethod->IsMethodDefinition() && + !enclosingMethod->IsArrowFunctionExpression()) { + enclosingMethod = enclosingMethod->Parent(); + } + return enclosingMethod; + }; + if (getEnclosingMethod(st) != getEnclosingMethod(st->Target())) { + checker->LogError(diagnostic::CONTINUE_TARGET_OUTSIDE_FUNCTION, {}, st->Start()); + } + checker->AddStatus(CheckerStatus::MEET_CONTINUE); return ReturnTypeForStatement(st); } @@ -2435,8 +3399,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() && !relation->IsLegalBoxedPrimitiveConversion(iterType, elemType)) { checker->LogError(diagnostic::ITERATOR_ELEMENT_TYPE_MISMATCH, {elemType, iterType}, st->Start()); return false; } @@ -2462,23 +3427,18 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const // NOTE: Smart casts are not processed correctly within the loops now, thus clear them at this point. auto [smartCasts, clearFlag] = checker->Context().EnterLoop(*st, std::nullopt); - checker::Type *const exprType = st->Right()->Check(checker); - if (exprType == nullptr) { - checker->LogError(diagnostic::FOROF_CANT_INFER_SOURCE, {}, st->Right()->Start()); - return checker->GlobalTypeError(); - } - - checker::Type *elemType = nullptr; + checker::Type *const exprType = st->Right()->Check(checker)->MaybeBaseTypeOfGradualType(); + checker::Type *elemType = checker->GlobalTypeError(); if (exprType->IsETSStringType()) { - elemType = checker->GetGlobalTypesHolder()->GlobalCharType(); - } else if (exprType->IsETSArrayType()) { - elemType = exprType->AsETSArrayType()->ElementType(); + elemType = checker->GlobalBuiltinETSStringType(); + } else if (exprType->IsETSArrayType() || exprType->IsETSResizableArrayType()) { + elemType = checker->GetElementTypeOfArray(exprType); } else if (exprType->IsETSObjectType() || exprType->IsETSUnionType() || exprType->IsETSTypeParameter()) { elemType = st->CheckIteratorMethod(checker); } - if (elemType == nullptr) { + if (elemType == checker->GlobalTypeError()) { checker->LogError(diagnostic::FOROF_SOURCE_NONITERABLE, {}, st->Right()->Start()); return checker->GlobalTypeError(); } @@ -2585,7 +3545,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; } @@ -2627,32 +3588,30 @@ bool ETSAnalyzer::CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::S // Case when function's return type is defined explicitly: if (st->argument_ == nullptr) { - if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() && - !funcReturnType->IsETSAsyncFuncReturnType()) { + ES2PANDA_ASSERT(funcReturnType != nullptr); + if (!funcReturnType->MaybeBaseTypeOfGradualType()->IsETSVoidType() && + funcReturnType != checker->GlobalVoidType() && + !funcReturnType->MaybeBaseTypeOfGradualType()->IsETSAsyncFuncReturnType()) { checker->LogError(diagnostic::RETURN_WITHOUT_VALUE, {}, st->Start()); return false; } funcReturnType = checker->GlobalVoidType(); } else { const auto name = containingFunc->Scope()->InternalName().Mutf8(); - if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { + if (!CheckArgumentVoidType(funcReturnType->MaybeBaseTypeOfGradualType(), checker, name, st)) { return false; } - if (st->argument_->IsObjectExpression()) { - st->argument_->AsObjectExpression()->SetPreferredType(funcReturnType); - } if (st->argument_->IsMemberExpression()) { checker->SetArrayPreferredTypeForNestedMemberExpressions(st->argument_->AsMemberExpression(), funcReturnType); - } - - if (st->argument_->IsArrayExpression()) { - st->argument_->AsArrayExpression()->SetPreferredType(funcReturnType); + } else { + st->argument_->SetPreferredType(funcReturnType); } checker::Type *argumentType = st->argument_->Check(checker); - return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc); + return CheckReturnType(checker, funcReturnType->MaybeBaseTypeOfGradualType(), argumentType, st->argument_, + containingFunc); } return true; } @@ -2674,13 +3633,14 @@ checker::Type *ETSAnalyzer::GetFunctionReturnType(ir::ReturnStatement *st, ir::S } else { // Case when function's return type should be inferred from return statement(s): if (containingFunc->Signature()->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { - InferReturnType(checker, containingFunc, funcReturnType, - st->argument_); // This removes the NEED_RETURN_TYPE flag, so only the first return - // statement going to land here... + funcReturnType = InferReturnType(checker, containingFunc, + st->argument_); // This removes the NEED_RETURN_TYPE flag, so only the + // first return statement going to land here... } else { // All subsequent return statements: - ProcessReturnStatements(checker, containingFunc, funcReturnType, st, - st->argument_); // and the remaining return statements will get processed here. + funcReturnType = + ProcessReturnStatements(checker, containingFunc, st, + st->argument_); // and the remaining return statements will get processed here. } } @@ -2734,9 +3694,8 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::TypeRelationFlag::NONE); auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); - auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U - ? checker->MaybeUnboxInRelation(comparedExprType) - : comparedExprType; + // may have no meaning to unbox comparedExprType + auto unboxedDiscType = checker->MaybeUnboxType(comparedExprType); SmartCastArray smartCasts = checker->Context().CloneSmartCasts(); bool hasDefaultCase = false; @@ -2777,8 +3736,18 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const { ETSChecker *checker = GetETSChecker(); - - if (checker::Type *argType = st->argument_->Check(checker); !argType->IsTypeError()) { + const auto *arg = st->argument_; + checker::Type *argType = st->argument_->Check(checker); + + 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()); } @@ -2831,7 +3800,8 @@ checker::Type *ETSAnalyzer::Check(ir::TryStatement *st) const checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const { - if (st->TsType() != nullptr) { + bool initChecked = st->Init() != nullptr ? st->Init()->TsType() != nullptr : true; + if (st->TsType() != nullptr && initChecked) { return st->TsType(); } @@ -2859,7 +3829,11 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) auto *smartType = variableType; if (auto *const initType = st->Init() != nullptr ? st->Init()->TsType() : nullptr; initType != nullptr) { - smartType = checker->ResolveSmartType(initType, variableType); + auto const value = st->Init()->IsNumberLiteral() + ? std::make_optional(st->Init()->AsNumberLiteral()->Number().GetDouble()) + : std::nullopt; + + smartType = checker->ResolveSmartType(initType, variableType, value); // Set smart type for identifier if it differs from annotated type // Top-level and captured variables are not processed here! if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) { @@ -2875,7 +3849,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclaration *st) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(st->Annotations()); + checker->CheckAnnotations(st); for (auto *it : st->Declarators()) { it->Check(checker); @@ -2913,7 +3887,7 @@ checker::Type *ETSAnalyzer::Check(ir::WhileStatement *st) const checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const { ETSChecker *checker = GetETSChecker(); - checker->CheckAnnotations(node->Annotations()); + checker->CheckAnnotations(node); node->elementType_->Check(checker); node->SetTsType(node->GetType(checker)); @@ -2930,41 +3904,47 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const return expr->TsType(); } - checker->CheckAnnotations(expr->TypeAnnotation()->Annotations()); + checker->CheckAnnotations(expr->TypeAnnotation()); auto *const targetType = expr->TypeAnnotation()->AsTypeNode()->GetType(checker); - if (targetType->IsTypeError()) { - return checker->InvalidateType(expr); - } + FORWARD_TYPE_ERROR(checker, targetType, expr); - ETSChecker::SetPreferredTypeIfPossible(expr->Expr(), targetType); + expr->Expr()->SetPreferredType(targetType); auto const sourceType = expr->Expr()->Check(checker); - if (sourceType->IsTypeError()) { - return checker->InvalidateType(expr); + FORWARD_TYPE_ERROR(checker, sourceType, expr); + + if (sourceType->DefinitelyETSNullish() && !targetType->PossiblyETSNullish()) { + return expr->SetTsType(checker->TypeError(expr, diagnostic::NULLISH_CAST_TO_NONNULLISH, expr->Start())); } - // NOTE(vpukhov): #20510 lowering - if (targetType->IsETSPrimitiveType() && sourceType->IsETSReferenceType()) { - auto *const boxedTargetType = checker->MaybeBoxInRelation(targetType); - if (!checker->Relation()->IsIdenticalTo(sourceType, boxedTargetType)) { - expr->Expr()->AddAstNodeFlags(ir::AstNodeFlags::CHECKCAST); - } + if (expr->Expr()->IsLiteral() && sourceType->IsBuiltinNumeric() && targetType->IsETSTypeParameter()) { + checker->LogError(diagnostic::INVALID_CAST, {sourceType->ToString(), targetType->ToString()}, + expr->Expr()->Start()); + return checker->InvalidateType(expr); } - if (sourceType->DefinitelyETSNullish() && !targetType->PossiblyETSNullish()) { - return checker->TypeError(expr, diagnostic::NULLISH_CAST_TO_NONNULLISH, expr->Start()); + if (expr->Expr()->IsLiteral() && sourceType->IsBuiltinNumeric() && targetType->IsETSUnionType()) { + bool allAreTypeParams = true; + for (auto *sub : targetType->AsETSUnionType()->ConstituentTypes()) { + if (!sub->IsETSTypeParameter()) { + allAreTypeParams = false; + } + } + if (allAreTypeParams) { + checker->LogError(diagnostic::INVALID_CAST, {sourceType->ToString(), targetType->ToString()}, + expr->Expr()->Start()); + return checker->InvalidateType(expr); + } } const checker::CastingContext ctx( - checker->Relation(), diagnostic::INVALID_CAST, {sourceType, targetType}, + checker->Relation(), + sourceType->IsBuiltinNumeric() && targetType->IsBuiltinNumeric() ? diagnostic::IMPROPER_NUMERIC_CAST + : diagnostic::INVALID_CAST, + // CC-OFFNXT(G.FMT.03-CPP) project code style + {sourceType, targetType}, checker::CastingContext::ConstructorData {expr->Expr(), sourceType, targetType, expr->Expr()->Start()}); - if (sourceType->IsETSDynamicType() && targetType->IsLambdaObject()) { - // NOTE: itrubachev. change targetType to created lambdaobject type. - // Now targetType is not changed, only construct signature is added to it - checker->BuildLambdaObjectClass(targetType->AsETSObjectType(), - expr->TypeAnnotation()->AsETSFunctionType()->ReturnType()); - } expr->isUncheckedCast_ = ctx.UncheckedCast(); // Make sure the array type symbol gets created for the assembler to be able to emit checkcast. @@ -2975,12 +3955,10 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const } if (targetType == checker->GetGlobalTypesHolder()->GlobalETSNeverType()) { - return checker->TypeError(expr, diagnostic::CAST_TO_NEVER, expr->Start()); + return expr->SetTsType(checker->TypeError(expr, diagnostic::CAST_TO_NEVER, expr->Start())); } - checker->ComputeApparentType(targetType); - expr->SetTsType(targetType); - return expr->TsType(); + return expr->SetTsType(targetType); } checker::Type *ETSAnalyzer::Check(ir::TSEnumDeclaration *st) const @@ -2999,18 +3977,17 @@ checker::Type *ETSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const auto *stmtType = checker->BuildBasicInterfaceProperties(st); ES2PANDA_ASSERT(stmtType != nullptr); - if (stmtType->IsTypeError()) { - return st->SetTsType(stmtType); - } + FORWARD_TYPE_ERROR(checker, stmtType, st); - auto *interfaceType = stmtType->AsETSObjectType(); + auto *interfaceType = stmtType->IsGradualType() ? stmtType->AsGradualType()->GetBaseType()->AsETSObjectType() + : stmtType->AsETSObjectType(); checker->CheckInterfaceAnnotations(st); interfaceType->SetSuperType(checker->GlobalETSObjectType()); checker->CheckInvokeMethodsLegitimacy(interfaceType); - st->SetTsType(interfaceType); - + st->SetTsType(stmtType); + checker->CheckDynamicInheritanceAndImplement(interfaceType->AsETSObjectType()); checker::ScopeContext scopeCtx(checker, st->Scope()); auto savedContext = checker::SavedCheckerContext(checker, checker::CheckerStatus::IN_INTERFACE, interfaceType); @@ -3030,9 +4007,7 @@ 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); @@ -3050,10 +4025,62 @@ checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const return expr->TsType(); } +static varbinder::Variable *FindNameForImportNamespace(ETSChecker *checker, util::StringView &searchName, + ETSObjectType *baseType) +{ + /* This function try to find name1.name2, name1.A in file file1.ets, + * ./file1.ets: + * import * as name1 from "./file2" + * + * ./file2.ets: + * import * as name2 from "./file3" + * import {A} from "./file3" + * export {name2} + * export {A} + * + * ./file3.ets + * export class A{} + * + * 1. Find in file2->program->ast->scope first + * 2. Find in varbinder->selectiveExportAliasMultimap second + * if both found, return variable + */ + auto declNode = baseType->GetDeclNode(); + if (!declNode->IsIdentifier()) { + return nullptr; + } + if (declNode->Parent() == nullptr || declNode->Parent()->Parent() == nullptr) { + return nullptr; + } + auto importDeclNode = declNode->Parent()->Parent(); + if (!importDeclNode->IsETSImportDeclaration()) { + return nullptr; + } + + auto importDecl = importDeclNode->AsETSImportDeclaration(); + + parser::Program *program = checker->SelectEntryOrExternalProgram( + static_cast(checker->VarBinder()), importDecl->ImportMetadata().resolvedSource); + + auto &bindings = program->Ast()->Scope()->Bindings(); + + if (auto result = bindings.find(searchName); result != bindings.end()) { + auto &sMap = checker->VarBinder() + ->AsETSBinder() + ->GetSelectiveExportAliasMultimap() + .find(importDecl->ImportMetadata().resolvedSource) + ->second; + if (auto it = sMap.find(searchName); it != sMap.end()) { + return result->second; + } + } + return nullptr; +} + checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const { ETSChecker *checker = GetETSChecker(); - checker::Type *baseType = expr->Left()->Check(checker); + checker::Type *baseType = expr->Left()->Check(checker)->MaybeBaseTypeOfGradualType(); if (baseType->IsETSObjectType()) { // clang-format off auto searchName = expr->Right()->Name(); @@ -3063,7 +4090,11 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const searchName = expr->Right()->Name(); } varbinder::Variable *prop = - baseType->AsETSObjectType()->GetProperty(searchName, checker::PropertySearchFlags::SEARCH_DECL); + baseType->AsETSObjectType()->GetProperty(searchName, PropertySearchFlags::SEARCH_DECL); + + if (prop == nullptr) { + prop = FindNameForImportNamespace(GetETSChecker(), searchName, baseType->AsETSObjectType()); + } // NOTE(dslynko): in debugger evaluation mode must lazily generate module's properties here. if (prop == nullptr) { checker->LogError(diagnostic::NONEXISTENT_TYPE, {expr->Right()->Name()}, expr->Right()->Start()); @@ -3082,8 +4113,9 @@ checker::Type *ETSAnalyzer::Check(ir::TSQualifiedName *expr) const checker::Type *ETSAnalyzer::Check(ir::TSTypeAliasDeclaration *st) const { ETSChecker *checker = GetETSChecker(); + auto checkerContext = SavedCheckerContext(checker, CheckerStatus::NO_OPTS, checker->Context().ContainingClass()); - checker->CheckAnnotations(st->Annotations()); + checker->CheckAnnotations(st); if (st->TypeParams() == nullptr) { const checker::SavedTypeRelationFlagsContext savedFlagsCtx( diff --git a/ets2panda/checker/ETSAnalyzer.h b/ets2panda/checker/ETSAnalyzer.h index 28e145066b5aa0515e12f162f3b226d40a28121e..3bac2af23338f69798704c8f3226e26c3bf49455 100644 --- a/ets2panda/checker/ETSAnalyzer.h +++ b/ets2panda/checker/ETSAnalyzer.h @@ -36,11 +36,16 @@ public: virtual checker::Type *Check(ir::nodeType *node) const override; // CC-OFF(G.PRE.02,G.PRE.09) name part AST_NODE_REINTERPRET_MAPPING(DECLARE_ETSANALYZER_CHECK_METHOD) #undef DECLARE_ETSANALYZER_CHECK_METHOD - 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 CollectNonOptionalProperty(const ETSObjectType *objType, + std::unordered_map &props) const; + void CheckObjectExprPropsHelper(const ir::ObjectExpression *expr, checker::ETSObjectType *objType, + checker::PropertySearchFlags searchFlags, + std::unordered_map &properties) 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; @@ -49,14 +54,11 @@ private: ETSChecker *GetETSChecker() const; void CheckInstantatedClass(ir::ETSNewClassInstanceExpression *expr, ETSObjectType *&calleeObj) const; void CheckMethodModifiers(ir::MethodDefinition *node) const; - checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, - checker::Type *calleeType) const; - checker::Type *GetReturnType(ir::CallExpression *expr, checker::Type *calleeType) const; checker::Type *GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc) const; - checker::Type *GetCallExpressionReturnType(ir::CallExpression *expr, checker::Type *calleeType) const; checker::Type *UnwrapPromiseType(checker::Type *type) const; checker::Type *GetSmartType(ir::AssignmentExpression *expr, checker::Type *leftType, checker::Type *rightType) const; + bool SetAssignmentExpressionTarget(ir::AssignmentExpression *const expr, ETSChecker *checker) const; bool CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::TypeNode *returnTypeAnnotation, ETSChecker *checker) const; @@ -78,12 +80,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 473909a8d1e7c0bcb079060334621fa403d226ab..d3127e33aa2eb640069872c868a0be4ba0186073 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -15,6 +15,7 @@ #include "ETSAnalyzerHelpers.h" #include "checker/types/ets/etsAsyncFuncReturnType.h" +#include "checker/types/typeError.h" namespace ark::es2panda::checker { @@ -51,12 +52,16 @@ void CheckExtensionIsShadowedInCurrentClassOrInterface(checker::ETSChecker *chec // check if there are class and interfaces' instance methods with the same name as extensions. auto *const methodVariable = objType->GetOwnProperty(methodName); - if (methodVariable == nullptr) { + if (methodVariable == nullptr || methodVariable->TsType()->IsTypeError()) { return; } + if (methodVariable->TsType()->IsTypeError()) { + return; + } const auto *const funcType = methodVariable->TsType()->AsETSFunctionType(); for (auto *funcSignature : funcType->CallSignatures()) { + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(funcSignature->ReturnType()); if (!checker->Relation()->SignatureIsSupertypeOf(signature, funcSignature) && !checker->HasSameAssemblySignature(signature, funcSignature)) { @@ -70,8 +75,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 +114,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 +152,9 @@ 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()); + ES2PANDA_ASSERT(originalExtensionSigInfo != nullptr); originalExtensionSigInfo->minArgCount -= 1U; originalExtensionSigInfo->params.erase(originalExtensionSigInfo->params.begin()); checker::Signature *originalExtensionSignature = @@ -212,7 +217,7 @@ void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::Scr checker->AddStatus(checker::CheckerStatus::IN_CONSTRUCTOR); } - if (node->IsExtensionMethod()) { + if (node->IsExtensionMethod() && scriptFunc->Signature() != nullptr) { CheckExtensionMethod(checker, scriptFunc, node); } @@ -221,6 +226,7 @@ void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::Scr if (scriptFunc->ReturnTypeAnnotation() == nullptr) { if (scriptFunc->IsAsyncFunc()) { auto returnType = checker->CreateETSAsyncFuncReturnTypeFromBaseType(scriptFunc->Signature()->ReturnType()); + ES2PANDA_ASSERT(returnType != nullptr); scriptFunc->Signature()->SetReturnType(returnType->PromiseType()); for (auto &returnStatement : scriptFunc->ReturnStatements()) { returnStatement->SetReturnType(checker, returnType); @@ -243,16 +249,17 @@ 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()); - checker->VarBinder()->AsETSBinder()->LookupTypeReference(objectId, false); - auto *returnType = checker->AllocNode( - checker->AllocNode(objectId, nullptr, nullptr, checker->Allocator()), - checker->Allocator()); + auto *objectId = checker->ProgramAllocNode(compiler::Signatures::BUILTIN_OBJECT_CLASS, + checker->ProgramAllocator()); + checker->VarBinder()->AsETSBinder()->LookupTypeReference(objectId); + auto *returnType = checker->ProgramAllocNode( + checker->ProgramAllocNode(objectId, nullptr, nullptr, checker->ProgramAllocator()), + checker->ProgramAllocator()); + ES2PANDA_ASSERT(returnType != nullptr); objectId->SetParent(returnType->Part()); returnType->Part()->SetParent(returnType); - returnType->SetTsType( - checker->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()); } @@ -305,19 +312,16 @@ static bool HasIteratorInterface(ETSObjectType const *const objectType) } void CheckIteratorMethodReturnType(ETSChecker *checker, ir::ScriptFunction *scriptFunc, - const lexer::SourcePosition &position, const std::string &methodName) + const lexer::SourcePosition &position, + [[maybe_unused]] const std::string &methodName) { - const auto *returnType = scriptFunc->Signature()->ReturnType(); - - if (returnType == nullptr) { - checker->LogError(diagnostic::MISSING_RETURN_TYPE_2, {util::StringView(methodName)}, position); - return; - } + const auto *returnType = scriptFunc->Signature()->ReturnType()->MaybeBaseTypeOfGradualType(); if (returnType->IsETSTypeParameter()) { returnType = checker->GetApparentType(returnType->AsETSTypeParameter()->GetConstraintType()); } + ES2PANDA_ASSERT(returnType != nullptr); if (returnType->IsETSObjectType() && HasIteratorInterface(returnType->AsETSObjectType())) { return; } @@ -368,12 +372,6 @@ checker::Signature *ResolveCallExtensionFunction(checker::Type *functionType, ch expr->Arguments().erase(expr->Arguments().begin()); return nullptr; } - if (!signature->HasSignatureFlag(SignatureFlags::EXTENSION_FUNCTION)) { - checker->LogError(diagnostic::PROPERTY_NONEXISTENT, - {memberExpr->Property()->AsIdentifier()->Name(), memberExpr->ObjType()->Name()}, - memberExpr->Property()->Start()); - return nullptr; - } SwitchMethodCallToFunctionCall(checker, expr, signature); return signature; @@ -405,23 +403,24 @@ 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()); - signatures.insert(signatures.end(), type->ClassMethodType()->CallSignatures().begin(), - type->ClassMethodType()->CallSignatures().end()); - signatures.insert(signatures.end(), type->ExtensionMethodType()->CallSignatures().begin(), - type->ExtensionMethodType()->CallSignatures().end()); + ArenaVector signatures(checker->ProgramAllocator()->Adapter()); + auto const &classMethodSignatures = type->ClassMethodType()->CallSignatures(); + auto const &extensionMethodSignatures = type->ExtensionMethodType()->CallSignaturesOfMethodOrArrow(); + + signatures.insert(signatures.end(), classMethodSignatures.cbegin(), classMethodSignatures.cend()); + signatures.insert(signatures.end(), extensionMethodSignatures.cbegin(), extensionMethodSignatures.cend()); auto *memberExpr = expr->Callee()->AsMemberExpression(); auto *dummyReceiver = memberExpr->Object(); - auto *dummyReceiverVar = type->ExtensionMethodType()->CallSignatures()[0]->Params()[0]; + auto *dummyReceiverVar = extensionMethodSignatures[0]->Params()[0]; expr->Arguments().insert(expr->Arguments().begin(), dummyReceiver); const bool typeParamsNeeded = dummyReceiverVar->TsType()->IsETSObjectType(); - for (auto *methodCallSig : type->ClassMethodType()->CallSignatures()) { + for (auto *methodCallSig : classMethodSignatures) { 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(); @@ -433,11 +432,11 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E auto *signature = checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, expr->Start(), checker::TypeRelationFlag::NO_THROW); - for (auto *methodCallSig : type->ClassMethodType()->CallSignatures()) { + for (auto *methodCallSig : classMethodSignatures) { 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`) @@ -480,8 +480,8 @@ checker::Signature *ResolveCallForETSExtensionFuncHelperType(checker::ETSExtensi signature = GetMostSpecificSigFromExtensionFuncAndClassMethod(type, checker, expr); if (signature == nullptr) { - checker->ThrowSignatureMismatch(type->ExtensionMethodType()->CallSignatures(), expr->Arguments(), expr->Start(), - "call"); + checker->ThrowSignatureMismatch(type->ExtensionMethodType()->CallSignaturesOfMethodOrArrow(), expr->Arguments(), + expr->Start(), "call"); } return signature; @@ -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()); } @@ -509,27 +509,9 @@ ArenaVector GetUnionTypeSignatures(ETSChecker *checker, ch void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType) { - if (checker->IsNullLikeOrVoidExpression(expr->Argument())) { - auto tsType = checker->CreateETSBooleanType(true); - tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); - expr->SetTsType(tsType); - return; - } - - if (operandType == nullptr || !operandType->IsConditionalExprType()) { - checker->LogError(diagnostic::ASSERT_NOT_LOGICAL, {}, expr->Argument()->Start()); - expr->SetTsType(checker->GlobalTypeError()); - return; - } + FORWARD_VALUE_ON_TYPE_ERROR(checker, operandType, expr, EMPTY_VALUE); - auto exprRes = operandType->ResolveConditionExpr(); - if (std::get<0>(exprRes)) { - auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); - tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); - expr->SetTsType(tsType); - return; - } - expr->SetTsType(checker->GlobalETSBooleanType()); + expr->SetTsType(checker->GlobalETSBooleanBuiltinType()); } void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType) @@ -537,29 +519,27 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, switch (expr->OperatorType()) { case lexer::TokenType::PUNCTUATOR_MINUS: case lexer::TokenType::PUNCTUATOR_PLUS: { - if (operandType == nullptr || !operandType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (operandType == nullptr || !operandType->IsETSObjectType() || + !operandType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::CONVERTIBLE_TO_NUMERIC)) { checker->LogError(diagnostic::OPERAND_NOT_NUMERIC, {}, expr->Argument()->Start()); expr->SetTsType(checker->GlobalTypeError()); break; } - if (operandType->HasTypeFlag(checker::TypeFlag::CONSTANT) && - expr->OperatorType() == lexer::TokenType::PUNCTUATOR_MINUS) { - expr->SetTsType(checker->NegateNumericType(operandType, expr)); - break; - } - expr->SetTsType(operandType); break; } case lexer::TokenType::PUNCTUATOR_TILDE: { - if (operandType == nullptr || !operandType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (operandType == nullptr || !operandType->IsETSObjectType() || + !operandType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::CONVERTIBLE_TO_NUMERIC)) { checker->LogError(diagnostic::OPERAND_NOT_NUMERIC, {}, expr->Argument()->Start()); expr->SetTsType(checker->GlobalTypeError()); break; } - - expr->Argument()->SetTsType(expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType))); + auto exprType = expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); + if (!expr->Argument()->TsType()->IsETSIntEnumType()) { + expr->Argument()->SetTsType(exprType); + } break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -611,14 +591,15 @@ checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir: checker->LogError(diagnostic::ITERATOR_TYPE_ABSENT, {}, left->Start()); return checker->GlobalTypeError(); } - return iterType; + return checker->GetNonConstantType(iterType); } -bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, const std::string &name, +bool CheckArgumentVoidType(checker::Type *funcReturnType, ETSChecker *checker, const std::string &name, ir::ReturnStatement *st) { if (name.find(compiler::Signatures::ETS_MAIN_WITH_MANGLE_BEGIN) != std::string::npos) { - if (!funcReturnType->IsETSVoidType() && !funcReturnType->IsIntType()) { + if (!funcReturnType->IsETSVoidType() && + !checker->Relation()->IsSupertypeOf(checker->GlobalIntBuiltinType(), funcReturnType)) { checker->LogError(diagnostic::MAIN_BAD_RETURN, {}, st->Start()); } } @@ -633,14 +614,6 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker checker->LogError(diagnostic::UNEXPECTED_VALUE_RETURN, {}, stArgument->Start()); return false; } - if (!checker::AssignmentContext(checker->Relation(), stArgument, argumentType, funcReturnType, - stArgument->Start(), std::nullopt, - checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) - // CC-OFFNXT(G.FMT.02) project code style - .IsAssignable()) { - checker->LogError(diagnostic::RETURN_TYPE_MISMATCH, {}, stArgument->Start()); - return false; - } return true; } @@ -666,15 +639,15 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker return true; } -void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, - ir::Expression *stArgument) +checker::Type *InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, ir::Expression *stArgument) { // First (or single) return statement in the function: - funcReturnType = + auto *funcReturnType = stArgument == nullptr ? checker->GlobalVoidType() : checker->GetNonConstantType(stArgument->Check(checker)); + ES2PANDA_ASSERT(funcReturnType != nullptr); if (funcReturnType->IsTypeError()) { containingFunc->Signature()->RemoveSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE); - return; + return funcReturnType; } /* @@ -684,38 +657,23 @@ void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, ch return () => {} ``` */ - if (stArgument != nullptr && stArgument->IsArrowFunctionExpression()) { - auto arrowFunc = stArgument->AsArrowFunctionExpression(); - auto typeAnnotation = arrowFunc->CreateTypeAnnotation(checker); - - auto *argumentType = arrowFunc->TsType(); - funcReturnType = typeAnnotation->GetType(checker); - if (!checker::AssignmentContext(checker->Relation(), arrowFunc, argumentType, funcReturnType, - stArgument->Start(), 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()); - funcReturnType = checker->GlobalTypeError(); - return; - } - } containingFunc->Signature()->SetReturnType(funcReturnType); containingFunc->Signature()->RemoveSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE); containingFunc->Signature()->AddSignatureFlag(checker::SignatureFlags::INFERRED_RETURN_TYPE); checker->VarBinder()->AsETSBinder()->BuildFunctionName(containingFunc); - if (stArgument != nullptr && stArgument->IsObjectExpression()) { - stArgument->AsObjectExpression()->SetPreferredType(funcReturnType); + if (stArgument != nullptr) { + stArgument->SetPreferredType(funcReturnType); } + + return funcReturnType; } bool IsArrayExpressionValidInitializerForType(ETSChecker *checker, const Type *const arrayExprPreferredType) { const auto validForTarget = arrayExprPreferredType == nullptr // preferred type will be inferred from elements - || arrayExprPreferredType->IsETSArrayType() // valid for array type - || arrayExprPreferredType->IsETSTupleType() // valid for tuple type + || arrayExprPreferredType->IsAnyETSArrayOrTupleType() // valid for array or tuple types || checker->Relation()->IsSupertypeOf(arrayExprPreferredType, // valid for 'Object' checker->GlobalETSObjectType()); @@ -736,16 +694,16 @@ void CastPossibleTupleOnRHS(ETSChecker *checker, ir::AssignmentExpression *expr) } } -void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, - ir::ReturnStatement *st, ir::Expression *stArgument) +checker::Type *ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, ir::ReturnStatement *st, + ir::Expression *stArgument) { - funcReturnType = containingFunc->Signature()->ReturnType(); + auto *funcReturnType = containingFunc->Signature()->ReturnType(); if (stArgument == nullptr) { // previous return statement(s) have value if (!funcReturnType->IsETSVoidType() && funcReturnType != checker->GlobalVoidType()) { checker->LogError(diagnostic::MIXED_VOID_NONVOID, {}, st->Start()); - return; + return funcReturnType; } } else { if (stArgument->IsObjectExpression()) { @@ -759,14 +717,15 @@ void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containing checker::Type *argumentType = checker->GetNonConstantType(stArgument->Check(checker)); // previous return statement(s) don't have any value + ES2PANDA_ASSERT(argumentType != nullptr); if (funcReturnType->IsETSVoidType() && !argumentType->IsETSVoidType()) { checker->LogError(diagnostic::MIXED_VOID_NONVOID, {}, stArgument->Start()); - return; + return funcReturnType; } const auto name = containingFunc->Scope()->InternalName().Mutf8(); if (!CheckArgumentVoidType(funcReturnType, checker, name, st)) { - return; + return funcReturnType; } auto *const relation = checker->Relation(); @@ -779,6 +738,7 @@ void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containing relation->SetNode(nullptr); relation->SetFlags(checker::TypeRelationFlag::NONE); } + return funcReturnType; } bool CheckReturnTypeNecessity(ir::MethodDefinition *node) @@ -787,8 +747,60 @@ bool CheckReturnTypeNecessity(ir::MethodDefinition *node) auto *scriptFunc = node->Function(); needReturnType &= (node->IsNative() || node->IsDeclare()); needReturnType &= !node->IsConstructor(); + ES2PANDA_ASSERT(scriptFunc != nullptr); needReturnType &= !scriptFunc->IsSetter(); return needReturnType; } +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; + } + + auto *classProp = prop->AsClassProperty(); + if (classProp->Key()->Variable() == nullptr) { + continue; + } + + if (classProp->Key()->Variable()->HasFlag(varbinder::VariableFlags::INIT_IN_STATIC_BLOCK) && + !classProp->Key()->Variable()->HasFlag(varbinder::VariableFlags::INITIALIZED)) { + checker->LogError(diagnostic::MISSING_INIT_FOR_CONST_PACKAGE_PROP, {}, prop->Start()); + } + } +} + +// NOLINTBEGIN(readability-else-after-return) +std::tuple IsConstantTestValue(ir::Expression const *expr) +{ + if (expr->IsNullLiteral() || expr->IsUndefinedLiteral()) { + return {true, false}; + } else if (expr->IsBooleanLiteral()) { + return {true, expr->AsBooleanLiteral()->Value()}; + } else if (expr->IsStringLiteral()) { + return {true, expr->AsStringLiteral()->Str().Length() != 0}; + } else if (expr->IsCharLiteral()) { + return {true, expr->AsCharLiteral()->Char() != 0}; + } else if (expr->IsBigIntLiteral()) { + return {true, expr->AsBigIntLiteral()->Str() != "0"}; + } else if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + return {true, !num.IsZero()}; + } else if (expr->TsType()->IsETSEnumType() && expr->TsType()->IsConstantType()) { + // NOTE(gogabr): Should handle enum constants + return {false, false}; + } + return {false, false}; +} +// NOLINTEND(readability-else-after-return) + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSAnalyzerHelpers.h b/ets2panda/checker/ETSAnalyzerHelpers.h index 23b7493cd37929305ba28d9e74407fd13f827e97..37ac4ce4f2c8fa2188c44b75e7a5ad116a72b27a 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.h +++ b/ets2panda/checker/ETSAnalyzerHelpers.h @@ -52,17 +52,20 @@ ArenaVector GetUnionTypeSignatures(ETSChecker *checker, ch void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType); void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType); checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir::AstNode *left); -bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, const std::string &name, +bool CheckArgumentVoidType(checker::Type *funcReturnType, ETSChecker *checker, const std::string &name, ir::ReturnStatement *st); bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker::Type *argumentType, ir::Expression *stArgument, ir::ScriptFunction *containingFunc); -void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, - ir::Expression *stArgument); +checker::Type *InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, 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); +checker::Type *ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, ir::ReturnStatement *st, + ir::Expression *stArgument); bool CheckReturnTypeNecessity(ir::MethodDefinition *node); + +void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModule *pkg); + +std::tuple IsConstantTestValue(ir::Expression const *expr); } // namespace ark::es2panda::checker #endif // ES2PANDA_CHECKER_ETSANALYZERHELPERS_H diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 122718064b968942d22f392b182091030cf32571..fcee9f460c42a61cb2f1b45cac30585e8f09cb62 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" @@ -21,6 +25,8 @@ #include "ir/expressions/callExpression.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/statements/blockStatement.h" +#include "types/type.h" +#include "utils/arena_containers.h" #include "varbinder/ETSBinder.h" #include "parser/program/program.h" #include "checker/ets/aliveAnalyzer.h" @@ -30,9 +36,63 @@ #include "ir/base/scriptFunction.h" #include "util/helpers.h" #include "evaluate/scopedDebugInfoPlugin.h" +#include "checker/types/ets/etsTupleType.h" 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(); @@ -40,20 +100,21 @@ static util::StringView InitBuiltin(ETSChecker *checker, std::string_view signat ES2PANDA_ASSERT(iterator != varMap.end()); auto *var = iterator->second; Type *type {nullptr}; - if (var->Declaration()->Node()->IsClassDefinition()) { - type = checker->BuildBasicClassProperties(var->Declaration()->Node()->AsClassDefinition()); - } else { - ES2PANDA_ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); - type = checker->BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); + if (var->HasFlag(varbinder::VariableFlags::BUILTIN_TYPE)) { + if (var->Declaration()->Node()->IsClassDefinition()) { + type = checker->BuildBasicClassProperties(var->Declaration()->Node()->AsClassDefinition()); + } else { + ES2PANDA_ASSERT(var->Declaration()->Node()->IsTSInterfaceDeclaration()); + type = checker->BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); + } + checker->GetGlobalTypesHolder()->InitializeBuiltin(iterator->first, type); } - checker->GetGlobalTypesHolder()->InitializeBuiltin(iterator->first, type); return iterator->first; } void ETSChecker::CheckObjectLiteralKeys(const ArenaVector &properties) { - static std::set names; - names.clear(); + std::set names; for (auto property : properties) { if (!property->IsProperty()) { @@ -197,7 +258,7 @@ static void IntializeFunctionInterfaces(GlobalTypesHolder *typeHolder) return typeHolder->GlobalFunctionBuiltinType(arity, hasRest)->AsETSObjectType(); }; - for (size_t arity = 0; arity < typeHolder->VariadicFunctionTypeThreshold(); arity++) { + for (size_t arity = 0; arity <= typeHolder->VariadicFunctionTypeThreshold(); arity++) { getItf(arity, false)->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); getItf(arity, true)->AddObjectFlag(ETSObjectFlags::FUNCTIONAL); } @@ -210,6 +271,9 @@ void ETSChecker::InitializeBuiltins(varbinder::ETSBinder *varbinder) } const auto varMap = varbinder->TopScope()->Bindings(); + if (varMap.find(compiler::Signatures::BUILTIN_OBJECT_CLASS) == varMap.end()) { + return; + } auto const objectName = InitBuiltin(this, compiler::Signatures::BUILTIN_OBJECT_CLASS); @@ -255,22 +319,14 @@ 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; } + permitRelaxedAny_ = options.IsPermitRelaxedAny(); auto *etsBinder = varbinder->AsETSBinder(); InitializeBuiltins(etsBinder); - for (auto &entry : etsBinder->DynamicImportVars()) { - auto &data = entry.second; - if (data.import->IsPureDynamic()) { - data.variable->SetTsType(GlobalBuiltinDynamicType(data.import->Language())); - } - } - bool isEvalMode = (debugInfoPlugin_ != nullptr); if (UNLIKELY(isEvalMode)) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -284,9 +340,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()); @@ -325,13 +378,23 @@ 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); + auto *savedProgram2 = VarBinder()->AsETSBinder()->Program(); + varbinder::RecordTableContext recordTableCtx(VarBinder()->AsETSBinder(), extProg); + VarBinder()->AsETSBinder()->SetProgram(extProg); + VarBinder()->AsETSBinder()->ResetTopScope(extProg->GlobalScope()); + checker::SavedCheckerContext savedContext(this, Context().Status(), Context().ContainingClass()); + AddStatus(checker::CheckerStatus::IN_EXTERNAL); + CheckProgram(extProg, VarBinder()->IsGenStdLib() || extProg->IsGenAbcForExternal()); + VarBinder()->AsETSBinder()->SetProgram(savedProgram2); + VarBinder()->AsETSBinder()->ResetTopScope(savedProgram2->GlobalScope()); + } } } ES2PANDA_ASSERT(Program()->Ast()->IsProgram()); + Program()->Ast()->Check(this); if (runAnalysis && !IsAnyError()) { @@ -367,6 +430,20 @@ bool ETSChecker::IsClassStaticMethod(checker::ETSObjectType *objType, checker::S signature->HasSignatureFlag(checker::SignatureFlags::STATIC); } +[[nodiscard]] TypeFlag ETSChecker::TypeKind(const Type *const type) noexcept +{ + // These types were not present in the ETS_TYPE list. Some of them are omitted intentionally, other are just bugs + static constexpr auto TO_CLEAR = TypeFlag::CONSTANT | TypeFlag::GENERIC | TypeFlag::ETS_INT_ENUM | + TypeFlag::ETS_STRING_ENUM | TypeFlag::READONLY | TypeFlag::BIGINT_LITERAL | + TypeFlag::ETS_TYPE_ALIAS | TypeFlag::TYPE_ERROR; + + CHECK_NOT_NULL(type); + auto res = static_cast(type->TypeFlags() & ~(TO_CLEAR)); + ES2PANDA_ASSERT_POS(res == TypeFlag::NONE || helpers::math::IsPowerOfTwo(res & ~(TypeFlag::NONE)), + ark::es2panda::GetPositionForDiagnostic()); + return res; +} + template ETSObjectType *ETSChecker::AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const { @@ -379,41 +456,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(); @@ -429,6 +545,16 @@ Type *ETSChecker::GlobalETSUndefinedType() const return GetGlobalTypesHolder()->GlobalETSUndefinedType(); } +Type *ETSChecker::GlobalETSAnyType() const +{ + return GetGlobalTypesHolder()->GlobalETSAnyType(); +} + +Type *ETSChecker::GlobalETSRelaxedAnyType() const +{ + return GetGlobalTypesHolder()->GlobalETSRelaxedAnyType(); +} + Type *ETSChecker::GlobalETSNeverType() const { return GetGlobalTypesHolder()->GlobalETSNeverType(); @@ -454,18 +580,28 @@ ETSObjectType *ETSChecker::GlobalETSObjectType() const return AsETSObjectType(&GlobalTypesHolder::GlobalETSObjectType); } -ETSUnionType *ETSChecker::GlobalETSNullishType() const +ETSUnionType *ETSChecker::GlobalETSUnionUndefinedNull() const { - auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSNullishType)(); + auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSUnionUndefinedNull)(); return ret != nullptr ? ret->AsETSUnionType() : nullptr; } -ETSUnionType *ETSChecker::GlobalETSNullishObjectType() const +ETSUnionType *ETSChecker::GlobalETSUnionUndefinedNullObject() const { - auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSNullishObjectType)(); + auto *ret = (GetGlobalTypesHolder()->*&GlobalTypesHolder::GlobalETSUnionUndefinedNullObject)(); return ret != nullptr ? ret->AsETSUnionType() : nullptr; } +ETSObjectType *ETSChecker::GlobalBuiltinClassType() const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalClassBuiltinType); +} + +ETSObjectType *ETSChecker::GlobalBuiltinETSResizableArrayType() const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalArrayBuiltinType); +} + ETSObjectType *ETSChecker::GlobalBuiltinETSStringType() const { return AsETSObjectType(&GlobalTypesHolder::GlobalETSStringBuiltinType); @@ -506,16 +642,6 @@ ETSObjectType *ETSChecker::GlobalBuiltinFunctionType() const return AsETSObjectType(&GlobalTypesHolder::GlobalFunctionBuiltinType); } -ETSObjectType *ETSChecker::GlobalBuiltinJSRuntimeType() const -{ - return AsETSObjectType(&GlobalTypesHolder::GlobalJSRuntimeBuiltinType); -} - -ETSObjectType *ETSChecker::GlobalBuiltinJSValueType() const -{ - return AsETSObjectType(&GlobalTypesHolder::GlobalJSValueBuiltinType); -} - ETSObjectType *ETSChecker::GlobalBuiltinFunctionType(size_t nargs, bool hasRest) const { return AsETSObjectType(&GlobalTypesHolder::GlobalFunctionBuiltinType, nargs, hasRest); @@ -536,38 +662,36 @@ size_t ETSChecker::GlobalBuiltinFunctionTypeVariadicThreshold() const return GetGlobalTypesHolder()->VariadicFunctionTypeThreshold(); } -ETSObjectType *ETSChecker::GlobalBuiltinDynamicType(Language lang) const +ETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) { - if (lang.GetId() == Language::Id::JS) { - return GlobalBuiltinJSValueType(); + ES2PANDA_ASSERT(contents->IsETSReferenceType()); + if (!contents->IsETSUnboxableObject()) { + auto *base = AsETSObjectType(&GlobalTypesHolder::GlobalBoxBuiltinType); + auto substitution = Substitution {}; + ES2PANDA_ASSERT(base != nullptr); + substitution.emplace(base->TypeArguments()[0]->AsETSTypeParameter(), contents); + return base->Substitute(Relation(), &substitution); } - return nullptr; -} -ETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) -{ - switch (TypeKind(contents)) { - case TypeFlag::ETS_BOOLEAN: + switch (contents->AsETSObjectType()->UnboxableKind()) { + case ETSObjectFlags::BUILTIN_BOOLEAN: return AsETSObjectType(&GlobalTypesHolder::GlobalBooleanBoxBuiltinType); - case TypeFlag::BYTE: + case ETSObjectFlags::BUILTIN_BYTE: return AsETSObjectType(&GlobalTypesHolder::GlobalByteBoxBuiltinType); - case TypeFlag::CHAR: - return AsETSObjectType(&GlobalTypesHolder::GlobalCharBoxBuiltinType); - case TypeFlag::SHORT: + case ETSObjectFlags::BUILTIN_SHORT: return AsETSObjectType(&GlobalTypesHolder::GlobalShortBoxBuiltinType); - case TypeFlag::INT: + case ETSObjectFlags::BUILTIN_CHAR: + return AsETSObjectType(&GlobalTypesHolder::GlobalCharBoxBuiltinType); + case ETSObjectFlags::BUILTIN_INT: return AsETSObjectType(&GlobalTypesHolder::GlobalIntBoxBuiltinType); - case TypeFlag::LONG: + case ETSObjectFlags::BUILTIN_LONG: return AsETSObjectType(&GlobalTypesHolder::GlobalLongBoxBuiltinType); - case TypeFlag::FLOAT: + case ETSObjectFlags::BUILTIN_FLOAT: return AsETSObjectType(&GlobalTypesHolder::GlobalFloatBoxBuiltinType); - case TypeFlag::DOUBLE: + case ETSObjectFlags::BUILTIN_DOUBLE: return AsETSObjectType(&GlobalTypesHolder::GlobalDoubleBoxBuiltinType); default: { - auto *base = AsETSObjectType(&GlobalTypesHolder::GlobalBoxBuiltinType); - auto *substitution = NewSubstitution(); - substitution->emplace(base->TypeArguments()[0]->AsETSTypeParameter(), contents); - return base->Substitute(Relation(), substitution); + ES2PANDA_UNREACHABLE(); } } } @@ -582,6 +706,16 @@ const GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() const return globalArraySignatures_; } +const ArenaSet &ETSChecker::UnionAssemblerTypes() const +{ + return unionAssemblerTypes_; +} + +ArenaSet &ETSChecker::UnionAssemblerTypes() +{ + return unionAssemblerTypes_; +} + Type *ETSChecker::GlobalTypeError() const { return GetGlobalTypesHolder()->GlobalTypeError(); @@ -625,19 +759,20 @@ void ETSChecker::HandleUpdatedCallExpressionNode(ir::CallExpression *callExpr) VarBinder()->AsETSBinder()->HandleCustomNodes(callExpr); } -Type *ETSChecker::SelectGlobalIntegerTypeForNumeric(Type *type) +Type *ETSChecker::SelectGlobalIntegerTypeForNumeric(Type *type) const { - switch (ETSType(type)) { - case checker::TypeFlag::FLOAT: { - return GlobalIntType(); - } - case checker::TypeFlag::DOUBLE: { - return GlobalLongType(); + if (type->IsETSObjectType()) { + auto const *objectType = type->AsETSObjectType(); + + if (objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { + return GlobalIntBuiltinType(); } - default: { - return type; + + if (objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { + return GlobalLongBuiltinType(); } } + return type; } Signature *ETSChecker::FindExtensionSetterInMap(util::StringView name, ETSObjectType *type) @@ -659,4 +794,20 @@ void ETSChecker::InsertExtensionGetterToMap(util::StringView name, ETSObjectType { GetGlobalTypesHolder()->InsertExtensionGetterToMap(name, type, sig); } + +bool ETSChecker::TypeHasDefaultValue(Type *tp) const +{ + return tp->IsBuiltinNumeric() || tp->IsETSBooleanType() || tp->IsETSCharType() || + Relation()->IsSupertypeOf(GlobalETSUndefinedType(), tp); +} + +/* Invoke method name in functional interfaces */ +std::string ETSChecker::FunctionalInterfaceInvokeName(size_t arity, bool hasRest) +{ + if (arity < GlobalBuiltinFunctionTypeVariadicThreshold()) { + return (hasRest ? "invokeR" : "invoke") + std::to_string(arity); + } + return "unsafeCall"; +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index a610a3902db7f59b7124be3c09b26416cef9a6c5..5aaf2180560f96f9ba72ed83b5af9b65b07164b6 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -21,10 +21,12 @@ #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 "types/type.h" #include "util/helpers.h" namespace ark::es2panda::varbinder { @@ -63,37 +65,35 @@ struct PairHash { using ComputedAbstracts = ArenaUnorderedMap, ArenaUnorderedSet>>; using ArrayMap = ArenaUnorderedMap, ETSArrayType *, PairHash>; +using ObjectInstantiationMap = ArenaUnorderedMap>; using GlobalArraySignatureMap = ArenaUnorderedMap; -using DynamicCallIntrinsicsMap = ArenaUnorderedMap>; -using DynamicClassIntrinsicsMap = ArenaUnorderedMap; -using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap; +using FunctionSignatureMap = ArenaUnorderedMap; +using FunctionInterfaceMap = ArenaUnorderedMap; using FunctionalInterfaceMap = ArenaUnorderedMap; using TypeMapping = ArenaUnorderedMap; -using DynamicCallNamesMap = ArenaMap, uint32_t>; -using ConstraintCheckRecord = std::tuple *, const Substitution *, lexer::SourcePosition>; +using ConstraintCheckRecord = std::tuple *, const Substitution, lexer::SourcePosition>; // can't use util::DiagnosticWithParams because std::optional can't contain references using MaybeDiagnosticInfo = std::optional>; +using AstNodePtr = ir::AstNode *; +using TypePtr = Type *; 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()), - DynamicClassIntrinsicsMap(Allocator()->Adapter())}, - dynamicLambdaSignatureCache_(Allocator()->Adapter()), + unionAssemblerTypes_(Allocator()->Adapter()), functionalInterfaceCache_(Allocator()->Adapter()), apparentTypes_(Allocator()->Adapter()), - dynamicCallNames_ { - {DynamicCallNamesMap(Allocator()->Adapter()), DynamicCallNamesMap(Allocator()->Adapter())}}, - overloadSigContainer_(Allocator()->Adapter()) + overloadSigContainer_(Allocator()->Adapter()), + readdedChecker_(Allocator()->Adapter()) { } @@ -102,15 +102,12 @@ public: NO_COPY_SEMANTIC(ETSChecker); NO_MOVE_SEMANTIC(ETSChecker); - [[nodiscard]] static inline TypeFlag ETSType(const Type *const type) noexcept + [[nodiscard]] static TypeFlag ETSType(const Type *const type) noexcept { - return static_cast(type->TypeFlags() & TypeFlag::ETS_TYPE); + return ETSChecker::TypeKind(type); } - [[nodiscard]] static inline TypeFlag TypeKind(const Type *const type) noexcept - { - return static_cast(type->TypeFlags() & checker::TypeFlag::ETS_TYPE); - } + [[nodiscard]] static TypeFlag TypeKind(const Type *const type) noexcept; Type *GlobalByteType() const; Type *GlobalShortType() const; @@ -123,14 +120,27 @@ public: Type *GlobalVoidType() const; Type *GlobalETSNullType() const; Type *GlobalETSUndefinedType() const; + Type *GlobalETSAnyType() const; + Type *GlobalETSRelaxedAnyType() const; Type *GlobalETSNeverType() const; Type *GlobalETSStringLiteralType() const; 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; + ETSUnionType *GlobalETSUnionUndefinedNull() const; + ETSUnionType *GlobalETSUnionUndefinedNullObject() const; + ETSObjectType *GlobalBuiltinClassType() const; + ETSObjectType *GlobalBuiltinETSResizableArrayType() const; ETSObjectType *GlobalBuiltinETSStringType() const; ETSObjectType *GlobalBuiltinETSBigIntType() const; ETSObjectType *GlobalBuiltinTypeType() const; @@ -139,8 +149,6 @@ public: ETSObjectType *GlobalStringBuilderBuiltinType() const; ETSObjectType *GlobalBuiltinPromiseType() const; ETSObjectType *GlobalBuiltinFunctionType() const; - ETSObjectType *GlobalBuiltinJSRuntimeType() const; - ETSObjectType *GlobalBuiltinJSValueType() const; ETSObjectType *GlobalBuiltinBoxType(Type *contents); ETSObjectType *GlobalBuiltinFunctionType(size_t nargs, bool hasRest) const; @@ -149,11 +157,17 @@ public: ETSObjectType *GlobalBuiltinTupleType(size_t nargs) const; - ETSObjectType *GlobalBuiltinDynamicType(Language lang) const; - GlobalArraySignatureMap &GlobalArrayTypes(); const GlobalArraySignatureMap &GlobalArrayTypes() const; + const ArenaSet &UnionAssemblerTypes() const; + ArenaSet &UnionAssemblerTypes(); + + bool IsRelaxedAnyTypeAnnotationAllowed() const + { + return permitRelaxedAny_; + } + Type *GlobalTypeError() const; [[nodiscard]] Type *InvalidateType(ir::Typed *node); [[nodiscard]] Type *TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, @@ -176,6 +190,7 @@ public: Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig); Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop); Type *GuaranteedTypeForUnionFieldAccess(ir::MemberExpression *memberExpression, ETSUnionType *etsUnionType); + void ReputCheckerData(); [[nodiscard]] bool IsETSChecker() const noexcept override { @@ -186,6 +201,7 @@ public: void CheckObjectLiteralKeys(const ArenaVector &properties); Type *BuildBasicClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); + Type *MaybeGradualType(ir::AstNode *node, ETSObjectType *type); Type *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); ETSObjectType *GetSuperType(ETSObjectType *type); ArenaVector GetInterfaces(ETSObjectType *type); @@ -194,7 +210,7 @@ public: void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(const Type *type); - std::optional GetTupleElementAccessValue(const Type *type); + std::optional GetTupleElementAccessValue(const ir::Expression *expr); bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr, bool reportError = true); bool ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *expr); @@ -203,6 +219,7 @@ public: ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param); void GetInterfacesOfClass(ETSObjectType *type, ArenaVector &interfaces); void CheckIfOverrideIsValidInInterface(ETSObjectType *classType, Signature *sig, Signature *sigFunc); + void CheckDynamicInheritanceAndImplement(ETSObjectType *const interfaceOrClassType); void CheckFunctionRedeclarationInInterface(ETSObjectType *classType, ArenaVector &similarSignatures, Signature *sigFunc); void ValidateAbstractMethodsToBeImplemented(ArenaVector &abstractsToBeImplemented, @@ -247,8 +264,15 @@ public: void CreateFunctionTypesFromAbstracts(const std::vector &abstracts, ArenaVector *target); void CheckCyclicConstructorCall(Signature *signature); + void CheckAnnotationReference(const ir::MemberExpression *memberExpr, const varbinder::LocalVariable *prop); + std::vector HandlePropertyResolution(varbinder::LocalVariable *const prop, + ir::MemberExpression *const memberExpr, + varbinder::Variable *const globalFunctionVar, + PropertySearchFlags searchFlag); std::vector ResolveMemberReference(const ir::MemberExpression *memberExpr, const ETSObjectType *target); + varbinder::LocalVariable *ResolveOverloadReference(const ir::Identifier *ident, ETSObjectType *objType, + PropertySearchFlags searchFlags); void WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *const memberExpr); varbinder::Variable *GetExtensionFuncVarInGlobalFunction(const ir::MemberExpression *const memberExpr); varbinder::Variable *GetExtensionFuncVarInGlobalField(const ir::MemberExpression *const memberExpr); @@ -277,6 +301,8 @@ public: void VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType); + bool TypeHasDefaultValue(Type *tp) const; + // Type creation ByteType *CreateByteType(int8_t value); ETSBooleanType *CreateETSBooleanType(bool value); @@ -288,7 +314,10 @@ 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 *CreateGradualType(Type *baseType, Language lang = Language(Language::Id::JS)); Type *CreateETSUnionType(Span constituentTypes); template Type *CreateETSUnionType(Type *const (&arr)[N]) // NOLINT(modernize-avoid-c-arrays) @@ -307,9 +336,6 @@ public: bool isRecursive = false); ETSFunctionType *CreateETSArrowType(Signature *signature); ETSFunctionType *CreateETSMethodType(util::StringView name, ArenaVector &&signatures); - ETSFunctionType *CreateETSDynamicArrowType(Signature *signature, Language lang); - ETSFunctionType *CreateETSDynamicMethodType(util::StringView name, ArenaVector &&signatures, - Language lang); ETSExtensionFuncHelperType *CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType, ETSFunctionType *extensionFunctionType); void AddThisReturnTypeFlagForInterfaceInvoke(ETSObjectType *interface); @@ -319,8 +345,6 @@ public: std::tuple CreateBuiltinArraySignatureInfo(const ETSArrayType *arrayType, size_t dim); Signature *CreateBuiltinArraySignature(const ETSArrayType *arrayType, size_t dim); - IntType *CreateIntTypeFromType(Type *type); - std::tuple CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName); ETSObjectType *CreatePromiseOf(Type *type); Signature *CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func); @@ -328,7 +352,6 @@ public: SignatureInfo *CreateSignatureInfo(); // Arithmetic - Type *NegateNumericType(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, @@ -344,12 +367,9 @@ public: checker::Type *CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types); - checker::Type *CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, - const checker::Type *const rightType); + checker::Type *CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType); - checker::Type *CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType, - const checker::Type *const rightType); checker::Type *CheckBinaryOperatorPlus( std::tuple op, bool isEqualOp, std::tuple types); @@ -360,9 +380,8 @@ public: std::tuple op, bool isEqualOp, std::tuple types); // CC-OFFNXT(G.FUN.01-CPP) solid logic - checker::Type *CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, - checker::Type *leftType, checker::Type *rightType, Type *unboxedL, - Type *unboxedR); + checker::Type *CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, checker::Type *leftType, + checker::Type *rightType, Type *unboxedL, Type *unboxedR); std::tuple CheckBinaryOperatorStrictEqual(ir::Expression *left, lexer::TokenType operationType, lexer::SourcePosition pos, checker::Type *leftType, checker::Type *rightType); @@ -375,15 +394,13 @@ public: checker::Type *rightType); checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right, lexer::SourcePosition pos); + bool CheckIfNumeric(Type *type); + bool CheckIfFloatingPoint(Type *type); bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType); Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression); - template - Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - - Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); + void SetGenerateValueOfFlags(std::tuple types, + std::tuple nodes); template Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); @@ -394,40 +411,58 @@ public: Signature *maybeSubstitutedFunctionSig = nullptr); void InferTypesForLambda(ir::ScriptFunction *lambda, Signature *signature); 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, + bool CheckLambdaTypeAnnotation(ir::ETSParameterExpression *param, ir::ArrowFunctionExpression *arrowFuncExpr, Type *parameterType, TypeRelationFlag flags); bool CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr, Type *const subParameterType); 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()); - } - Substitution *CopySubstitution(const Substitution *src) + + ArenaSubstitution *NewArenaSubstitution() { - return Allocator()->New(*src); + return ProgramAllocator()->New(ProgramAllocator()->Adapter()); } + 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); + + static Substitution ArenaSubstitutionToSubstitution(const ArenaSubstitution *orig); void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg); + void EmplaceSubstituted(ArenaSubstitution *substitution, ETSTypeParameter *tparam, Type *typeArg); + [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForReadonly(const ArenaVector &typeParams, ETSReadonlyType *paramType, Type *argumentType, Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionForPartialTypeParam(const ArenaVector &typeParams, + ETSPartialTypeParameter *paramType, Type *argumentType, + Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector &typeParams, ETSObjectType *paramType, Type *argumentType, Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionTypeParameter(ETSTypeParameter *paramType, Type *argumentType, + Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionForNonNullish(const ArenaVector &typeParams, + ETSNonNullishType *paramType, Type *argumentType, + Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForFunction(const ArenaVector &typeParams, ETSFunctionType *paramType, Type *argumentType, Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionForAwaited(const ArenaVector &typeParams, ETSAwaitedType *paramType, + Type *argumentType, Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForUnion(const ArenaVector &typeParams, ETSUnionType *paramUn, 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); @@ -444,13 +479,39 @@ public: bool ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, std::size_t index, TypeRelationFlag flags); bool CheckOptionalLambdaFunction(ir::Expression *argument, Signature *substitutedSig, std::size_t index); - bool ValidateArgumentAsIdentifier(const ir::Identifier *identifier); bool IsValidRestArgument(ir::Expression *argument, Signature *substitutedSig, TypeRelationFlag flags, std::size_t index); + bool SetPreferredTypeForArrayArgument(ir::ArrayExpression *arrayExpr, Signature *substitutedSig); bool ValidateSignatureRestParams(Signature *substitutedSig, const ArenaVector &arguments, TypeRelationFlag flags, bool reportError, bool unique); - void ThrowSignatureMismatch(ArenaVector &signatures, const ArenaVector &arguments, - const lexer::SourcePosition &pos, std::string_view signatureKind); + void ThrowSignatureMismatch(ArenaVector const &signatures, + const ArenaVector &arguments, const lexer::SourcePosition &pos, + std::string_view signatureKind); + Signature *FirstMatchSignatures(ir::CallExpression *expr, checker::Type *calleeType); + Signature *MatchOrderSignatures(ArenaVector &signatures, + const ir::TSTypeParameterInstantiation *typeArguments, + const ArenaVector &arguments, const lexer::SourcePosition &pos, + TypeRelationFlag resolveFlags); + void CleanArgumentsInformation(const ArenaVector &arguments); + Signature *ValidateOrderSignature( + std::tuple info, + const ArenaVector &arguments, const lexer::SourcePosition &pos, + const std::vector &argTypeInferenceRequired, const bool unique); + bool ValidateOrderSignatureRequiredParams(Signature *substitutedSig, const ArenaVector &arguments, + TypeRelationFlag flags, + const std::vector &argTypeInferenceRequired); + bool ValidateOrderSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, std::size_t index, + TypeRelationFlag flags); + void ThrowOverloadMismatch(util::StringView callName, const ArenaVector &arguments, + const lexer::SourcePosition &pos, std::string_view signatureKind); + Signature *ResolveTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, + const lexer::SourcePosition &pos, + TypeRelationFlag reportFlag = TypeRelationFlag::NONE); + Signature *ResolvePotentialTrailingLambda(ir::CallExpression *callExpr, ArenaVector const &signatures, + ArenaVector &arguments); + bool SetPreferredTypeBeforeValidate(Signature *substitutedSig, ir::Expression *argument, size_t index, + TypeRelationFlag flags, const std::vector &argTypeInferenceRequired); + // CC-OFFNXT(G.FUN.01-CPP) solid logic Signature *ValidateSignatures(ArenaVector &signatures, const ir::TSTypeParameterInstantiation *typeArguments, @@ -463,6 +524,8 @@ public: void SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType); + void CheckAmbiguousCall(Type *&mostSpecificType, Type *sigType, Signature *prevSig, Signature *sig, + const lexer::SourcePosition &pos); void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, ArenaMultiMap &bestSignaturesForParameter, const ArenaVector &arguments); @@ -476,6 +539,7 @@ public: Signature *ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpression *callExpr, ArenaVector const &signatures, ArenaVector &arguments); + Signature *MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr); Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, TypeRelationFlag reportFlag = TypeRelationFlag::NONE); @@ -496,8 +560,8 @@ public: Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef); bool CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *currentFunc, bool omitSameAsm = false); - static bool CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept; + const ir::MethodDefinition *currentFunc, bool omitSameAsm = false, + TypeRelationFlag relationFlags = TypeRelationFlag::NO_RETURN_TYPE_CHECK); static bool HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept; static bool HasSameAssemblySignatures(ETSFunctionType const *const func1, ETSFunctionType const *const func2) noexcept; @@ -529,9 +593,9 @@ public: void ReplaceScope(ir::AstNode *root, ir::AstNode *oldNode, varbinder::Scope *newScope); // Helpers + std::string FunctionalInterfaceInvokeName(size_t arity, bool hasRest); static std::string GetAsyncImplName(const util::StringView &name); static std::string GetAsyncImplName(ir::MethodDefinition *asyncMethod); - static bool IsAsyncImplMethod(ir::MethodDefinition const *method); std::vector GetNameForSynteticObjectType(const util::StringView &source); template void BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleObjType, ir::ETSImportDeclaration *importDecl, @@ -541,6 +605,7 @@ public: const util::StringView &importPath); void SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjType, const util::StringView &importPath, ir::ETSImportDeclaration *importDecl = nullptr); + parser::Program *SelectEntryOrExternalProgram(varbinder::ETSBinder *etsBinder, const util::StringView &importPath); void SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjectType *moduleObjType); Type *GetReferencedTypeFromBase(Type *baseType, ir::Expression *name); Type *GetReferencedTypeBase(ir::Expression *name); @@ -558,18 +623,26 @@ 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; + 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); - bool ValidateAnnotationPropertyType(checker::Type *tsType); - void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const; + void ValidateUnaryOperatorOperand(varbinder::Variable *variable, ir::Expression *expr); 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); + + template + void CheckAnnotations(ir::AnnotationAllowed *node) + { + if (node->HasAnnotations()) { + CheckAnnotations(node->Annotations()); + } + } + void CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir::AnnotationDeclaration *annoDecl); bool CheckAmbientAnnotationFieldInitializerValue(ir::Expression *init, ir::Expression *expected); bool CheckAmbientAnnotationFieldInitializer(ir::Expression *init, ir::Expression *expected); @@ -580,18 +653,15 @@ public: void CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::AnnotationDeclaration *annoDecl); void CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util::StringView const &baseName, ArenaUnorderedMap &fieldMap); + void InferLambdaInAssignmentExpression(ir::AssignmentExpression *const expr); void InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init); checker::Type *ApplyConditionalOperatorPromotion(checker::ETSChecker *checker, checker::Type *unboxedL, checker::Type *unboxedR); - Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true, - bool isCondExpr = false); + Type *ApplyUnaryOperatorPromotion(ir::Expression *expr, Type *type, bool isCondExpr = false); + Type *GetUnaryOperatorPromotedType(Type *type, const bool doPromotion = true); Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType); - bool HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, - checker::Type *leftType); - - checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags, - ir::Expression *init); + checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags); void CheckEnumType(ir::Expression *init, checker::Type *initType, const util::StringView &varName); checker::Type *CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, ir::ModifierFlags flags); @@ -623,11 +693,7 @@ public: Type *MaybeUnboxInRelation(Type *objectType); Type *MaybeUnboxConditionalInRelation(Type *objectType); Type *MaybeBoxInRelation(Type *objectType); - void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType); - ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType); - ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const; Type *MaybeBoxExpression(ir::Expression *expr); - Type *MaybeUnboxExpression(ir::Expression *expr); Type *MaybeBoxType(Type *type) const; Type *MaybeUnboxType(Type *type) const; Type const *MaybeBoxType(Type const *type) const; @@ -637,21 +703,22 @@ public: bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue); void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, const lexer::SourcePosition &pos); - std::string GetStringFromLiteral(ir::Expression *caseTest) const; - varbinder::Variable *FindVariableInFunctionScope(util::StringView name); + varbinder::Variable *FindVariableInFunctionScope( + util::StringView name, const varbinder::ResolveBindingOptions options = varbinder::ResolveBindingOptions::ALL); std::pair FindVariableInClassOrEnclosing( util::StringView name, const ETSObjectType *classType); - varbinder::Variable *FindVariableInGlobal(const ir::Identifier *identifier); + varbinder::Variable *FindVariableInGlobal( + const ir::Identifier *identifier, + const varbinder::ResolveBindingOptions options = varbinder::ResolveBindingOptions::ALL); varbinder::Variable *ExtraCheckForResolvedError(ir::Identifier *ident); void ValidateResolvedIdentifier(ir::Identifier *ident); static bool IsVariableStatic(const varbinder::Variable *var); static bool IsVariableGetterSetter(const varbinder::Variable *var); static bool IsVariableExtensionAccessor(const varbinder::Variable *var); + static bool IsVariableOverloadDeclaration(const varbinder::Variable *var); bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare); void SaveCapturedVariable(varbinder::Variable *var, ir::Identifier *ident); bool SaveCapturedVariableInLocalClass(varbinder::Variable *var, ir::Identifier *ident); - void MaybeAddBoxingFlagInRelation(TypeRelation *relation, Type *target); - void MaybeAddUnboxingFlagInRelation(TypeRelation *relation, Type *source, Type *self); void CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self); void CheckUnboxedTypesAssignable(TypeRelation *relation, Type *source, Type *target); void CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target); @@ -666,6 +733,12 @@ public: ir::BlockStatement *FindFinalizerOfTryStatement(ir::AstNode *startFrom, const ir::AstNode *p); void CheckExceptionClauseType(const std::vector &exceptions, ir::CatchClause *catchClause, checker::Type *clauseType); + + void CheckConstructorOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const; + void CheckFunctionOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const; + void CheckClassMethodOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const; + void CheckInterfaceMethodOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const; + ETSObjectType *GetRelevantArgumentedTypeFromChild(ETSObjectType *child, ETSObjectType *target); util::StringView GetHashFromTypeArguments(const ArenaVector &typeArgTypes); util::StringView GetHashFromSubstitution(const Substitution *substitution, const bool isExtensionFuncFlag); @@ -676,7 +749,7 @@ public: bool IsExtensionAccessorFunctionType(const checker::Type *type); bool IsArrayExprSizeValidForTuple(const ir::ArrayExpression *arrayExpr, const ETSTupleType *tuple); void ModifyPreferredType(ir::ArrayExpression *arrayExpr, Type *newPreferredType); - Type *SelectGlobalIntegerTypeForNumeric(Type *type); + Type *SelectGlobalIntegerTypeForNumeric(Type *type) const; ir::ClassProperty *ClassPropToImplementationProp(ir::ClassProperty *classProp, varbinder::ClassScope *scope); ir::Expression *GenerateImplicitInstantiateArg(const std::string &className); @@ -696,7 +769,6 @@ public: void ETSObjectTypeDeclNode(ETSChecker *checker, ETSObjectType *const objectType); ir::CallExpression *CreateExtensionAccessorCall(ETSChecker *checker, ir::MemberExpression *expr, ArenaVector &&args); - static void SetPreferredTypeIfPossible(ir::Expression *expr, Type *targetType); Signature *FindRelativeExtensionGetter(ir::MemberExpression *const expr, ETSFunctionType *funcType); Signature *FindRelativeExtensionSetter(ir::MemberExpression *const expr, ETSFunctionType *funcType); Type *GetExtensionAccessorReturnType(ir::MemberExpression *expr); @@ -743,6 +815,11 @@ public: // Readonly Type *GetReadonlyType(Type *type); void MakePropertiesReadonly(ETSObjectType *classType); + // Awaited + Type *HandleAwaitedUtilityType(Type *typeToBeAwaited); + Type *HandleAwaitExpression(Type *typeToBeAwaited, ir::AwaitExpression *expr); + Type *UnwrapPromiseType(checker::Type *type); + bool IsPromiseType(Type *type); // Required Type *HandleRequiredType(Type *typeToBeRequired); void MakePropertiesNonNullish(ETSObjectType *classType); @@ -750,15 +827,17 @@ public: void MakePropertyNonNullish(ETSObjectType *classType, varbinder::LocalVariable *prop); void ValidateObjectLiteralForRequiredType(const ETSObjectType *requiredType, const ir::ObjectExpression *initObjExpr); + bool IsStaticInvoke(ir::MemberExpression *const expr); + void ValidateCallExpressionIdentifier(ir::Identifier *const ident, Type *const type); using NamedAccessMeta = std::tuple; static NamedAccessMeta FormNamedAccessMetadata(varbinder::Variable const *prop); // Smart cast support - [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType); + [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, + std::optional value = std::nullopt); [[nodiscard]] std::pair CheckTestNullishCondition(Type *testedType, Type *actualType, bool strict); - [[nodiscard]] std::pair CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType, - bool strict); + [[nodiscard]] std::pair CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType); [[nodiscard]] std::pair CheckTestObjectCondition(ETSArrayType *testedType, Type *actualType); void ApplySmartCast(varbinder::Variable const *variable, checker::Type *smartType) noexcept; @@ -770,15 +849,6 @@ public: static Type *TryToInstantiate(Type *type, ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); - // Dynamic interop - template - Signature *ResolveDynamicCallExpression(ir::Expression *callee, const ArenaVector &arguments, Language lang, - bool isConstruct); - ir::ClassProperty *CreateStaticReadonlyField(const char *name); - void BuildClassBodyFromDynamicImports(const ArenaVector &dynamicImports, - ArenaVector *classBody); - void BuildDynamicImportClass(); - void BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir::TypeNode *retTypeAnnotation); // Trailing lambda void EnsureValidCurlyBrace(ir::CallExpression *callExpr); @@ -800,16 +870,6 @@ public: void ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType, ir::ScriptFunction *containingFunc, ir::ReturnStatement *st); - auto *DynamicCallNames(bool isConstruct) - { - return &dynamicCallNames_[static_cast(isConstruct)]; - } - - const auto *DynamicCallNames(bool isConstruct) const - { - return &dynamicCallNames_[static_cast(isConstruct)]; - } - std::recursive_mutex *Mutex() { return &mtx_; @@ -822,7 +882,14 @@ public: return util::NodeAllocator::ForceSetParent(Allocator(), std::forward(args)...); } - ArenaVector &PendingConstraintCheckRecords(); + template + T *ProgramAllocNode(Args &&...args) + { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return util::NodeAllocator::ForceSetParent(ProgramAllocator(), std::forward(args)...); + } + + std::vector &PendingConstraintCheckRecords(); size_t &ConstraintCheckScopesCount(); ETSObjectType *GetCachedFunctionalInterface(ir::ETSFunctionType *type); @@ -847,9 +914,11 @@ public: ir::MethodDefinition *CreateClassMethod(std::string_view name, ir::ScriptFunctionFlags funcFlags, ir::ModifierFlags modifierFlags, const MethodBuilder &builder); ir::ClassDeclaration *BuildClass(util::StringView name, const ClassBuilder &builder); + const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr); void LogUnresolvedReferenceError(ir::Identifier *ident); void WrongContextErrorClassifyByType(ir::Identifier *ident); + Type *CreateSyntheticTypeFromOverload(varbinder::Variable *const var); void CreateOverloadSigContainer(Signature *overloadHelperSig) { @@ -866,6 +935,26 @@ public: return overloadSigContainer_; } + ObjectInstantiationMap &GetObjectInstantiationMap() + { + return objectInstantiationMap_; + } + + FunctionSignatureMap &GetInvokeToArrowSignatures() + { + return invokeToArrowSignatures_; + } + + FunctionInterfaceMap &GetArrowToFuncInterfaces() + { + return arrowToFuncInterfaces_; + } + + void ClearApparentTypes() noexcept + { + apparentTypes_.clear(); + } + void CleanUp() override { Checker::CleanUp(); @@ -873,34 +962,46 @@ public: pendingConstraintCheckRecords_.clear(); constraintCheckScopesCount_ = 0; globalArraySignatures_.clear(); - cachedComputedAbstracts_.clear(); - for (auto &dynamicCallIntrinsicsMap : dynamicIntrinsics_) { - dynamicCallIntrinsicsMap.clear(); - } - - for (auto &dynamicClassIntrinsicsMap : dynamicClasses_) { - dynamicClassIntrinsicsMap.clear(); - } - dynamicLambdaSignatureCache_.clear(); + unionAssemblerTypes_.clear(); + GetCachedComputedAbstracts()->clear(); functionalInterfaceCache_.clear(); apparentTypes_.clear(); - for (auto &dynamicCallNamesMap : dynamicCallNames_) { - dynamicCallNamesMap.clear(); - } elementStack_.clear(); overloadSigContainer_.clear(); } // This helper finds the intersection of two callSignatures sets - // The result is stored in callSignatures of newly created ETSFunctionType + // 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, const ETSObjectType *classType); - void ValidateCallExpressionIdentifier(ir::Identifier *const ident, Type *const type); void ValidateNewClassInstanceIdentifier(ir::Identifier *const ident); void ValidateMemberIdentifier(ir::Identifier *const ident); void ValidateAssignmentIdentifier(ir::Identifier *const ident, Type *const type); @@ -918,14 +1019,15 @@ private: std::tuple IsResolvedAndValue(const ir::Expression *expr, Type *type) const; PropertySearchFlags GetSearchFlags(const ir::MemberExpression *memberExpr, const varbinder::Variable *targetRef); PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr); - const varbinder::Variable *GetTargetRef(const ir::MemberExpression *memberExpr); Type *GetTypeOfSetterGetter([[maybe_unused]] varbinder::Variable *var); - void IterateInVariableContext([[maybe_unused]] varbinder::Variable *const var); + SavedCheckerContext CreateSavedCheckerContext(varbinder::Variable *const var); bool CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, checker::Type *annotationType, varbinder::Variable *const bindingVar); void CheckItemCasesConstant(ArenaVector const &cases); void CheckItemCasesDuplicate(ArenaVector const &cases); + void CheckAnnotations(const ArenaVector &annotations); + template EnumType *CreateEnumTypeFromEnumDeclaration(ir::TSEnumDeclaration const *const enumDecl); @@ -933,27 +1035,6 @@ private: ClassInitializerBuilder const &builder); std::pair CreateScriptFunction(ClassInitializerBuilder const &builder); - template - ir::MethodDefinition *CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector &arguments, - Language lang); - ir::ClassStaticBlock *CreateDynamicCallClassInitializer(Language lang, bool isConstruct); - ir::ClassStaticBlock *CreateDynamicModuleClassInitializer(const std::vector &imports); - ir::MethodDefinition *CreateDynamicModuleClassInitMethod(); - - ir::MethodDefinition *CreateLambdaObjectClassInitializer(ETSObjectType *functionalInterface); - - ir::MethodDefinition *CreateLambdaObjectClassInvokeMethod(Signature *invokeSignature, - ir::TypeNode *retTypeAnnotation); - - void ClassInitializerFromImport(ir::ETSImportDeclaration *import, ArenaVector *statements); - void EmitDynamicModuleClassInitCall(); - DynamicCallIntrinsicsMap *DynamicCallIntrinsics(bool isConstruct) - { - return &dynamicIntrinsics_[static_cast(isConstruct)]; - } - - ir::ClassDeclaration *GetDynamicClass(Language lang, bool isConstruct); - using Type2TypeMap = std::unordered_map; using TypeSet = std::unordered_set; bool CheckTypeParameterConstraint(ir::TSTypeParameter *param, Type2TypeMap &extends); @@ -961,6 +1042,7 @@ private: void SetUpTypeParameterConstraint(ir::TSTypeParameter *param); ETSObjectType *UpdateGlobalType(ETSObjectType *objType, util::StringView name); + void WrapTypeNode(ir::AstNode *node); void CheckProgram(parser::Program *program, bool runAnalysis = false); void CheckWarnings(parser::Program *program, const util::Options &options); @@ -968,15 +1050,6 @@ private: bool ComputeSuperType(ETSObjectType *type); - template - UType HandleModulo(UType leftValue, UType rightValue); - - template - Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType); - - template - typename TargetType::UType GetOperand(Type *type); - template ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const; Signature *GetMostSpecificSignature(ArenaVector &compatibleSignatures, @@ -988,10 +1061,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 *ident, ir::Identifier *classId, ir::Identifier *methodId, + ir::CallExpression *callExpr); bool TryTransformingToStaticInvoke(ir::Identifier *ident, const Type *resolvedType); // Partial @@ -1008,21 +1086,22 @@ private: std::unordered_set &typeAliases); ArrayMap arrayTypes_; - ArenaVector pendingConstraintCheckRecords_; + std::vector pendingConstraintCheckRecords_ {}; + ObjectInstantiationMap objectInstantiationMap_; + FunctionSignatureMap invokeToArrowSignatures_; + FunctionInterfaceMap arrowToFuncInterfaces_; size_t constraintCheckScopesCount_ {0}; GlobalArraySignatureMap globalArraySignatures_; - ComputedAbstracts cachedComputedAbstracts_; - // NOTE(aleksisch): Extract dynamic from checker to separate class - std::array dynamicIntrinsics_; - std::array dynamicClasses_; - DynamicLambdaObjectSignatureMap dynamicLambdaSignatureCache_; + ArenaSet unionAssemblerTypes_; + ComputedAbstracts *cachedComputedAbstracts_ {nullptr}; FunctionalInterfaceMap functionalInterfaceCache_; TypeMapping apparentTypes_; - std::array dynamicCallNames_; std::recursive_mutex mtx_; evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr}; std::unordered_set elementStack_; ArenaVector overloadSigContainer_; + ArenaSet readdedChecker_; + bool permitRelaxedAny_ {false}; }; } // namespace ark::es2panda::checker 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..1126ba93c03b19140c9f8c2a5b66671fcfd2a0d1 100644 --- a/ets2panda/checker/SemanticAnalyzer.h +++ b/ets2panda/checker/SemanticAnalyzer.h @@ -27,6 +27,7 @@ #include "ir/base/decorator.h" #include "ir/base/metaProperty.h" #include "ir/base/methodDefinition.h" +#include "ir/base/overloadDeclaration.h" #include "ir/base/property.h" #include "ir/base/scriptFunction.h" #include "ir/base/spreadElement.h" @@ -37,9 +38,9 @@ #include "ir/base/tsSignatureDeclaration.h" #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsFunctionType.h" +#include "ir/ets/etsIntrinsicNode.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 +50,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 cfaad3f534778bcc113cfa6f35b12ba77bdffdfb..655c154d5f62250d0c9fb34c1864a88a80a7bb09 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -74,6 +74,7 @@ checker::Type *TSAnalyzer::Check(ir::TSIndexSignature *node) const checker::ObjectDescriptor *desc = checker->Allocator()->New(checker->Allocator()); checker::ObjectType *placeholder = checker->Allocator()->New(desc); + ES2PANDA_ASSERT(placeholder != nullptr); if (node->Kind() == ir::TSIndexSignature::TSIndexSignatureKind::NUMBER) { placeholder->Desc()->numberIndexInfo = info; } else { @@ -107,6 +108,7 @@ checker::Type *TSAnalyzer::Check(ir::TSMethodSignature *node) const } returnType->Check(checker); + ES2PANDA_ASSERT(callSignature != nullptr); callSignature->SetReturnType(returnType->GetType(checker)); return nullptr; @@ -280,12 +282,13 @@ checker::Type *TSAnalyzer::Check(ir::ArrayExpression *expr) const util::StringView memberIndex = util::Helpers::ToStringView(checker->Allocator(), index); varbinder::LocalVariable *tupleMember = varbinder::Scope::CreateVar( checker->Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY, nullptr); - + ES2PANDA_ASSERT(tupleMember != nullptr); if (inConstContext) { tupleMember->AddFlag(varbinder::VariableFlags::READONLY); } tupleMember->SetTsType(*it); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(tupleMember); } @@ -326,7 +329,7 @@ checker::Type *TSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const if (funcVar != nullptr && funcVar->TsType() == nullptr) { funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(checker->HandleFunctionReturn(expr->Function())); if (!expr->Function()->Body()->IsExpression()) { @@ -569,7 +572,7 @@ checker::Type *TSAnalyzer::Check(ir::FunctionExpression *expr) const if (funcVar != nullptr && funcVar->TsType() == nullptr) { funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(checker->HandleFunctionReturn(expr->Function())); expr->Function()->Body()->Check(checker); @@ -787,6 +790,7 @@ void TSAnalyzer::CheckNonComputed(checker::ObjectDescriptor *desc, ir::Expressio auto *memberVar = varbinder::Scope::CreateVar(checker->Allocator(), propName, flags, it); + ES2PANDA_ASSERT(memberVar != nullptr); if (inConstContext) { memberVar->AddFlag(varbinder::VariableFlags::READONLY); } else { @@ -798,7 +802,7 @@ void TSAnalyzer::CheckNonComputed(checker::ObjectDescriptor *desc, ir::Expressio if (prop->Key()->IsNumberLiteral()) { memberVar->AddFlag(varbinder::VariableFlags::NUMERIC_NAME); } - + ES2PANDA_ASSERT(desc != nullptr); varbinder::LocalVariable *foundMember = desc->FindProperty(propName); allPropertiesMap.insert({propName, it->Start()}); @@ -876,6 +880,7 @@ checker::Type *TSAnalyzer::Check(ir::ObjectExpression *expr) const } checker::Type *returnType = checker->Allocator()->New(desc); + ES2PANDA_ASSERT(returnType != nullptr); returnType->AsObjectType()->AddObjectFlag(checker::ObjectFlags::RESOLVED_MEMBERS | checker::ObjectFlags::CHECK_EXCESS_PROPS); return returnType; @@ -1342,6 +1347,7 @@ static void CheckSimpleVariableDeclaration(checker::TSChecker *checker, ir::Vari initializerType = checker->GetBaseTypeOfLiteralType(initializerType); } + ES2PANDA_ASSERT(initializerType != nullptr); if (initializerType->IsNullType()) { checker->ThrowTypeError( {"Cannot infer type for variable '", declarator->Id()->AsIdentifier()->Name(), "'."}, @@ -1729,10 +1735,12 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, if (res == nullptr) { auto *decl = checker->Allocator()->New(memberStr); + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(variable->Declaration()->Node()); enumScope->AddDecl(checker->Allocator(), decl, ScriptExtension::TS); res = enumScope->FindLocal(memberStr, varbinder::ResolveBindingOptions::BINDINGS); ES2PANDA_ASSERT(res && res->IsEnumVariable()); + ES2PANDA_ASSERT(enumVar != nullptr); enumVar = res->AsEnumVariable(); enumVar->AsEnumVariable()->SetBackReference(); enumVar->SetTsType(checker->GlobalStringType()); @@ -1740,6 +1748,7 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, ES2PANDA_ASSERT(res->IsEnumVariable()); enumVar = res->AsEnumVariable(); auto *decl = checker->Allocator()->New(memberStr); + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(variable->Declaration()->Node()); enumVar->ResetDecl(decl); } @@ -1846,6 +1855,7 @@ checker::Type *TSAnalyzer::Check(ir::TSEnumDeclaration *st) const if (enumVar->TsType() == nullptr) { checker::ScopeContext scopeCtx(checker, st->Scope()); checker::Type *enumType = InferType(checker, st->IsConst(), st); + ES2PANDA_ASSERT(enumType != nullptr); enumType->SetVariable(enumVar); enumVar->SetTsType(enumType); } @@ -1953,6 +1963,7 @@ checker::Type *TSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker->Allocator()->New(checker->Allocator()); resolvedType = checker->Allocator()->New(checker->Allocator(), st->Id()->Name(), desc); + ES2PANDA_ASSERT(resolvedType != nullptr); resolvedType->SetVariable(var); var->SetTsType(resolvedType); } diff --git a/ets2panda/checker/TSAnalyzerUnreachable.cpp b/ets2panda/checker/TSAnalyzerUnreachable.cpp index 2d555f09ed85d26bd9ddd084cde1517ffff37f74..43a987d1cbef1363bed34d02767b82d326bec5b8 100644 --- a/ets2panda/checker/TSAnalyzerUnreachable.cpp +++ b/ets2panda/checker/TSAnalyzerUnreachable.cpp @@ -48,6 +48,11 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::MethodDefinition *node) co ES2PANDA_UNREACHABLE(); } +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::OverloadDeclaration *node) const +{ + ES2PANDA_UNREACHABLE(); +} + checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const { ES2PANDA_UNREACHABLE(); @@ -84,12 +89,12 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSFunctionType *node) con ES2PANDA_UNREACHABLE(); } -checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSIntrinsicNode *node) const { ES2PANDA_UNREACHABLE(); } -checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSLaunchExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node) const { ES2PANDA_UNREACHABLE(); } @@ -144,6 +149,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..77756cb4891aa666dcdf36041f559260a12ff917 100644 --- a/ets2panda/checker/TSchecker.h +++ b/ets2panda/checker/TSchecker.h @@ -101,7 +101,7 @@ class TSMethodSignature; class ChainExpression; class VariableDeclarator; -enum class AstNodeType; +enum class AstNodeType : uint8_t; } // namespace ark::es2panda::ir namespace ark::es2panda::checker { @@ -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 79ca7ea09915d770b560d2c1113354a759fe2b7e..ab4e17a2e079d1182cf78b6a0e32ecc6eedbaa1d 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) @@ -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) @@ -166,6 +164,11 @@ bool Checker::IsAnyError() return DiagnosticEngine().IsAnyError(); } +bool Checker::IsDeclForDynamicStaticInterop() const +{ + return Program()->IsDeclForDynamicStaticInterop(); +} + ScopeContext::ScopeContext(Checker *checker, varbinder::Scope *newScope) : checker_(checker), prevScope_(checker_->scope_), prevProgram_(checker_->Program()) { @@ -180,14 +183,16 @@ 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); - identicalResults_.cached.clear(); - assignableResults_.cached.clear(); - comparableResults_.cached.clear(); - uncheckedCastableResults_.cached.clear(); - supertypeResults_.cached.clear(); + relation_ = allocator_->New(this); + identicalResults_.Clear(); + assignableResults_.Clear(); + comparableResults_.Clear(); + uncheckedCastableResults_.Clear(); + supertypeResults_.Clear(); typeStack_.clear(); namedTypeStack_.clear(); } diff --git a/ets2panda/checker/checker.h b/ets2panda/checker/checker.h index 6720cd4f1305f313c68bf21412365ce315c4292e..d7466fb0d418ece598f7f6319d2b61f1e64a4e9a 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 { @@ -32,7 +33,7 @@ namespace ark::es2panda::ir { class AstNode; class Expression; class BlockStatement; -enum class AstNodeType; +enum class AstNodeType : uint8_t; } // namespace ark::es2panda::ir namespace ark::es2panda::varbinder { @@ -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_; @@ -171,8 +184,13 @@ public: 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 Warning(std::string_view message, const lexer::SourcePosition &pos) const; - void ReportWarning(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); + void LogTypeError(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 diagnostic::DiagnosticKind &diagKind, @@ -216,14 +234,22 @@ public: virtual void CleanUp(); + [[nodiscard]] ThreadSafeArenaAllocator *ProgramAllocator() + { + return programAllocator_ == nullptr ? allocator_ : programAllocator_; + } + + bool IsDeclForDynamicStaticInterop() const; + 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_ {}; @@ -231,11 +257,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()}; + RelationHolder assignableResults_ {Allocator()}; + RelationHolder comparableResults_ {Allocator()}; + RelationHolder uncheckedCastableResults_ {Allocator()}; + RelationHolder supertypeResults_ {Allocator()}; std::unordered_map typeStack_; std::unordered_set namedTypeStack_; @@ -262,8 +288,9 @@ private: class TypeStackElement { public: - explicit TypeStackElement(Checker *checker, void *element, const std::optional &diag, - const lexer::SourcePosition &pos, bool isRecursive = false) + explicit TypeStackElement(Checker *checker, const void *element, + const std::optional &diag, const lexer::SourcePosition &pos, + bool isRecursive = false) : checker_(checker), element_(element), isRecursive_(isRecursive) { if (!checker->typeStack_.insert({element, nullptr}).second) { @@ -309,7 +336,7 @@ public: private: Checker *checker_; - void *element_; + const void *element_; bool hasErrorChecker_ {false}; bool isRecursive_; bool cleanup_ {true}; @@ -457,6 +484,88 @@ private: Type *type_ {}; }; +class SignatureMatchContext { +public: + explicit SignatureMatchContext(Checker *checker, util::DiagnosticType diagnosticKind, bool isLogError = true) + : diagnosticEngine_(checker->DiagnosticEngine()), + diagnosticCheckpoint_(), + diagnosticKind_(diagnosticKind), + isLogError_(isLogError) + { + diagnosticCheckpoint_ = diagnosticEngine_.Save(); + } + + bool ValidSignatureMatchStatus() + { + std::array diagnosticCheckpoint = diagnosticEngine_.Save(); + return diagnosticCheckpoint_[diagnosticKind_] == diagnosticCheckpoint[diagnosticKind_]; + } + + ~SignatureMatchContext() + { + if (isLogError_) { + return; + } + + diagnosticEngine_.Rollback(diagnosticCheckpoint_); + } + + NO_COPY_SEMANTIC(SignatureMatchContext); + NO_MOVE_SEMANTIC(SignatureMatchContext); + +private: + util::DiagnosticEngine &diagnosticEngine_; + std::array diagnosticCheckpoint_; + util::DiagnosticType diagnosticKind_; + bool isLogError_; +}; + +class SignatureCollectContext { +public: + explicit SignatureCollectContext(Checker *checker, varbinder::LocalVariable *overloadDeclaration, + bool isCreateSyntheticVar = false) + : checker_(checker), isCreateSyntheticVar_(isCreateSyntheticVar) + { + preOverloadDeclaration_ = checker_->Context().ContainingOverloadDeclaration() != nullptr + ? checker_->Context().ContainingOverloadDeclaration()->AsLocalVariable() + : nullptr; + checker_->Context().SetContainingOverloadDeclaration(overloadDeclaration); + } + + bool IsOverloadDeclarationCall() + { + return checker_->Context().ContainingOverloadDeclaration() != nullptr; + } + + varbinder::LocalVariable *CreateSyntheticVar(ThreadSafeArenaAllocator *const allocator) + { + varbinder::VariableFlags variableFlags = + IsOverloadDeclarationCall() ? varbinder::VariableFlags::SYNTHETIC | varbinder::VariableFlags::METHOD | + varbinder::VariableFlags::OVERLOAD + : varbinder::VariableFlags::SYNTHETIC | varbinder::VariableFlags::METHOD; + varbinder::LocalVariable *syntheticVar = allocator->New(variableFlags); + return syntheticVar; + } + + ~SignatureCollectContext() + { + if (isCreateSyntheticVar_ && syntheticVar_ != nullptr) { + syntheticVar_->Reset(checker_->Context().ContainingOverloadDeclaration()->Declaration(), + syntheticVar_->Flags()); + checker_->Context().SetContainingOverloadDeclaration(preOverloadDeclaration_); + } + } + + NO_COPY_SEMANTIC(SignatureCollectContext); + NO_MOVE_SEMANTIC(SignatureCollectContext); + +private: + Checker *checker_; + bool isCreateSyntheticVar_; + varbinder::LocalVariable *preOverloadDeclaration_; + varbinder::LocalVariable *syntheticVar_ = nullptr; +}; + } // namespace ark::es2panda::checker #endif /* CHECKER_H */ diff --git a/ets2panda/checker/checkerContext.cpp b/ets2panda/checker/checkerContext.cpp index a71ce444760e3a7265daec87290db0a9fdeb36d2..fa10d82fac4f1bb494e247289620832e0fec818f 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}; } } @@ -456,10 +473,6 @@ void CheckerContext::OnBreakStatement(ir::BreakStatement const *breakStatement) status_ |= CheckerStatus::MEET_BREAK; - if (smartCasts_.empty()) { - return; - } - SmartCastArray smartCasts {}; smartCasts.reserve(smartCasts_.size()); @@ -469,9 +482,7 @@ void CheckerContext::OnBreakStatement(ir::BreakStatement const *breakStatement) } } - if (!smartCasts.empty()) { - AddBreakSmartCasts(targetStatement, std::move(smartCasts)); - } + AddBreakSmartCasts(targetStatement, std::move(smartCasts)); ClearSmartCasts(); } @@ -483,7 +494,8 @@ void CheckerContext::AddBreakSmartCasts(ir::Statement const *targetStatement, Sm void CheckerContext::CombineBreakSmartCasts(ir::Statement const *targetStatement) { - ES2PANDA_ASSERT(smartCasts_.empty()); + ES2PANDA_ASSERT((targetStatement->IsSwitchStatement() && targetStatement->AsSwitchStatement()->Cases().empty()) || + smartCasts_.empty()); if (!breakSmartCasts_.empty()) { bool firstCase = true; diff --git a/ets2panda/checker/checkerContext.h b/ets2panda/checker/checkerContext.h index aa5e6b26fcdbad5213fec9eecbe6e003013339d3..1c3f8cb59cbc159b26305cd181952b77465ba865 100644 --- a/ets2panda/checker/checkerContext.h +++ b/ets2panda/checker/checkerContext.h @@ -165,6 +165,11 @@ public: return status_; } + [[nodiscard]] varbinder::Variable *ContainingOverloadDeclaration() noexcept + { + return containingOverloadDeclaration_; + } + void SetContainingSignature(Signature *containingSignature) noexcept { containingSignature_ = containingSignature; @@ -175,6 +180,11 @@ public: containingClass_ = containingClass; } + void SetContainingOverloadDeclaration(varbinder::Variable *containingOverloadDeclaration) noexcept + { + containingOverloadDeclaration_ = containingOverloadDeclaration; + } + void AddCapturedVar(varbinder::Variable *var, const lexer::SourcePosition &pos) { capturedVars_.emplace(var, pos); @@ -275,6 +285,7 @@ private: const ETSObjectType *containingClass_ {nullptr}; ir::ArrowFunctionExpression *containingLambda_ {nullptr}; Signature *containingSignature_ {nullptr}; + varbinder::Variable *containingOverloadDeclaration_ {nullptr}; lexer::TokenType operatorType_ = lexer::TokenType::EOS; SmartCastCondition testCondition_ {}; diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index a6a2282f077a6f3fa1baf9bdf153b09d1dfff553..e4edb04a7a1eadcccc752a94d25838480119604d 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -44,6 +44,7 @@ #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsStructDeclaration.h" #include "ir/ts/tsInterfaceDeclaration.h" +#include "checker/ETSAnalyzerHelpers.h" #include "checker/types/globalTypesHolder.h" #include "varbinder/variable.h" #include "varbinder/declaration.h" @@ -189,7 +190,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; } @@ -234,6 +235,7 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); if (func->Body() == nullptr || func->IsProxy()) { return; } @@ -241,20 +243,27 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) status_ = LivenessStatus::ALIVE; AnalyzeStat(func->Body()); ES2PANDA_ASSERT(methodDef->TsType() && methodDef->TsType()->IsETSFunctionType()); - const auto *returnType = methodDef->TsType()->AsETSFunctionType()->FindSignature(func)->ReturnType(); + const auto *signature = methodDef->TsType()->AsETSFunctionType()->FindSignature(func); + ES2PANDA_ASSERT(signature != nullptr); + const auto *returnType = signature->ReturnType(); const auto isVoid = returnType->IsETSVoidType() || returnType == checker_->GlobalVoidType(); auto isPromiseVoid = false; - if (returnType->IsETSAsyncFuncReturnType()) { - const auto *asAsync = returnType->AsETSAsyncFuncReturnType(); - isPromiseVoid = asAsync->GetPromiseTypeArg() == checker_->GlobalETSUndefinedType(); + if (returnType->IsETSObjectType() && + returnType->AsETSObjectType()->AssemblerName() == compiler::Signatures::BUILTIN_PROMISE) { + const auto *asAsync = returnType->AsETSObjectType(); + isPromiseVoid = asAsync->TypeArguments().front() == checker_->GlobalETSUndefinedType() || + asAsync->TypeArguments().front() == checker_->GlobalVoidType(); } - if (status_ == LivenessStatus::ALIVE && !isVoid && !isPromiseVoid && !util::Helpers::IsAsyncMethod(methodDef)) { + if (status_ == LivenessStatus::ALIVE && !isVoid && !isPromiseVoid) { + ES2PANDA_ASSERT(methodDef->Function() != nullptr); if (!methodDef->Function()->HasReturnStatement()) { - checker_->LogError(diagnostic::MISSING_RETURN_STMT, {}, func->Start()); - ClearPendingExits(); + if (!util::Helpers::IsAsyncMethod(methodDef)) { + checker_->LogError(diagnostic::MISSING_RETURN_STMT, {}, func->Start()); + ClearPendingExits(); + } return; } @@ -281,8 +290,8 @@ void AliveAnalyzer::AnalyzeDoLoop(const ir::DoWhileStatement *doWhile) AnalyzeStat(doWhile->Body()); status_ = Or(status_, ResolveContinues(doWhile)); AnalyzeNode(doWhile->Test()); - ES2PANDA_ASSERT(doWhile->Test()->TsType() && doWhile->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = doWhile->Test()->TsType()->ResolveConditionExpr(); + ES2PANDA_ASSERT(doWhile->Test()->TsType()); + const auto exprRes = IsConstantTestValue(doWhile->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || !std::get<1>(exprRes))); status_ = Or(status_, ResolveBreaks(doWhile)); } @@ -291,8 +300,8 @@ void AliveAnalyzer::AnalyzeWhileLoop(const ir::WhileStatement *whileStmt) { SetOldPendingExits(PendingExits()); AnalyzeNode(whileStmt->Test()); - ES2PANDA_ASSERT(whileStmt->Test()->TsType() && whileStmt->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = whileStmt->Test()->TsType()->ResolveConditionExpr(); + ES2PANDA_ASSERT(whileStmt->Test()->TsType()); + const auto exprRes = IsConstantTestValue(whileStmt->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || std::get<1>(exprRes))); AnalyzeStat(whileStmt->Body()); status_ = Or(status_, ResolveContinues(whileStmt)); @@ -309,9 +318,9 @@ void AliveAnalyzer::AnalyzeForLoop(const ir::ForUpdateStatement *forStmt) if (forStmt->Test() != nullptr) { AnalyzeNode(forStmt->Test()); - ES2PANDA_ASSERT(forStmt->Test()->TsType() && forStmt->Test()->TsType()->IsConditionalExprType()); + ES2PANDA_ASSERT(forStmt->Test()->TsType()); condType = forStmt->Test()->TsType(); - std::tie(resolveType, res) = forStmt->Test()->TsType()->ResolveConditionExpr(); + std::tie(resolveType, res) = IsConstantTestValue(forStmt->Test()); status_ = From(!resolveType || res); } else { status_ = LivenessStatus::ALIVE; @@ -406,7 +415,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 +467,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 3459f33a10eb3ddd9be175adde303b115c2b4cc9..b0b13c62aa6e307cb0fbd3f8452c4003ce8269b6 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -15,7 +15,8 @@ #include "arithmetic.h" -#include "checker/types/ts/nullType.h" +#include "checker/types/globalTypesHolder.h" +#include "checker/types/typeError.h" #include "lexer/token/token.h" namespace ark::es2panda::checker { @@ -28,7 +29,7 @@ struct BinaryArithmOperands { checker::Type *reducedR; }; -static inline BinaryArithmOperands GetBinaryOperands(ETSChecker *checker, ir::BinaryExpression *expr) +static BinaryArithmOperands GetBinaryOperands(ETSChecker *checker, ir::BinaryExpression *expr) { auto typeL = expr->Left()->Check(checker); auto typeR = expr->Right()->Check(checker); @@ -48,20 +49,6 @@ static void LogOperatorCannotBeApplied(ETSChecker *checker, BinaryArithmOperands LogOperatorCannotBeApplied(checker, ops.expr->OperatorType(), ops.typeL, ops.typeR, ops.expr->Start()); } -static inline void UnboxOperands(ETSChecker *checker, BinaryArithmOperands const &ops) -{ - auto const unbox = [checker](ir::Expression *expr, Type *type, Type *reducedType) { - if (type != reducedType) { - expr->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(reducedType)); - } - if (reducedType->IsETSEnumType()) { - expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } - }; - unbox(ops.expr->Left(), ops.typeL, ops.reducedL); - unbox(ops.expr->Right(), ops.typeR, ops.reducedR); -} - static inline void RepairTypeErrorsInOperands(Type **left, Type **right) { if (IsTypeError(*left)) { @@ -87,11 +74,40 @@ static inline void RepairTypeErrorWithDefault(Type **type, Type *dflt) } } -static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +static bool CheckOpArgsTypeEq(ETSChecker *checker, Type *left, Type *right, Type *type) +{ + return ((left != nullptr) && (right != nullptr) && checker->IsTypeIdenticalTo(left, type) && + checker->IsTypeIdenticalTo(right, type)); +} + +static bool FindOpArgsType(ETSChecker *checker, Type *left, Type *right, Type *target) +{ + return (checker->Relation()->IsSupertypeOf(target, left) || checker->Relation()->IsSupertypeOf(target, right)); +} + +bool ETSChecker::CheckIfNumeric(Type *type) +{ + if (type == nullptr) { + return false; + } + if (type->IsETSPrimitiveType()) { + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); + } + auto *unboxed = MaybeUnboxInRelation(type); + return (unboxed != nullptr) && unboxed->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); +} + +bool ETSChecker::CheckIfFloatingPoint(Type *type) { - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); + if (type == nullptr) { + return false; + } + auto *unboxed = MaybeUnboxInRelation(type); + return (unboxed != nullptr) && (unboxed->IsFloatType() || unboxed->IsDoubleType()); +} +static Type *EffectivePrimitiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +{ if (left->IsDoubleType() || right->IsDoubleType()) { return checker->GlobalDoubleType(); } @@ -101,7 +117,11 @@ static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *rig if (left->IsLongType() || right->IsLongType()) { return checker->GlobalLongType(); } - return checker->GlobalIntType(); + // NOTE(dkofanov): Deprecated operations on 'char' #28006 + if (left->IsCharType() && right->IsCharType()) { + return checker->GlobalCharType(); + } + return checker->GlobalIntType(); // return int in case of primitive types by default } static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) @@ -111,99 +131,81 @@ static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) } if (type->IsETSIntEnumType()) { + // Pull out the type argument to BaseEnum + if (type->AsETSObjectType()->SuperType() != nullptr && + !type->AsETSObjectType()->SuperType()->TypeArguments().empty()) { + auto *baseEnumArg = type->AsETSObjectType()->SuperType()->TypeArguments()[0]; + return checker->MaybeUnboxInRelation(baseEnumArg); + } return checker->GlobalIntType(); } + if (type->IsETSStringEnumType()) { return checker->GlobalETSStringLiteralType(); } return checker->MaybeUnboxInRelation(type); } -static std::pair BinaryCoerceToPrimitives(ETSChecker *checker, Type *left, Type *right, - bool const promote) +static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) { - Type *const unboxedL = TryConvertToPrimitiveType(checker, left); - Type *const unboxedR = TryConvertToPrimitiveType(checker, right); - if (unboxedL == nullptr || unboxedR == nullptr) { - return {nullptr, false}; - } + ES2PANDA_ASSERT(checker->CheckIfNumeric(left) && checker->CheckIfNumeric(right)); - bool const bothConst = unboxedL->IsConstantType() && unboxedR->IsConstantType(); - - if (!promote) { - return {unboxedR, bothConst}; + auto bothBoxed = left->IsETSUnboxableObject() && right->IsETSUnboxableObject(); + if (!bothBoxed) { + return EffectivePrimitiveTypeOfNumericOp(checker, left, right); } - if (unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - return {EffectiveTypeOfNumericOp(checker, unboxedL, unboxedR), bothConst}; + auto globalTypesHolder = checker->GetGlobalTypesHolder(); + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalDoubleBuiltinType())) { + return globalTypesHolder->GlobalDoubleBuiltinType(); } - return {unboxedR, bothConst}; + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalFloatBuiltinType())) { + return globalTypesHolder->GlobalFloatBuiltinType(); + } + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalLongBuiltinType())) { + return globalTypesHolder->GlobalLongBuiltinType(); + } + return globalTypesHolder->GlobalIntegerBuiltinType(); // return Int for Byte, Short, Int } -Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) +// NOTE(dkofanov): Deprecated operations on 'char' #28006 +static Type *BinaryGetPromotedType(ETSChecker *checker, Type *left, Type *right, bool const promote) { - ES2PANDA_ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - TypeFlag typeKind = ETSType(type); - Type *result = nullptr; - - switch (typeKind) { - case TypeFlag::BYTE: { - result = CreateByteType(-(type->AsByteType()->GetValue())); - break; - } - case TypeFlag::CHAR: { - result = CreateCharType(-(type->AsCharType()->GetValue())); - break; - } - case TypeFlag::SHORT: { - result = CreateShortType(-(type->AsShortType()->GetValue())); - break; - } - case TypeFlag::INT: { - result = CreateIntType(-(type->AsIntType()->GetValue())); - break; - } - case TypeFlag::LONG: { - result = CreateLongType(-(type->AsLongType()->GetValue())); - break; - } - case TypeFlag::FLOAT: { - result = CreateFloatType(-(type->AsFloatType()->GetValue())); - break; - } - case TypeFlag::DOUBLE: { - result = CreateDoubleType(-(type->AsDoubleType()->GetValue())); - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } + Type *const unboxedL = TryConvertToPrimitiveType(checker, left); + Type *const unboxedR = TryConvertToPrimitiveType(checker, right); + if (unboxedL == nullptr || unboxedR == nullptr) { + return nullptr; } - node->SetTsType(result); - return result; -} + Type *typeL = left; + Type *typeR = right; -Type *ETSChecker::HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); + bool const bothBoxed = !typeL->IsETSPrimitiveType() && !typeR->IsETSPrimitiveType(); - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformRelationOperationOnTypes(left, right, operationType); + if (!promote) { + return typeR; } - if (left->IsFloatType() || right->IsFloatType()) { - return PerformRelationOperationOnTypes(left, right, operationType); + if (!bothBoxed) { + if (unboxedL->IsETSEnumType() || unboxedR->IsETSEnumType()) { + return nullptr; + } + if (!typeL->IsETSPrimitiveType()) { + typeL = checker->MaybeUnboxType(typeL); + } + if (!typeR->IsETSPrimitiveType()) { + typeR = checker->MaybeUnboxType(typeR); + } } - if (left->IsLongType() || right->IsLongType()) { - return PerformRelationOperationOnTypes(left, right, operationType); + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR)) { + return EffectiveTypeOfNumericOp(checker, typeL, typeR); + } + if (checker->CheckIfNumeric(typeR)) { + return typeR; } - return PerformRelationOperationOnTypes(left, right, operationType); + return typeL; } bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op) @@ -212,11 +214,26 @@ bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::To return false; } - if (!left->IsETSBigIntType()) { - return false; + // Allow operations between BigInt and numeric types - number will be converted to BigInt + bool leftIsBigInt = left->IsETSBigIntType(); + bool rightIsBigInt = right->IsETSBigIntType(); + // Allow if either operand is BigInt. + // The non-BigInt operand will be converted to BigInt during lowering. + if ((leftIsBigInt && CheckIfNumeric(right)) || (rightIsBigInt && CheckIfNumeric(left))) { + switch (op) { + case lexer::TokenType::PUNCTUATOR_GREATER_THAN: + case lexer::TokenType::PUNCTUATOR_LESS_THAN: + case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: + return true; + default: + break; + } } - if (!right->IsETSBigIntType()) { + if (!leftIsBigInt || !rightIsBigInt) { return false; } @@ -226,6 +243,7 @@ bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::To case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::KEYW_INSTANCEOF: + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: // This is handled in the main CheckBinaryOperator function return false; default: @@ -250,6 +268,53 @@ bool ETSChecker::CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType return true; } +void ETSChecker::SetGenerateValueOfFlags(std::tuple types, + std::tuple nodes) +{ + auto [leftType, rightType, _, __] = types; + auto [left, right] = nodes; + if (leftType->IsETSEnumType()) { + left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + } + if (rightType->IsETSEnumType()) { + right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + } +} + +static bool TypeIsAppropriateForArithmetic(const checker::Type *type, ETSChecker *checker) +{ + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || + (type->IsETSObjectType() && + checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type)); +} + +static checker::Type *CheckBinaryOperatorForIntEnums(ETSChecker *checker, checker::Type *const leftType, + checker::Type *const rightType) +{ + if (!leftType->IsETSEnumType() && !rightType->IsETSEnumType()) { + return nullptr; + } + if (TypeIsAppropriateForArithmetic(leftType, checker) && TypeIsAppropriateForArithmetic(rightType, checker)) { + Type *leftNumeric; + if (leftType->IsETSIntEnumType()) { + leftNumeric = checker->MaybeBoxInRelation(TryConvertToPrimitiveType(checker, leftType)); + } else { + leftNumeric = leftType; + } + + Type *rightNumeric; + if (rightType->IsETSIntEnumType()) { + rightNumeric = checker->MaybeBoxInRelation(TryConvertToPrimitiveType(checker, rightType)); + } else { + rightNumeric = rightType; + } + + return EffectiveTypeOfNumericOp(checker, leftNumeric, rightNumeric); + } + + return nullptr; +} + checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types) @@ -260,22 +325,15 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( // Try to handle errors on a lower level RepairTypeErrorsInOperands(&leftType, &rightType); RepairTypeErrorsInOperands(&unboxedL, &unboxedR); - if (leftType->IsTypeError()) { // both are errors - return GlobalTypeError(); - } - - checker::Type *tsType {}; - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); + ERROR_TYPE_CHECK(this, leftType, return GlobalTypeError()); + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - auto type = CheckBinaryOperatorForIntEnums(leftType, rightType); + if (promotedType == nullptr || !CheckIfNumeric(leftType) || !CheckIfNumeric(rightType)) { + auto type = CheckBinaryOperatorForIntEnums(this, leftType, rightType); if (type != nullptr) { return type; } @@ -283,66 +341,42 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return GlobalTypeError(); } - if (bothConst) { - tsType = HandleArithmeticOperationOnTypes(leftType, rightType, operationType); - } - - return (tsType != nullptr) ? tsType : promotedType; -} - -checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, - const checker::Type *const rightType) -{ - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); - } - if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalFloatType(); - } - if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalDoubleType(); - } - if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); - } - return GlobalIntType(); - } - return nullptr; + return promotedType; } checker::Type *ETSChecker::CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (!leftType->IsETSEnumType() && !rightType->IsETSEnumType()) { + return nullptr; + } + if (TypeIsAppropriateForArithmetic(leftType, this) && TypeIsAppropriateForArithmetic(rightType, this)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } - return GlobalIntType(); + return GlobalIntBuiltinType(); } return nullptr; } -checker::Type *ETSChecker::CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType, - const checker::Type *const rightType) +static checker::Type *CheckBinaryOperatorPlusForEnums(ETSChecker *checker, checker::Type *const leftType, + checker::Type *const rightType) { - if (auto numericType = CheckBinaryOperatorForIntEnums(leftType, rightType); numericType != nullptr) { + if (auto numericType = CheckBinaryOperatorForIntEnums(checker, leftType, rightType); numericType != nullptr) { return numericType; } if ((leftType->IsETSStringEnumType() && (rightType->IsETSStringType() || rightType->IsETSStringEnumType())) || (rightType->IsETSStringEnumType() && (leftType->IsETSStringType() || leftType->IsETSStringEnumType()))) { - return GlobalETSStringLiteralType(); + return checker->GlobalETSStringLiteralType(); } return nullptr; } @@ -357,9 +391,7 @@ checker::Type *ETSChecker::CheckBinaryOperatorPlus( // Try to handle errors on a lower level RepairTypeErrorsInOperands(&leftType, &rightType); RepairTypeErrorsInOperands(&unboxedL, &unboxedR); - if (leftType->IsTypeError()) { // both are errors - return GlobalTypeError(); - } + ERROR_TYPE_CHECK(this, leftType, return GlobalTypeError()); if (leftType->IsETSStringType() || rightType->IsETSStringType()) { if (operationType == lexer::TokenType::PUNCTUATOR_MINUS || @@ -374,29 +406,19 @@ checker::Type *ETSChecker::CheckBinaryOperatorPlus( if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } - - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - auto type = CheckBinaryOperatorPlusForEnums(leftType, rightType); + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { + auto type = CheckBinaryOperatorPlusForEnums(this, leftType, rightType); if (type != nullptr) { return type; } LogError(diagnostic::BINOP_NONARITHMETIC_TYPE, {}, pos); - return GlobalTypeError(); - } - - if (bothConst) { - return HandleArithmeticOperationOnTypes(leftType, rightType, operationType); } return promotedType; } -static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) +[[maybe_unused]] static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) { switch (checker->ETSType(type)) { case TypeFlag::BYTE: { @@ -423,6 +445,7 @@ static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const return nullptr; } +// NOTE(dkofanov): Deprecated operations on 'char' #28006 checker::Type *ETSChecker::CheckBinaryOperatorShift( std::tuple op, bool isEqualOp, std::tuple types) @@ -430,8 +453,8 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( auto [left, right, operationType, pos] = op; auto [leftType, rightType, unboxedL, unboxedR] = types; - RepairTypeErrorWithDefault(&leftType, GlobalIntType()); - RepairTypeErrorWithDefault(&rightType, GlobalIntType()); + RepairTypeErrorWithDefault(&leftType, GlobalIntBuiltinType()); + RepairTypeErrorWithDefault(&rightType, GlobalIntBuiltinType()); RepairTypeErrorWithDefault(&unboxedL, GlobalIntType()); RepairTypeErrorWithDefault(&unboxedR, GlobalIntType()); @@ -440,15 +463,10 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - auto promotedLeftType = ApplyUnaryOperatorPromotion(unboxedL, false, !isEqualOp); - auto promotedRightType = ApplyUnaryOperatorPromotion(unboxedR, false, !isEqualOp); - - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedLeftType == nullptr || !promotedLeftType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - promotedRightType == nullptr || - !promotedRightType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto promotedLeftType = GetUnaryOperatorPromotedType(leftType, !isEqualOp); + auto promotedRightType = GetUnaryOperatorPromotedType(rightType, !isEqualOp); + if (promotedLeftType == nullptr || promotedRightType == nullptr || !CheckIfNumeric(promotedLeftType) || + !CheckIfNumeric(promotedRightType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -457,12 +475,25 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - if (promotedLeftType->HasTypeFlag(TypeFlag::CONSTANT) && promotedRightType->HasTypeFlag(TypeFlag::CONSTANT)) { - return HandleBitwiseOperationOnTypes(promotedLeftType, promotedRightType, operationType); + auto isPrim = promotedLeftType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedLeftType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + } + + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); + } + + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedLeftType; } - return GetBitwiseCompatibleType(this, promotedLeftType); + + ES2PANDA_UNREACHABLE(); + return nullptr; } +// NOTE(dkofanov): Deprecated operations on 'char' #28006 checker::Type *ETSChecker::CheckBinaryOperatorBitwise( std::tuple op, bool isEqualOp, std::tuple types) @@ -472,28 +503,19 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( RepairTypeErrorsInOperands(&leftType, &rightType); RepairTypeErrorsInOperands(&unboxedL, &unboxedR); - if (leftType->IsTypeError()) { // both are errors - return GlobalTypeError(); - } + ERROR_TYPE_CHECK(this, leftType, return GlobalTypeError()); if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { LogError(diagnostic::BINOP_UNION, {}, pos); return GlobalTypeError(); } - if (unboxedL != nullptr && unboxedL->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) && unboxedR != nullptr && - unboxedR->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return HandleBooleanLogicalOperators(unboxedL, unboxedR, operationType); + if (CheckOpArgsTypeEq(this, unboxedL, unboxedR, GlobalETSBooleanType())) { + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); } - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -501,73 +523,98 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( LogError(diagnostic::OP_NONNUMERIC, {}, pos); return GlobalTypeError(); } + SetGenerateValueOfFlags(types, {left, right}); + + auto isPrim = promotedType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + } - if (bothConst) { - return HandleBitwiseOperationOnTypes(leftType, rightType, operationType); + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); } - return SelectGlobalIntegerTypeForNumeric(promotedType); + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedType; + } + return nullptr; } checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, - ir::BinaryExpression *expr, checker::Type *leftType, - checker::Type *rightType, Type *unboxedL, Type *unboxedR) + checker::Type *leftType, checker::Type *rightType, Type *unboxedL, + Type *unboxedR) { RepairTypeErrorsInOperands(&leftType, &rightType); RepairTypeErrorsInOperands(&unboxedL, &unboxedR); - if (leftType->IsTypeError()) { // both are errors - return GlobalTypeError(); - } + ERROR_TYPE_CHECK(this, leftType, return GlobalTypeError()); + // Don't do any boxing for primitive type when another operand is Enum. Enum will become primitive type later. if (leftType->IsETSEnumType() || rightType->IsETSEnumType()) { left->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); right->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); } - if (right->IsNumberLiteral() && AdjustNumberLiteralType(right->AsNumberLiteral(), rightType, leftType)) { + + if (right->IsNumberLiteral() && !left->IsNumberLiteral() && leftType->IsBuiltinNumeric()) { return leftType; } - if (left->IsNumberLiteral() && AdjustNumberLiteralType(left->AsNumberLiteral(), leftType, rightType)) { + if (left->IsNumberLiteral() && !right->IsNumberLiteral() && rightType->IsBuiltinNumeric()) { return rightType; } - if (HandleLogicalPotentialResult(left, right, expr, leftType)) { - ES2PANDA_ASSERT(expr->Result()->TsType() != nullptr); - return expr->Result()->TsType(); - } - if (IsTypeIdenticalTo(leftType, rightType)) { return GetNonConstantType(leftType); } - if (IsTypeIdenticalTo(unboxedL, unboxedR)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return GetNonConstantType(unboxedL); - } + return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); +} - if (unboxedL != nullptr && unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && unboxedR != nullptr && - unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return EffectiveTypeOfNumericOp(this, unboxedL, unboxedR); +static bool ContainsNumbers(ETSChecker *checker, Type *tp) +{ + auto isSubtypeOfNumeric = [checker](Type *tp2) { + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), tp2); + }; + if (isSubtypeOfNumeric(tp)) { + return true; + } + if (tp->IsETSUnionType()) { + for (auto *constituent : tp->AsETSUnionType()->ConstituentTypes()) { + if (isSubtypeOfNumeric(constituent)) { + return true; + } + } } - return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); + return false; } +// CC-OFFNXT(huge_cyclomatic_complexity, huge_cca_cyclomatic_complexity[C++]) solid logic +// NOTE: code inside this function follows the broken logic bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType) { - auto isGlobalObjectType {[](checker::Type *const type) -> bool { - return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); + auto isRelaxedType {[&](checker::Type *const type) -> bool { + return (type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType()) || type->IsETSAnyType() || + type->IsETSNullType() || type->IsETSUndefinedType(); }}; - // Equality expression is always allowed for Object, undefined and null - if (isGlobalObjectType(leftType) || isGlobalObjectType(rightType) || leftType->IsETSUndefinedType() || - rightType->IsETSUndefinedType() || leftType->IsETSNullType() || rightType->IsETSNullType()) { + // Equality expression is always allowed for *magic types* + if (isRelaxedType(leftType) || isRelaxedType(rightType)) { return true; } + // Any two types that can be numeric are comparable + if (ContainsNumbers(this, leftType) && ContainsNumbers(this, rightType)) { + return true; + } + + // Boolean and any type that can be numeric or char are not comparable + if ((FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalCharBuiltinType())) && + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType())) { + return false; + } + // NOTE (mxlgv): Skip for unions. Required implementation of the specification section: // 7.25.6 Reference Equality Based on Actual Type (Union Equality Operators) if (leftType->IsETSUnionType()) { @@ -594,6 +641,11 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che } } + if (FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) && + (leftType->IsETSEnumType() || rightType->IsETSEnumType())) { + return true; + } + // 7.24.5 Enumeration Relational Operators return leftType->IsETSEnumType() == rightType->IsETSEnumType(); } @@ -604,12 +656,9 @@ std::tuple ETSChecker::CheckBinaryOperatorStrictEqual(ir::Expres checker::Type *leftType, checker::Type *rightType) { RepairTypeErrorsInOperands(&leftType, &rightType); - if (leftType->IsTypeError()) { // both are errors - // We still know that operation result should be boolean, so recover. - return {GlobalETSBooleanType(), GlobalETSObjectType()}; - } + // We still know that operation result should be boolean, so recover. + ERROR_TYPE_CHECK(this, leftType, return std::make_tuple(GlobalETSBooleanBuiltinType(), GlobalETSObjectType())); - checker::Type *tsType {}; if (!IsReferenceType(leftType) || !IsReferenceType(rightType)) { LogError(diagnostic::BINOP_NOT_REFERENCE, {}, pos); return {GlobalETSBooleanType(), GlobalETSObjectType()}; @@ -618,43 +667,11 @@ std::tuple ETSChecker::CheckBinaryOperatorStrictEqual(ir::Expres Relation()->SetNode(left); if (!CheckValidEqualReferenceType(leftType, rightType)) { LogOperatorCannotBeApplied(this, operationType, leftType, rightType, pos); - return {GlobalETSBooleanType(), GlobalETSObjectType()}; - } - - if (!Relation()->IsCastableTo(leftType, rightType) && !Relation()->IsCastableTo(rightType, leftType)) { + } else if (!Relation()->IsCastableTo(leftType, rightType) && !Relation()->IsCastableTo(rightType, leftType)) { LogOperatorCannotBeApplied(this, operationType, leftType, rightType, pos); - return {GlobalETSBooleanType(), GlobalETSObjectType()}; } - tsType = GlobalETSBooleanType(); - if (rightType->IsETSDynamicType() && leftType->IsETSDynamicType()) { - return {tsType, GlobalBuiltinJSValueType()}; - } - - return {tsType, GlobalETSObjectType()}; -} - -static Type *CheckOperatorEqualDynamic(ETSChecker *checker, BinaryArithmOperands const &ops) -{ - auto left = ops.expr->Left(); - auto right = ops.expr->Right(); - // canonicalize - auto *const dynExp = left->TsType()->IsETSDynamicType() ? left : right; - auto *const otherExp = dynExp == left ? right : left; - - if (otherExp->TsType()->IsETSDynamicType()) { - return checker->GlobalBuiltinJSValueType(); - } - if (dynExp->TsType()->AsETSDynamicType()->IsConvertible(otherExp->TsType())) { - // NOTE: vpukhov. boxing flags are not set in dynamic values - return otherExp->TsType(); - } - if (otherExp->TsType()->IsETSReferenceType()) { - // have to prevent casting dyn_exp via ApplyCast without nullish flag - return checker->GlobalETSNullishObjectType(); - } - checker->LogError(diagnostic::BINOP_DYN_UNIMPLEMENTED, {}, ops.expr->Start()); - return checker->GlobalETSNullishObjectType(); + return {GlobalETSBooleanType(), GlobalETSObjectType()}; } static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOperands const &ops) @@ -665,13 +682,6 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper return checker->CreateETSUnionType({typeL, typeR}); } - if (typeL->IsETSEnumType() && typeR->IsETSEnumType()) { - if (checker->Relation()->IsIdenticalTo(typeL, typeR)) { - return typeL; - } - return nullptr; - } - if (typeL->IsETSReferenceType() && typeR->IsETSReferenceType()) { checker->Relation()->SetNode(expr->Left()); if (!checker->CheckValidEqualReferenceType(typeL, typeR)) { @@ -697,24 +707,17 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands { [[maybe_unused]] auto const [expr, typeL, typeR, reducedL, reducedR] = ops; - expr->Left()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - expr->Right()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - if (typeL->IsTypeError()) { // both are errors - return checker->GlobalTypeError(); - } - - if (typeL->IsETSDynamicType() || typeR->IsETSDynamicType()) { - return CheckOperatorEqualDynamic(checker, ops); - } + ERROR_TYPE_CHECK(checker, typeL, return checker->GlobalTypeError()); if (reducedL->IsETSBooleanType() && reducedR->IsETSBooleanType()) { if (reducedL->IsConstantType() && reducedR->IsConstantType()) { - bool res = reducedL->AsETSBooleanType()->GetValue() == reducedR->AsETSBooleanType()->GetValue(); - res = ((expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL) == res); - return checker->CreateETSBooleanType(res); + return checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); } - UnboxOperands(checker, ops); - return checker->GlobalETSBooleanType(); + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR) && typeL->IsETSUnboxableObject() && + typeR->IsETSUnboxableObject()) { + return typeL; + } + return reducedL; } return HandelReferenceBinaryEquality(checker, ops); @@ -742,6 +745,7 @@ static bool NonNumericTypesAreAppropriateForComparison(ETSChecker *checker, Type return false; } +// NOTE(dkofanov): Deprecated operations on 'char' #28006 std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expression *left, ir::Expression *right, lexer::TokenType operationType, lexer::SourcePosition pos, bool isEqualOp, @@ -750,9 +754,7 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres { RepairTypeErrorsInOperands(&leftType, &rightType); RepairTypeErrorsInOperands(&unboxedL, &unboxedR); - if (leftType->IsTypeError()) { // both are errors - return {GlobalETSBooleanType(), GlobalTypeError()}; - } + ERROR_TYPE_CHECK(this, leftType, return std::make_tuple(GlobalETSBooleanBuiltinType(), GlobalTypeError())); if ((leftType->IsETSUnionType() || rightType->IsETSUnionType()) && operationType != lexer::TokenType::PUNCTUATOR_EQUAL && @@ -760,94 +762,164 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres operationType != lexer::TokenType::PUNCTUATOR_STRICT_EQUAL && operationType != lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL) { LogError(diagnostic::BINOP_UNION, {}, pos); - return {GlobalETSBooleanType(), leftType}; + return {GlobalETSBooleanBuiltinType(), leftType}; } - auto *const promotedType = std::get<0>(BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp)); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { - return {GlobalETSBooleanType(), CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)})}; + return {GlobalETSBooleanBuiltinType(), + CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)})}; } - if (promotedType != nullptr && (unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType())) { + if (promotedType != nullptr && unboxedL != nullptr && unboxedR != nullptr && + unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType()) { LogOperatorCannotBeApplied(this, operationType, leftType, rightType, pos); - return {GlobalETSBooleanType(), leftType}; + return {GlobalETSBooleanBuiltinType(), leftType}; } if (promotedType == nullptr) { if (!NonNumericTypesAreAppropriateForComparison(this, leftType, rightType)) { LogError(diagnostic::BINOP_INCOMPARABLE, {}, pos); } - return {GlobalETSBooleanType(), GlobalETSBooleanType()}; + return {GlobalETSBooleanBuiltinType(), GlobalETSBooleanBuiltinType()}; } - return {GlobalETSBooleanType(), promotedType}; + return {GlobalETSBooleanBuiltinType(), promotedType}; } std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType, checker::Type *rightType) { RepairTypeErrorsInOperands(&leftType, &rightType); - if (leftType->IsTypeError()) { // both are errors - return {GlobalETSBooleanType(), GlobalTypeError()}; - } + ERROR_TYPE_CHECK(this, leftType, return std::make_tuple(GlobalETSBooleanBuiltinType(), GlobalTypeError())); - if (!IsReferenceType(leftType) || !IsReferenceType(rightType)) { + if (leftType->IsETSPrimitiveType() || rightType->IsETSPrimitiveType()) { LogError(diagnostic::BINOP_NOT_SAME, {}, pos); - return {GlobalETSBooleanType(), leftType}; + return {GlobalETSBooleanBuiltinType(), leftType}; } - if (rightType->IsETSDynamicType() && !rightType->AsETSDynamicType()->HasDecl()) { - LogError(diagnostic::INSTANCEOF_NOT_TYPE, {}, pos); - return {GlobalETSBooleanType(), leftType}; - } - - checker::Type *opType = rightType->IsETSDynamicType() ? GlobalBuiltinJSValueType() : GlobalETSObjectType(); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ComputeApparentType(rightType); + checker::Type *opType = GlobalETSObjectType(); RemoveStatus(checker::CheckerStatus::IN_INSTANCEOF_CONTEXT); - return {GlobalETSBooleanType(), opType}; + return {GlobalETSBooleanBuiltinType(), opType}; } -bool ETSChecker::AdjustNumberLiteralType(ir::NumberLiteral *const literal, Type *literalType, Type *const otherType) +template +static void ConvertNumberLiteralTo(ir::NumberLiteral *lit, Type *toType) { - if (otherType->IsETSObjectType() && !otherType->IsETSEnumType()) { - auto *const objectType = otherType->AsETSObjectType(); - if (objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) && !objectType->IsETSStringType()) { - literal->RemoveBoxingUnboxingFlags(GetBoxingFlag(literalType)); - literalType = MaybeUnboxInRelation(objectType); - literal->SetTsType(literalType); - literal->AddBoxingUnboxingFlags(GetBoxingFlag(literalType)); - return true; + auto &number = lit->Number(); + number.SetValue(number.GetValueAndCastTo()); + toType->AddTypeFlag(TypeFlag::CONSTANT); + lit->SetTsType(toType); +} + +template +static bool CheckNumberLiteralValue(ETSChecker *checker, ir::NumberLiteral const *const lit) +{ + auto const maxTo = static_cast(std::numeric_limits::max()); + auto const minTo = static_cast(std::numeric_limits::min()); + auto const val = lit->Number().GetValue(); + if (val < minTo || val > maxTo) { + checker->LogError(diagnostic::CONSTANT_VALUE_OUT_OF_RANGE, {}, lit->Start()); + return false; + } + return true; +} + +// Just to reduce the size of 'ConvertNumberLiteral' +static void ConvertIntegerNumberLiteral(ETSChecker *checker, ir::NumberLiteral *lit, ETSObjectType *fromType, + ETSObjectType *toType) +{ + if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { + ConvertNumberLiteralTo(lit, checker->GlobalLongBuiltinType()->Clone(checker)); + } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { + if (!fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) || + CheckNumberLiteralValue(checker, lit)) { + ConvertNumberLiteralTo(lit, checker->GlobalIntBuiltinType()->Clone(checker)); + } + } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && + !CheckNumberLiteralValue(checker, lit)) { + return; + } + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_INT) && + !CheckNumberLiteralValue(checker, lit)) { + return; + } + ConvertNumberLiteralTo(lit, checker->GlobalShortBuiltinType()->Clone(checker)); + } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && + !CheckNumberLiteralValue(checker, lit)) { + return; + } + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_INT) && + !CheckNumberLiteralValue(checker, lit)) { + return; + } + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT) && + !CheckNumberLiteralValue(checker, lit)) { + return; + } + ConvertNumberLiteralTo(lit, checker->GlobalByteBuiltinType()->Clone(checker)); + } +} + +static void ConvertNumberLiteral(ETSChecker *checker, ir::NumberLiteral *lit, ETSObjectType *toType) +{ + ES2PANDA_ASSERT(toType->IsBuiltinNumeric() && lit->TsType()->IsBuiltinNumeric()); + + if (auto *fromType = lit->TsType()->AsETSObjectType(); !checker->Relation()->IsIdenticalTo(fromType, toType)) { + switch (static_cast(toType->ObjectFlags() & ETSObjectFlags::BUILTIN_NUMERIC)) { + case ETSObjectFlags::BUILTIN_DOUBLE: + ConvertNumberLiteralTo(lit, checker->GlobalDoubleBuiltinType()->Clone(checker)); + break; + + case ETSObjectFlags::BUILTIN_FLOAT: + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { + checker->LogError(diagnostic::INVALID_ASSIGNMNENT, {fromType, toType}, lit->Start()); + } else { + ConvertNumberLiteralTo(lit, checker->GlobalFloatBuiltinType()->Clone(checker)); + } + break; + + case ETSObjectFlags::BUILTIN_LONG: + case ETSObjectFlags::BUILTIN_INT: + case ETSObjectFlags::BUILTIN_SHORT: + case ETSObjectFlags::BUILTIN_BYTE: + if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOATING_POINT)) { + checker->LogError(diagnostic::INVALID_ASSIGNMNENT, {fromType, toType}, lit->Start()); + } else { + ConvertIntegerNumberLiteral(checker, lit, fromType, toType); + } + break; + + default: + ES2PANDA_UNREACHABLE(); } } - return false; } Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right, lexer::SourcePosition pos) { auto *leftType = left->TsType(); - if (!IsReferenceType(leftType)) { - LogError(diagnostic::COALESCE_NOT_REF, {}, pos); - return leftType; - } leftType = GetNonNullishType(leftType); - if (leftType->IsTypeError()) { - ES2PANDA_ASSERT(IsAnyError()); - return GlobalTypeError(); + + ERROR_TYPE_CHECK(this, leftType, return GlobalTypeError()); + + if (leftType->IsETSPrimitiveType()) { + LogError(diagnostic::COALESCE_NOT_REF, {}, pos); } - auto *rightType = MaybeBoxExpression(right); + auto *rightType = MaybeBoxType(right->TsType()); if (IsTypeIdenticalTo(leftType, rightType)) { return leftType; } // If possible and required update number literal type to the proper value (identical to left-side type) - if (right->IsNumberLiteral() && AdjustNumberLiteralType(right->AsNumberLiteral(), rightType, leftType)) { + if (right->IsNumberLiteral() && leftType->IsBuiltinNumeric()) { + ConvertNumberLiteral(this, right->AsNumberLiteral(), leftType->AsETSObjectType()); return leftType; } @@ -867,6 +939,8 @@ std::map &GetCheckMap() {lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL, &ETSChecker::CheckBinaryOperatorMulDivMod}, {lexer::TokenType::PUNCTUATOR_MOD, &ETSChecker::CheckBinaryOperatorMulDivMod}, {lexer::TokenType::PUNCTUATOR_MOD_EQUAL, &ETSChecker::CheckBinaryOperatorMulDivMod}, + {lexer::TokenType::PUNCTUATOR_EXPONENTIATION, &ETSChecker::CheckBinaryOperatorMulDivMod}, + {lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL, &ETSChecker::CheckBinaryOperatorMulDivMod}, {lexer::TokenType::PUNCTUATOR_MINUS, &ETSChecker::CheckBinaryOperatorPlus}, {lexer::TokenType::PUNCTUATOR_MINUS_EQUAL, &ETSChecker::CheckBinaryOperatorPlus}, @@ -907,6 +981,7 @@ struct TypeParams { Type *unboxedR; }; +// CC-OFFNXT(G.FUN.01, huge_method) solid logic static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, const BinaryOperatorParams &binaryParams, const TypeParams &typeParams) @@ -917,22 +992,23 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, checker::Type *const leftType = typeParams.leftType; checker::Type *const rightType = typeParams.rightType; checker::Type *tsType {}; + BinaryArithmOperands ops = GetBinaryOperands(checker, binaryParams.expr->AsBinaryExpression()); BinaryArithmOperands opsRepaired = RepairTypeErrorsInOperands(ops); switch (binaryParams.operationType) { case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { - tsType = checker->CheckBinaryOperatorLogical(left, right, binaryParams.expr->AsBinaryExpression(), leftType, - rightType, typeParams.unboxedL, typeParams.unboxedR); + tsType = checker->CheckBinaryOperatorLogical(left, right, leftType, rightType, typeParams.unboxedL, + typeParams.unboxedR); break; } case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if (Type *res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { - return {checker->GlobalETSBooleanType(), res}; + if (auto res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { + return {checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), res}; } [[fallthrough]]; } @@ -960,123 +1036,70 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, return {tsType, tsType}; } -namespace { -bool IsStringEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToStringEnumOperand(ir::Expression *op, const ir::Expression *otherOp) { - if (expr == nullptr) { - return false; - } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; + auto type = op->TsType(); + auto otherType = otherOp->TsType(); + if (type->IsETSStringEnumType() && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - return type->IsETSStringEnumType(); } -bool IsIntEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToIntEnumOperand(ir::Expression *op, const ir::Expression *otherOp) { - if (expr == nullptr) { - return false; + auto type = op->TsType(); + auto otherType = otherOp->TsType(); + if (type->IsETSIntEnumType() && + ((otherType->IsETSObjectType() && otherType->AsETSObjectType()->IsBoxedPrimitive()) || + otherType->IsETSIntEnumType())) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; - } - - return type->IsETSIntEnumType(); } -bool CheckNumericOperatorContext(ir::Expression *expression, lexer::TokenType op) +static void CheckEnumInOperatorContext(ir::Expression *expression, lexer::TokenType opType, ir::Expression *left, + ir::Expression *right, ETSChecker *checker) { - const bool isMultiplicative = op == lexer::TokenType::PUNCTUATOR_MULTIPLY || - op == lexer::TokenType::PUNCTUATOR_DIVIDE || op == lexer::TokenType::PUNCTUATOR_MOD; - const bool isAdditive = op == lexer::TokenType::PUNCTUATOR_PLUS || op == lexer::TokenType::PUNCTUATOR_MINUS; - const bool isShift = op == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isBitwise = op == lexer::TokenType::PUNCTUATOR_BITWISE_AND || - op == lexer::TokenType::PUNCTUATOR_BITWISE_OR || - op == lexer::TokenType::PUNCTUATOR_BITWISE_XOR; - const bool isConditionalAndOr = - op == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || op == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; - - if (IsIntEnum(expression)) { - if (isMultiplicative || isAdditive || isShift || isRelational || isEquality || isBitwise || - isConditionalAndOr) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } - return true; - } - return false; -} + auto [lType, rType] = std::tuple {left->TsType(), right->TsType()}; -void CheckStringOperatorContext(ir::Expression *expression, checker::Type *otherType, lexer::TokenType op) -{ - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - if (IsStringEnum(expression) && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { - if (op == lexer::TokenType::PUNCTUATOR_PLUS || isRelational || isEquality) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_GREATER_THAN: + case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_LESS_THAN: + case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { + if (lType->IsETSEnumType() && rType->IsETSEnumType() && !checker->Relation()->IsIdenticalTo(lType, rType)) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expression->Start()); + return; + } + [[fallthrough]]; } - } -} - -bool CheckRelationalOperatorsBetweenEnums(ir::Expression *left, ir::Expression *right, lexer::TokenType op) -{ - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - - if (((IsStringEnum(left) && IsStringEnum(right)) || - (IsIntEnum(left) && IsIntEnum(right)))) { // NOTE(psiket) In case of int enums it has been already checked in - // the CheckNumericOperatorContext function - if (isRelational || isEquality) { - left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return true; + case lexer::TokenType::PUNCTUATOR_PLUS: { + TryAddValueOfFlagToStringEnumOperand(left, right); + TryAddValueOfFlagToStringEnumOperand(right, left); + [[fallthrough]]; } - } - return false; -} - -void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression) -{ - if (!expression->IsBinaryExpression()) { - return; - } - - auto binaryExpression = expression->AsBinaryExpression(); - auto op = binaryExpression->OperatorType(); - auto leftExp = binaryExpression->Left(); - auto rightExp = binaryExpression->Right(); - - // Numeric Operator Context - auto leftIsIntEnum = CheckNumericOperatorContext(leftExp, op); - auto rightIsIntEnum = CheckNumericOperatorContext(rightExp, op); - if (leftIsIntEnum || rightIsIntEnum) { - return; - } - - // String Operator Context - CheckStringOperatorContext(leftExp, rightExp->TsType(), op); - CheckStringOperatorContext(rightExp, leftExp->TsType(), op); - - // Relational operators if both are enumeration Types - if (CheckRelationalOperatorsBetweenEnums(leftExp, rightExp, op)) { - return; + case lexer::TokenType::PUNCTUATOR_MULTIPLY: + case lexer::TokenType::PUNCTUATOR_DIVIDE: + case lexer::TokenType::PUNCTUATOR_MOD: + case lexer::TokenType::PUNCTUATOR_MINUS: + case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: + case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + TryAddValueOfFlagToIntEnumOperand(left, right); + TryAddValueOfFlagToIntEnumOperand(right, left); + break; + } + default: + // NOTE(dkofanov): What about the '+=' operation? + break; } } -} // namespace std::tuple ETSChecker::CheckArithmeticOperations( ir::Expression *expr, std::tuple op, @@ -1092,16 +1115,28 @@ std::tuple ETSChecker::CheckArithmeticOperations( if (rightType->IsETSUnionType()) { rightType = GetNonConstantType(rightType); } + CheckEnumInOperatorContext(expr, operationType, left, right, this); auto checkMap = GetCheckMap(); if (checkMap.find(operationType) != checkMap.end()) { auto check = checkMap[operationType]; auto tsType = check(this, std::make_tuple(left, right, operationType, pos), isEqualOp, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); + if (tsType == nullptr) { + return {leftType, rightType}; + } + if (tsType->IsETSPrimitiveType()) { + tsType = MaybeBoxType(tsType); + } + if (left->TsType()->IsTypeError()) { + left->SetTsType(tsType); + } + if (right->TsType()->IsTypeError()) { + right->SetTsType(tsType); + } return {tsType, tsType}; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return CheckBinaryOperatorHelper(this, {left, right, expr, operationType, pos, isEqualOp}, {leftType, rightType, unboxedL, unboxedR}); } @@ -1114,6 +1149,8 @@ static std::tuple ResolveCheckBinaryOperatorForBigInt(ETSChecker case lexer::TokenType::PUNCTUATOR_LESS_THAN: case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: return {checker->GlobalETSBooleanType(), checker->GlobalETSBooleanType()}; default: return {leftType, rightType}; @@ -1141,10 +1178,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); } @@ -1154,8 +1187,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, return {leftType, leftType}; } - CheckNeedToGenerateGetValueForBinaryExpression(expr); - const bool isLogicalExtendedOperator = (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); Type *unboxedL = @@ -1175,55 +1206,4 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); } -Type *ETSChecker::HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - return PerformArithmeticOperationOnTypes(left, right, operationType); -} - -Type *ETSChecker::HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - return HandleBitWiseArithmetic(left, right, operationType); -} - -void ETSChecker::FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression) -{ - if (type->IsETSEnumType()) { - typeExpression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return; - } - if (type->IsETSObjectType() && (unboxedType != nullptr)) { - typeExpression->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedType)); - } -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/arithmetic.h b/ets2panda/checker/ets/arithmetic.h index 0f6782c00bf8b7a1b710e12495faef58392e7969..6ca03978bb6127cf14ad560447bfb15a78af169d 100644 --- a/ets2panda/checker/ets/arithmetic.h +++ b/ets2panda/checker/ets/arithmetic.h @@ -18,176 +18,9 @@ #include "checker/ETSchecker.h" #include "checker/ETSAnalyzer.h" +#include "checker/types/globalTypesHolder.h" namespace ark::es2panda::checker { - -template -typename TargetType::UType ETSChecker::GetOperand(Type *type) -{ - switch (ETSType(type)) { - case TypeFlag::BYTE: { - return type->AsByteType()->GetValue(); - } - case TypeFlag::CHAR: { - return type->AsCharType()->GetValue(); - } - case TypeFlag::SHORT: { - return type->AsShortType()->GetValue(); - } - case TypeFlag::INT: { - return type->AsIntType()->GetValue(); - } - case TypeFlag::LONG: { - return type->AsLongType()->GetValue(); - } - case TypeFlag::FLOAT: { - return type->AsFloatType()->GetValue(); - } - case TypeFlag::DOUBLE: { - return type->AsDoubleType()->GetValue(); - } - case TypeFlag::ETS_BOOLEAN: { - return type->AsETSBooleanType()->GetValue(); - } - default: { - ES2PANDA_UNREACHABLE(); - } - } -} - -template -Type *ETSChecker::PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - - bool result {}; - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_LESS_THAN: { - result = leftValue < rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { - result = leftValue <= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { - result = leftValue > rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { - result = leftValue >= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_EQUAL: { - result = leftValue == rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - result = leftValue != rightValue; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return CreateETSBooleanType(result); -} - -template -Type *ETSChecker::PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - auto result = leftValue; - auto isForbiddenZeroDivision = [&rightValue]() { return std::is_integral::value && rightValue == 0; }; - auto isIntegralDivideResOverflow = [&rightValue, &leftValue]() { - // Note: Handle corner cases - return std::is_integral_v && leftValue == std::numeric_limits::min() && rightValue == -1; - }; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { - result = leftValue + rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: { - result = leftValue - rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - - if (isIntegralDivideResOverflow()) { - return Allocator()->New(std::numeric_limits::min()); - } - - result = leftValue / rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MULTIPLY: - case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: { - result = leftValue * rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - result = HandleModulo(leftValue, rightValue); - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} - -template <> -inline IntType::UType ark::es2panda::checker::ETSChecker::HandleModulo(IntType::UType leftValue, - IntType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline LongType::UType ark::es2panda::checker::ETSChecker::HandleModulo(LongType::UType leftValue, - LongType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline FloatType::UType ark::es2panda::checker::ETSChecker::HandleModulo(FloatType::UType leftValue, - FloatType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - -template <> -inline DoubleType::UType ark::es2panda::checker::ETSChecker::HandleModulo( - DoubleType::UType leftValue, DoubleType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - template inline IntegerUType CastIfFloat(FloatOrIntegerUType num) { @@ -197,61 +30,6 @@ inline IntegerUType CastIfFloat(FloatOrIntegerUType num) return num; } } - -template -Type *ETSChecker::HandleBitWiseArithmetic(Type *left, Type *right, lexer::TokenType operationType) -{ - using IntegerUType = typename IntegerType::UType; - using UnsignedUType = std::make_unsigned_t; - - UnsignedUType result = 0; - UnsignedUType unsignedLeftValue = CastIfFloat(GetOperand(left)); - UnsignedUType unsignedRightValue = CastIfFloat(GetOperand(right)); - - auto mask = std::numeric_limits::digits - 1U; - auto shift = unsignedRightValue & mask; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: { - result = unsignedLeftValue & unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: { - result = unsignedLeftValue | unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: { - result = unsignedLeftValue ^ unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue << shift; - break; - } - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(IntegerUType) == 4 || sizeof(IntegerUType) == 8); - result = static_cast(unsignedLeftValue) >> shift; // NOLINT(hicpp-signed-bitwise) - break; - } - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue >> shift; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} } // namespace ark::es2panda::checker #endif diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index d47d219f105c30e8a93a7f5cbfff645516314598..a411f9d429bf07f01adc90396a3a08a1261112b7 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -14,7 +14,6 @@ */ #include "assignAnalyzer.h" -#include #include "ir/base/classDefinition.h" #include "ir/base/classProperty.h" @@ -58,6 +57,7 @@ #include "varbinder/scope.h" #include "varbinder/declaration.h" #include "checker/ETSchecker.h" +#include "checker/types/gradualType.h" #include "ir/base/catchClause.h" #include "parser/program/program.h" #include "checker/types/ts/objectType.h" @@ -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(); } @@ -535,11 +532,14 @@ static bool IsInitialConstructor(const ir::AstNode *node) } const auto methodDef = node->AsMethodDefinition(); + ES2PANDA_ASSERT(methodDef != nullptr); if (methodDef->Function()->Body() == nullptr || methodDef->Function()->IsExternal()) { return false; } - const auto funcBody = node->AsMethodDefinition()->Function()->Body()->AsBlockStatement(); + const auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + const auto funcBody = func->Body()->AsBlockStatement(); return !(!funcBody->Statements().empty() && funcBody->Statements()[0]->IsExpressionStatement() && funcBody->Statements()[0]->AsExpressionStatement()->GetExpression()->IsCallExpression() && @@ -554,7 +554,7 @@ static bool IsInitialConstructor(const ir::AstNode *node) void AssignAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) { auto *func = methodDef->Function(); - + ES2PANDA_ASSERT(func != nullptr); if (func->Body() == nullptr || func->IsProxy()) { return; } @@ -1016,10 +1016,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 || @@ -1211,8 +1207,11 @@ util::StringView AssignAnalyzer::GetVariableType(const ir::AstNode *node) const util::StringView AssignAnalyzer::GetVariableName(const ir::AstNode *node) const { switch (node->Type()) { - case ir::AstNodeType::CLASS_PROPERTY: - return node->AsClassProperty()->Id()->Name(); + case ir::AstNodeType::CLASS_PROPERTY: { + const ir::Identifier *identifier = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(identifier != nullptr); + return identifier->Name(); + } case ir::AstNodeType::VARIABLE_DECLARATOR: return node->AsVariableDeclarator()->Id()->AsIdentifier()->Name(); default: @@ -1220,7 +1219,7 @@ util::StringView AssignAnalyzer::GetVariableName(const ir::AstNode *node) const } } -const lexer::SourcePosition &AssignAnalyzer::GetVariablePosition(const ir::AstNode *node) const +lexer::SourcePosition AssignAnalyzer::GetVariablePosition(const ir::AstNode *node) const { switch (node->Type()) { case ir::AstNodeType::CLASS_PROPERTY: @@ -1284,7 +1283,9 @@ varbinder::Variable *AssignAnalyzer::GetBoundVariable(const ir::AstNode *node) varbinder::Variable *ret = nullptr; if (node->IsClassProperty()) { - ret = node->AsClassProperty()->Id()->Variable(); + const ir::Identifier *identifier = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(identifier != nullptr); + ret = identifier->Variable(); } else if (node->IsVariableDeclarator()) { ret = node->AsVariableDeclarator()->Id()->AsIdentifier()->Variable(); } else { @@ -1354,6 +1355,20 @@ const ir::AstNode *AssignAnalyzer::GetDeclaringNode(const ir::AstNode *node) return ret; } +static bool IsDefaultValueType(const Type *type, bool isNonReadonlyField) +{ + if (type == nullptr) { + return false; + } + if (type->IsGradualType()) { + return IsDefaultValueType(type->AsGradualType()->GetBaseType(), isNonReadonlyField); + } + return (type->IsETSPrimitiveType() || (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) || + 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); @@ -1371,11 +1386,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) @@ -1395,7 +1406,7 @@ void AssignAnalyzer::LetInit(const ir::AstNode *node) // check reassignment of readonly properties util::StringView type = GetVariableType(declNode); util::StringView name = GetVariableName(declNode); - const lexer::SourcePosition &pos = GetVariablePosition(node); + const lexer::SourcePosition pos = GetVariablePosition(node); auto uninit = [this](NodeId a) { uninits_.Excl(a); @@ -1406,9 +1417,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); } @@ -1443,7 +1454,15 @@ void AssignAnalyzer::CheckInit(const ir::AstNode *node) } if (declNode->Parent() != classDef_) { - // property of an other class + // property of another class + return; + } + + if (node->IsDefinite()) { + return; + } + + if (declNode->AsClassProperty()->IsImmediateInit()) { return; } } @@ -1456,14 +1475,13 @@ void AssignAnalyzer::CheckInit(const ir::AstNode *node) util::StringView type = GetVariableType(declNode); util::StringView name = GetVariableName(declNode); - const lexer::SourcePosition &pos = GetVariablePosition(node); + const lexer::SourcePosition pos = GetVariablePosition(node); std::stringstream ss; if (node->IsClassProperty()) { checker_->LogError(diagnostic::PROPERTY_MAYBE_MISSING_INIT, {name}, pos); } else { - ss << Capitalize(type) << " '" << name << "' is used before being assigned."; - Warning(ss.str(), pos); + checker_->LogError(diagnostic::USE_BEFORE_INIT, {Capitalize(type), name}, pos); } } } diff --git a/ets2panda/checker/ets/assignAnalyzer.h b/ets2panda/checker/ets/assignAnalyzer.h index 73148898bfe9bc9b916f27c0b0de1a8524e6a187..c5004e5fae3e216dadfdda8282fd03dfb64ad9d6 100644 --- a/ets2panda/checker/ets/assignAnalyzer.h +++ b/ets2panda/checker/ets/assignAnalyzer.h @@ -136,8 +136,8 @@ 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; @@ -150,7 +150,7 @@ private: NodeId GetNodeId(const ir::AstNode *node) const; util::StringView GetVariableType(const ir::AstNode *node) const; util::StringView GetVariableName(const ir::AstNode *node) const; - const lexer::SourcePosition &GetVariablePosition(const ir::AstNode *node) const; + lexer::SourcePosition GetVariablePosition(const ir::AstNode *node) const; const ir::AstNode *GetDeclaringNode(const ir::AstNode *node); varbinder::Variable *GetBoundVariable(const ir::AstNode *node); bool VariableHasDefaultValue(const ir::AstNode *node); diff --git a/ets2panda/checker/ets/baseAnalyzer.h b/ets2panda/checker/ets/baseAnalyzer.h index 8599c5d00a4cf3d9ed0b8b8b11b719a40f323683..93ed62e4836982c61eb7fce7ea3387956c0408d1 100644 --- a/ets2panda/checker/ets/baseAnalyzer.h +++ b/ets2panda/checker/ets/baseAnalyzer.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 @@ -21,7 +21,7 @@ namespace ark::es2panda::ir { class AstNode; -enum class AstNodeType; +enum class AstNodeType : uint8_t; } // namespace ark::es2panda::ir namespace ark::es2panda::checker { diff --git a/ets2panda/checker/ets/castingContext.cpp b/ets2panda/checker/ets/castingContext.cpp index 0f1c377aaa3d61389ec083ad314ea99ca5704da2..d7a3e5f069d60d2a94c69c03debb0e95d5e3db20 100644 --- a/ets2panda/checker/ets/castingContext.cpp +++ b/ets2panda/checker/ets/castingContext.cpp @@ -26,9 +26,8 @@ CastingContext::CastingContext(TypeRelation *relation, const diagnostic::Diagnos const SavedTypeRelationFlagsContext savedTypeRelationFlags(relation, flags_); relation->SetNode(data.node); - const bool isLegalBoxedPrimitiveConversion = relation->IsLegalBoxedPrimitiveConversion(data.target, data.source); relation->Result(false); - if (!relation->IsSupertypeOf(data.target, data.source) && !isLegalBoxedPrimitiveConversion) { + if (!relation->IsSupertypeOf(data.target, data.source)) { relation->IsCastableTo(data.source, data.target); // #22954 string comparison if (!relation->IsTrue() && data.source->ToString() == data.target->ToString()) { @@ -39,13 +38,6 @@ CastingContext::CastingContext(TypeRelation *relation, const diagnostic::Diagnos } } - if (isLegalBoxedPrimitiveConversion && !relation->IsTrue()) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - Type *sourceUnboxedType = checker->MaybeUnboxType(data.source); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetBoxingFlag(data.target)); - } - uncheckedCast_ = relation->UncheckedCast(); relation->SetNode(nullptr); } diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index e165cb0e9a3491fecc9d078e62921ba3bce4567f..90c5d2f5be896c9e5a163c814e21236480cb8378 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -16,7 +16,6 @@ #include "conversion.h" #include "checker/ets/boxingConverter.h" -#include "checker/ets/narrowingConverter.h" #include "checker/ets/unboxingConverter.h" #include "checker/ets/wideningConverter.h" #include "checker/types/ets/etsTupleType.h" @@ -35,23 +34,6 @@ void WideningPrimitive(TypeRelation *const relation, Type *const source, Type *c WideningConverter(relation->GetChecker()->AsETSChecker(), relation, target, source); } -void NarrowingPrimitive(TypeRelation *const relation, Type *const source, Type *const target) -{ - ES2PANDA_ASSERT(source->IsETSPrimitiveType() && target->IsETSPrimitiveType()); - - NarrowingConverter(relation->GetChecker()->AsETSChecker(), relation, target, source); -} - -void WideningNarrowingPrimitive(TypeRelation *const relation, ByteType *const source, CharType *const target) -{ - auto *const tempInt = relation->GetChecker()->AsETSChecker()->GetGlobalTypesHolder()->GlobalIntType(); - WideningPrimitive(relation, source, tempInt); - if (!relation->IsTrue()) { - return; - } - NarrowingPrimitive(relation, tempInt, target); -} - void WideningReference(TypeRelation *const relation, ETSObjectType *const source, ETSObjectType *const target) { relation->IsSupertypeOf(target, source); @@ -253,13 +235,6 @@ void NarrowingReference(TypeRelation *const relation, ETSObjectType *const sourc NarrowingReferenceImpl(relation, source, target); } -static inline void RollbackBoxingIfFailed(TypeRelation *const relation) -{ - if (!relation->IsTrue()) { - relation->GetNode()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); - } -} - ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) { auto *const etsChecker = relation->GetChecker()->AsETSChecker(); @@ -268,7 +243,6 @@ ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) return nullptr; } auto *const boxedType = boxed.Result()->AsETSObjectType(); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetBoxingFlag(boxedType)); return boxedType; } @@ -280,7 +254,6 @@ Type *Unboxing(TypeRelation *const relation, ETSObjectType *const source) return nullptr; } auto *const unboxedType = unboxed.Result(); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetUnboxingFlag(unboxedType)); return unboxedType; } @@ -292,27 +265,6 @@ void UnboxingWideningPrimitive(TypeRelation *const relation, ETSObjectType *cons } ES2PANDA_ASSERT(unboxedSource != nullptr); WideningPrimitive(relation, target, unboxedSource); - RollbackBoxingIfFailed(relation); -} - -void UnboxingNarrowingPrimitive(TypeRelation *const relation, ETSObjectType *const source, Type *const target) -{ - auto *const unboxedSource = Unboxing(relation, source); - if (!relation->IsTrue()) { - return; - } - ES2PANDA_ASSERT(unboxedSource != nullptr); - NarrowingPrimitive(relation, target, unboxedSource); -} - -void UnboxingWideningNarrowingPrimitive(TypeRelation *const relation, ETSObjectType *const source, Type *const target) -{ - auto *const unboxedSource = Unboxing(relation, source); - if (!relation->IsTrue()) { - return; - } - ES2PANDA_ASSERT(unboxedSource != nullptr); - WideningNarrowingPrimitive(relation, unboxedSource->AsByteType(), target->AsCharType()); } void NarrowingReferenceUnboxing(TypeRelation *const relation, ETSObjectType *const source, Type *const target) @@ -337,7 +289,6 @@ void BoxingWideningReference(TypeRelation *const relation, Type *const source, E } ES2PANDA_ASSERT(boxedSource != nullptr); WideningReference(relation, boxedSource, target); - RollbackBoxingIfFailed(relation); } void String(TypeRelation *const relation, Type *const source) @@ -346,14 +297,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/conversion.h b/ets2panda/checker/ets/conversion.h index cf75be4906f1534d32e161d4088702fb7825aebc..e78b65c087e67a85ff304efbdb430ed4e6ab4620 100644 --- a/ets2panda/checker/ets/conversion.h +++ b/ets2panda/checker/ets/conversion.h @@ -23,8 +23,6 @@ namespace ark::es2panda::checker::conversion { void Identity(TypeRelation *relation, Type *source, Type *target); void WideningPrimitive(TypeRelation *relation, Type *source, Type *target); -void NarrowingPrimitive(TypeRelation *relation, Type *source, Type *target); -void WideningNarrowingPrimitive(TypeRelation *relation, ByteType *source, CharType *target); void WideningReference(TypeRelation *relation, ETSObjectType *source, ETSObjectType *target); void WideningReference(TypeRelation *relation, ETSArrayType *source, ETSObjectType *target); @@ -38,8 +36,6 @@ void NarrowingReference(TypeRelation *relation, ETSObjectType *source, ETSTupleT ETSObjectType *Boxing(TypeRelation *relation, Type *source); Type *Unboxing(TypeRelation *relation, ETSObjectType *source); -void UnboxingWideningNarrowingPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); -void UnboxingNarrowingPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); void UnboxingWideningPrimitive(TypeRelation *relation, ETSObjectType *source, Type *target); void NarrowingReferenceUnboxing(TypeRelation *relation, ETSObjectType *source, Type *target); void BoxingWideningReference(TypeRelation *relation, Type *source, ETSObjectType *target); diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index 503cb2567ebd0d96dc82c3a7e7c23919ee8ff76b..2a67acd88d5d2d5a73df5b16812ca6e63de7b950 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -20,8 +20,6 @@ #include "varbinder/declaration.h" #include "varbinder/varbinder.h" #include "varbinder/ETSBinder.h" -#include "checker/types/ets/etsDynamicFunctionType.h" -#include "checker/ets/dynamic/dynamicCall.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "ir/base/classProperty.h" #include "ir/base/classStaticBlock.h" @@ -50,6 +48,7 @@ namespace ark::es2panda::checker { void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) { auto scope = compiler::NearestScope(node); + ES2PANDA_ASSERT(scope != nullptr); if (scope->IsGlobalScope()) { // NOTE(aleksisch): All classes are contained in ETSGlobal class scope (not just Global scope), // however it's parent is ETSModule. It should be fixed @@ -64,6 +63,7 @@ void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) // however right now checker do it when called on ClassDefinition auto method = node->AsMethodDefinition(); auto func = method->Value()->AsFunctionExpression()->Function(); + ES2PANDA_ASSERT(method->Id() != nullptr); func->Id()->SetVariable(method->Id()->Variable()); } ScopeContext checkerScope(checker, scope); @@ -73,6 +73,7 @@ void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) void ProcessScopesNode(ETSChecker *checker, ir::AstNode *node) { auto *scope = compiler::NearestScope(node); + ES2PANDA_ASSERT(scope != nullptr); if (scope->IsGlobalScope()) { // NOTE(aleksisch): All classes are contained in ETSGlobal scope, // however it's parent is ETSModule (not ETSGlobal). It should be fixed @@ -85,180 +86,41 @@ 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()); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto dynamicTypeNode = AllocNode(GlobalBuiltinDynamicType(lang), Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto intTypeNode = AllocNode(ir::PrimitiveType::INT, Allocator()); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *objParam = AddParam("obj", dynamicTypeNode); - params.push_back(objParam); - - ir::ETSParameterExpression *param2; - if (!DynamicCall::IsByValue(VarBinder()->AsETSBinder(), callee)) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - param2 = AddParam("qname_start", intTypeNode); - params.push_back(param2); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - param2 = AddParam("qname_len", intTypeNode->Clone(Allocator(), nullptr)); - } else { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - param2 = AddParam("this", dynamicTypeNode->Clone(Allocator(), nullptr)); - } - - params.push_back(param2); - - for (size_t i = 0; i < arguments.size(); i++) { - util::UString paramName("p" + std::to_string(i), Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto paramType = arguments[i]->TsType()->IsLambdaObject() - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ? dynamicTypeNode->Clone(Allocator(), nullptr) - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - : AllocNode(arguments[i]->TsType(), Allocator()); - // 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)); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *func = AllocNode( - Allocator(), 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()); - func->SetIdent(name); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = AllocNode( - // 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); - return method; -} - -static void ToString(ETSChecker *checker, const ArenaVector &arguments, std::stringstream &ss) -{ - for (auto *arg : arguments) { - auto type = arg->Check(checker); - ss << "-"; - type->ToString(ss); - } -} - -static void ToString([[maybe_unused]] ETSChecker *checker, const ArenaVector &arguments, - std::stringstream &ss) -{ - for (auto *arg : arguments) { - auto *type = arg->TsType(); - ss << "-"; - type->ToString(ss); - } -} - -template -Signature *ETSChecker::ResolveDynamicCallExpression(ir::Expression *callee, const ArenaVector &arguments, - Language lang, bool isConstruct) -{ - auto &dynamicIntrinsics = *DynamicCallIntrinsics(isConstruct); - - auto mapIt = dynamicIntrinsics.find(lang); - if (mapIt == dynamicIntrinsics.cend()) { - std::tie(mapIt, std::ignore) = dynamicIntrinsics.emplace(lang, Allocator()->Adapter()); - } - - auto &map = mapIt->second; - - std::stringstream ss; - ss << "dyncall"; - if (DynamicCall::IsByValue(VarBinder()->AsETSBinder(), callee)) { - ss << "-byvalue"; - } else { - const auto callNames = DynamicCall::ResolveCall(VarBinder()->AsETSBinder(), callee); - DynamicCallNames(isConstruct)->try_emplace(callNames.name, 0); - } - - ToString(this, arguments, ss); - - auto key = ss.str(); - auto it = map.find(util::StringView(key)); - if (it == map.end()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto klass = GetDynamicClass(lang, isConstruct); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = CreateDynamicCallIntrinsic(callee, arguments, lang); - auto props = ArenaVector(Allocator()->Adapter()); - props.emplace_back(method); - klass->Definition()->AddProperties(std::move(props)); - - { - auto prevClass = VarBinder()->AsETSBinder()->GetGlobalRecordTable()->ClassDefinition(); - VarBinder()->AsETSBinder()->GetGlobalRecordTable()->SetClassDefinition(klass->Definition()); - ProcessScopesNode(this, method); - ProcessCheckerNode(this, method); - VarBinder()->AsETSBinder()->GetGlobalRecordTable()->SetClassDefinition(prevClass); - } - method->Function()->Signature()->SetReturnType(GlobalBuiltinDynamicType(lang)); - - map.emplace(util::UString(key, Allocator()).View(), method->Function()); - return method->Function()->Signature(); - } - - return it->second->Signature(); -} - -template Signature *ETSChecker::ResolveDynamicCallExpression( - ir::Expression *callee, const ArenaVector &arguments, Language lang, bool isConstruct); - -template Signature *ETSChecker::ResolveDynamicCallExpression( - ir::Expression *callee, const ArenaVector &arguments, Language lang, bool isConstruct); - std::pair 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, ir::ModifierFlags::STATIC, }); // clang-format on + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); return std::make_pair(func, id); @@ -267,24 +129,25 @@ 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}); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); return std::make_pair(func, id); @@ -297,10 +160,11 @@ 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()); + ES2PANDA_ASSERT(staticBlock != nullptr); staticBlock->AddModifier(ir::ModifierFlags::STATIC); return staticBlock; @@ -313,59 +177,40 @@ 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 = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(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) - statements->push_back(AllocNode(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); @@ -376,338 +221,41 @@ ir::ClassDeclaration *ETSChecker::BuildClass(util::StringView name, const ClassB return classDecl; } -ir::ClassProperty *ETSChecker::CreateStaticReadonlyField(const char *name) -{ - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(name, Allocator()); - 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); - - return field; -} - -ir::ClassDeclaration *ETSChecker::GetDynamicClass(Language lang, bool isConstruct) -{ - auto &klasses = dynamicClasses_[static_cast(isConstruct)]; - if (klasses.count(lang) != 0U) { - return klasses[lang]; - } - auto className = - isConstruct ? compiler::Signatures::Dynamic::NewClass(lang) : compiler::Signatures::Dynamic::CallClass(lang); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto klass = BuildClass(className, [this, lang, isConstruct](ArenaVector *classBody) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateStaticReadonlyField("qname_start_from")); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateDynamicCallClassInitializer(lang, isConstruct)); - }); - klasses.emplace(lang, klass); - return klass; -} - -void ETSChecker::ClassInitializerFromImport(ir::ETSImportDeclaration *import, ArenaVector *statements) -{ - 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()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodId = AllocNode(builtin_method_name, Allocator()); - auto *callee = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - - // NOTE: #23698. Make 'ohmUrl' mandatory in 'dynamicPaths'. - util::StringView ohmUrl = util::UString(import->OhmUrl(), Allocator()).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(); - } - } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ArenaVector callParams({AllocNode(ohmUrl)}, Allocator()->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()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldId = AllocNode(import->AssemblerName(), Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *property = AllocNode(moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, - false, false); - - auto *initializer = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(property, loadCall, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - statements->push_back(AllocNode(initializer)); -} - -ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( - const std::vector &imports) -{ - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateClassStaticInitializer([this, imports](ArenaVector *statements, - [[maybe_unused]] ArenaVector *params) { - for (auto *import : imports) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ClassInitializerFromImport(import, statements); - } - }); -} - 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; } -ir::MethodDefinition *ETSChecker::CreateDynamicModuleClassInitMethod() -{ - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateClassMethod(compiler::Signatures::DYNAMIC_MODULE_CLASS_INIT, ir::ScriptFunctionFlags::METHOD, - ir::ModifierFlags::PUBLIC | ir::ModifierFlags::STATIC, - [this]([[maybe_unused]] ArenaVector *statements, - [[maybe_unused]] ArenaVector *params, - Type **returnType) { *returnType = GlobalVoidType(); }); -} - -ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInvokeMethod(Signature *invokeSignature, - ir::TypeNode *retTypeAnnotation) -{ - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateClassMethod( - 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()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ir::ETSParameterExpression *thisParam = AddParam(thisParamName.View(), nullptr); - params->push_back(thisParam); - - ArenaVector callParams(Allocator()->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) - auto *param = AddParam(paramName, AllocNode(invokeParam->TsType(), Allocator())); - params->push_back(param); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - callParams.push_back(param->Clone(Allocator(), 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); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *callLambda = AllocNode(callee, std::move(callParams), nullptr, false); - - auto *castToRetTypeExpr = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(callLambda, retTypeAnnotation->Clone(Allocator(), nullptr), false); - castToRetTypeExpr->SetTsType(invokeSignature->ReturnType()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *retStatement = AllocNode(castToRetTypeExpr); - statements->push_back(retStatement); - - *returnType = invokeSignature->ReturnType(); - }); -} - -void ETSChecker::EmitDynamicModuleClassInitCall() -{ - auto *globalClass = VarBinder()->Program()->GlobalClass(); - auto &body = globalClass->Body(); - auto it = std::find_if(body.begin(), body.end(), [](ir::AstNode *node) { return node->IsClassStaticBlock(); }); - - ES2PANDA_ASSERT(it != body.end()); - - auto *staticBlock = (*it)->AsClassStaticBlock(); - 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 *callee = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - - ArenaVector callParams(Allocator()->Adapter()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *initCall = AllocNode(callee, std::move(callParams), nullptr, false); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const node = AllocNode(initCall); - node->SetParent(cctorBody); - cctorBody->Statements().push_back(node); - - ProcessScopesNode(this, node); - ProcessCheckerNode(this, node); -} - -void ETSChecker::BuildClassBodyFromDynamicImports(const ArenaVector &dynamicImports, - ArenaVector *classBody) -{ - std::unordered_set fields; - std::vector imports; - - for (auto *import : dynamicImports) { - auto source = import->Source()->Str(); - if (fields.find(source) != fields.cend()) { - continue; - } - - auto assemblyName = std::string(source); - std::replace_if( - assemblyName.begin(), assemblyName.end(), [](char c) { return std::isalnum(c) == 0; }, '_'); - assemblyName.append(std::to_string(fields.size())); - - import->AssemblerName() = util::UString(assemblyName, Allocator()).View(); - fields.insert(import->AssemblerName()); - imports.push_back(import); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(import->AssemblerName(), Allocator()); - auto flags = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC | ir::ModifierFlags::READONLY; - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *field = AllocNode( - fieldIdent, nullptr, - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(GlobalBuiltinDynamicType(import->Language()), Allocator()), flags, - Allocator(), false); - - classBody->push_back(field); - } - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateDynamicModuleClassInitializer(imports)); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateDynamicModuleClassInitMethod()); -} - -void ETSChecker::BuildDynamicImportClass() -{ - const auto &dynamicImports = VarBinder()->AsETSBinder()->DynamicImports(); - if (dynamicImports.empty()) { - return; - } - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - BuildClass(compiler::Signatures::DYNAMIC_MODULE_CLASS, - [this, dynamicImports](ArenaVector *classBody) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - BuildClassBodyFromDynamicImports(dynamicImports, classBody); - }); - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - EmitDynamicModuleClassInitCall(); -} - -ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInitializer(ETSObjectType *functionalInterface) -{ - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateClassInstanceInitializer( - [this](ArenaVector *statements, ArenaVector *params) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - 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( - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - jsvalueParamName.View(), AllocNode(GlobalBuiltinJSValueType(), Allocator())); - params->push_back(jsvalueParam); - // 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()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *property = AllocNode(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); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - statements->push_back(AllocNode(initializer)); - }, - functionalInterface); -} - -void ETSChecker::BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir::TypeNode *retTypeAnnotation) -{ - auto *invokeMethod = functionalInterface->GetOwnProperty( - compiler::Signatures::STATIC_INVOKE_METHOD); - auto *invokeSignature = invokeMethod->TsType()->AsETSFunctionType()->CallSignatures()[0]; - - std::stringstream ss; - ss << compiler::Signatures::LAMBDA_OBJECT; - ToString(this, invokeSignature->Params(), ss); - auto syntheticLambdaObjName = ss.str(); - if (dynamicLambdaSignatureCache_.count(syntheticLambdaObjName) != 0) { - functionalInterface->AddConstructSignature(dynamicLambdaSignatureCache_[syntheticLambdaObjName]); - return; - } - - auto buildBody = [this, invokeSignature, retTypeAnnotation, - functionalInterface](ArenaVector *classBody) { - auto assemblyName = "jsvalue_lambda"; - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(assemblyName, Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *field = AllocNode( - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - fieldIdent, nullptr, AllocNode(GlobalBuiltinJSValueType(), Allocator()), - ir::ModifierFlags::PRIVATE, Allocator(), false); - classBody->push_back(field); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateLambdaObjectClassInitializer(functionalInterface)); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - classBody->push_back(CreateLambdaObjectClassInvokeMethod(invokeSignature, retTypeAnnotation)); - }; - - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - BuildClass(util::StringView(syntheticLambdaObjName), buildBody); - - dynamicLambdaSignatureCache_[syntheticLambdaObjName] = functionalInterface->ConstructSignatures()[0]; -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/dynamic/dynamicCall.cpp b/ets2panda/checker/ets/dynamic/dynamicCall.cpp deleted file mode 100644 index a80dd1fd2d37652086e92691e3388feb4912ecd3..0000000000000000000000000000000000000000 --- a/ets2panda/checker/ets/dynamic/dynamicCall.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "checker/ets/dynamic/dynamicCall.h" - -#include "ir/ets/etsImportDeclaration.h" -#include "ir/ets/etsTypeReference.h" -#include "ir/ets/etsTypeReferencePart.h" -#include "ir/module/importSpecifier.h" -#include "ir/ts/tsQualifiedName.h" -#include "ir/expressions/memberExpression.h" - -namespace ark::es2panda::checker { - -DynamicCall::Result DynamicCall::ResolveCall(const varbinder::ETSBinder *varbinder, const ir::Expression *callee) -{ - auto calleeName = NameHolder(varbinder->Allocator()->Adapter()); - - if (callee->IsETSTypeReference()) { - // new A.B.C() => call js.new(A, ".B.C") - callee = callee->AsETSTypeReference()->Part()->Name(); - while (callee->IsTSQualifiedName()) { - auto *qname = callee->AsTSQualifiedName(); - callee = qname->Left(); - calleeName.emplace_back(qname->Right()->AsIdentifier()->Name()); - } - ES2PANDA_ASSERT(callee->IsIdentifier()); - } else if (callee->IsMemberExpression()) { - const auto memberExpr = callee->AsMemberExpression(); - callee = SqueezeExpr(memberExpr, calleeName); - } - if (callee->IsIdentifier()) { - // kinda optimization in case: - // `import X from Y` to use (load Y, call "X"), instead of (load Y, load X, call) - const auto var = callee->AsIdentifier()->Variable(); - const auto *data = varbinder->DynamicImportDataForVar(var); - if (data != nullptr && data->specifier != nullptr && data->specifier->IsImportSpecifier()) { - calleeName.emplace_back(data->specifier->AsImportSpecifier()->Imported()->Name()); - std::reverse(calleeName.begin(), calleeName.end()); - return {data->import, calleeName}; - } - } - std::reverse(calleeName.begin(), calleeName.end()); - return {callee, calleeName}; -} - -DynamicCall::Result DynamicCall::SqueezeExpr(ArenaAllocator *allocator, const ir::MemberExpression *expr) -{ - NameHolder name(allocator->Adapter()); - auto obj = SqueezeExpr(expr, name); - std::reverse(name.begin(), name.end()); - return {obj, name}; -} - -const ir::Expression *DynamicCall::SqueezeExpr(const ir::MemberExpression *memberExpr, NameHolder &name) -{ - if (!memberExpr->Object()->TsType()->IsETSDynamicType() || memberExpr->IsComputed()) { - return memberExpr; - } - ES2PANDA_ASSERT(memberExpr->Property()->IsIdentifier()); - name.emplace_back(memberExpr->Property()->AsIdentifier()->Name()); - if (memberExpr->Object()->IsMemberExpression()) { - return SqueezeExpr(memberExpr->Object()->AsMemberExpression(), name); - } - return memberExpr->Object(); -} - -} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.cpp b/ets2panda/checker/ets/etsWarningAnalyzer.cpp index 3a395fe53dfba5e5adf660ae01617a86c91343c4..f207387c3f3d1c864cf618001ad783eeda5b3e71 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.cpp +++ b/ets2panda/checker/ets/etsWarningAnalyzer.cpp @@ -34,8 +34,6 @@ #include "ir/base/classDefinition.h" #include "ir/statements/forOfStatement.h" #include "ir/statements/variableDeclarator.h" -#include "ir/statements/variableDeclaration.h" -#include "ir/expressions/updateExpression.h" namespace ark::es2panda::checker { @@ -44,7 +42,7 @@ void ETSWarningAnalyzer::AnalyzeClassDefForFinalModifier(const ir::ClassDefiniti ES2PANDA_ASSERT(classDef != nullptr); if (program_ == nullptr || classDef->IsFinal() || classDef->IsAbstract() || classDef->IsStatic() || - classDef->IsGlobal() || classDef->IsExported()) { + classDef->IsGlobal() || classDef->IsExported() || classDef->HasExportAlias()) { return; } @@ -103,10 +101,13 @@ void ETSWarningAnalyzer::AnalyzeClassMethodForFinalModifier(const ir::MethodDefi if (!potentialDescendant->IsDescendantOf(classAsETSObject)) { continue; } - const util::StringView bodyMethodName = - ETSChecker::GetSignatureFromMethodDefinition(bodyPart->AsMethodDefinition())->Function()->Id()->Name(); + auto signature = ETSChecker::GetSignatureFromMethodDefinition(bodyPart->AsMethodDefinition()); + ES2PANDA_ASSERT(signature != nullptr); + const util::StringView bodyMethodName = signature->Function()->Id()->Name(); + const auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); if (bodyPart->IsOverride() && bodyMethodName != compiler::Signatures::CTOR && - bodyMethodName == methodDef->Function()->Id()->Name()) { + bodyMethodName == func->Id()->Name()) { suggestFinal = false; break; } @@ -210,13 +211,13 @@ void ETSWarningAnalyzer::ETSWarningsProhibitTopLevelStatements(const ir::AstNode } for (const auto *itBody : classDef->Body()) { - if (!itBody->IsMethodDefinition() || + if (!itBody->IsMethodDefinition() || itBody->AsMethodDefinition()->Id() == nullptr || itBody->AsMethodDefinition()->Id()->Name() != compiler::Signatures::INIT_METHOD) { continue; } - - for (const auto *statement : - itBody->AsMethodDefinition()->Function()->Body()->AsBlockStatement()->Statements()) { + const auto *func = itBody->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + for (const auto *statement : func->Body()->AsBlockStatement()->Statements()) { if (program_->NodeContainsETSNolint(statement, ETSWarnings::ETS_PROHIBIT_TOP_LEVEL_STATEMENTS)) { continue; } @@ -270,174 +271,17 @@ void ETSWarningAnalyzer::ETSWarningRemoveLambda(const ir::AstNode *node) node->Iterate([&](auto *childNode) { ETSWarningRemoveLambda(childNode); }); } -void ETSWarningAnalyzer::CheckTypeOfBoxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - const auto flags = node->GetBoxingUnboxingFlags(); - if ((flags & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0) { - std::string diagnosticParam; - switch (static_cast(flags & ir::BoxingUnboxingFlags::BOXING_FLAG)) { - case ir::BoxingUnboxingFlags::BOX_TO_INT: - diagnosticParam = "Int"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN: - diagnosticParam = "Boolean"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_BYTE: - diagnosticParam = "Byte"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_CHAR: - diagnosticParam = "Char"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: - diagnosticParam = "Double"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_FLOAT: - diagnosticParam = "Float"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_LONG: - diagnosticParam = "Long"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_SHORT: - diagnosticParam = "Short"; - break; - default: - break; - } - - if (!diagnosticParam.empty()) { - util::DiagnosticMessageParams diagnosticParams = {diagnosticParam, GetBoxingUnboxingType(node)}; - LogWarning(diagnostic::IMPLICIT_BOXING_TO, diagnosticParams, node->Start()); - } - } -} - -void ETSWarningAnalyzer::CheckTypeOfUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - const auto flags = node->GetBoxingUnboxingFlags(); - if ((flags & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0) { - std::string diagnosticParam; - switch (static_cast(flags & ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - case ir::BoxingUnboxingFlags::UNBOX_TO_INT: - diagnosticParam = "Int"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN: - diagnosticParam = "Boolean"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_BYTE: - diagnosticParam = "Byte"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_CHAR: - diagnosticParam = "Char"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE: - diagnosticParam = "Double"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT: - diagnosticParam = "Float"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_LONG: - diagnosticParam = "Long"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_SHORT: - diagnosticParam = "Short"; - break; - default: - break; - } - - if (!diagnosticParam.empty()) { - util::DiagnosticMessageParams diagnosticParams = {diagnosticParam, GetBoxingUnboxingType(node)}; - LogWarning(diagnostic::IMPLICIT_BOXING_TO, diagnosticParams, node->Start()); - } - } -} - -void ETSWarningAnalyzer::CheckTypeOfBoxingUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - - CheckTypeOfBoxing(node); - CheckTypeOfUnboxing(node); -} - -std::string ETSWarningAnalyzer::GetBoxingUnboxingType(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node->Parent() != nullptr); - switch (node->Parent()->Type()) { - case ir::AstNodeType::VARIABLE_DECLARATOR: { - return " in Variable Declaration"; - } - case ir::AstNodeType::CALL_EXPRESSION: { - return " in Call Method/Function"; - } - case ir::AstNodeType::SWITCH_STATEMENT: { - return " in Switch-case Statement"; - } - case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { - return " in Assignment Expression"; - } - case ir::AstNodeType::BINARY_EXPRESSION: { - return " in Binary Expression"; - } - case ir::AstNodeType::UNARY_EXPRESSION: { - return " in Unary Expression"; - } - case ir::AstNodeType::UPDATE_EXPRESSION: { - return " in Update Expression"; - } - case ir::AstNodeType::MEMBER_EXPRESSION: { - return " in Member Expression"; - } - default: - return ""; - } -} - -void ETSWarningAnalyzer::ETSWarningImplicitBoxingUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - - switch (node->Type()) { - case ir::AstNodeType::VARIABLE_DECLARATOR: - case ir::AstNodeType::SWITCH_STATEMENT: - case ir::AstNodeType::CALL_EXPRESSION: - case ir::AstNodeType::BINARY_EXPRESSION: - case ir::AstNodeType::ASSIGNMENT_EXPRESSION: - case ir::AstNodeType::UNARY_EXPRESSION: - case ir::AstNodeType::UPDATE_EXPRESSION: - case ir::AstNodeType::MEMBER_EXPRESSION: { - if (!program_->NodeContainsETSNolint(node, ETSWarnings::ETS_IMPLICIT_BOXING_UNBOXING)) { - node->Iterate([this](auto *childNode) { CheckTypeOfBoxingUnboxing(childNode); }); - } - break; - } - default: { - break; - } - } - - 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..8bfecef62796f19c4c764671e35cbc7b11fdb5fd 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.h +++ b/ets2panda/checker/ets/etsWarningAnalyzer.h @@ -48,28 +48,20 @@ public: case ETSWarnings::ETS_REMOVE_LAMBDA: ETSWarningRemoveLambda(node); break; - case ETSWarnings::ETS_IMPLICIT_BOXING_UNBOXING: - ETSWarningImplicitBoxingUnboxing(node); - break; default: break; } } 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; void AnalyzeClassDefForFinalModifier(const ir::ClassDefinition *classDef); void AnalyzeClassMethodForFinalModifier(const ir::MethodDefinition *methodDef, const ir::ClassDefinition *classDef); - void CheckTypeOfBoxing(const ir::AstNode *node); - void CheckTypeOfUnboxing(const ir::AstNode *node); void CheckTopLevelExpressions(const ir::Expression *expression); void CheckProhibitedTopLevelStatements(const ir::Statement *statement); - std::string GetBoxingUnboxingType(const ir::AstNode *node); - void CheckTypeOfBoxingUnboxing(const ir::AstNode *node); void ETSWarningAnnotationUnusedGenericAliasWarn(const ir::AstNode *node); void ETSWarningSuggestFinal(const ir::AstNode *node); @@ -77,7 +69,6 @@ private: void ETSWarningBoostEqualityStatement(const ir::AstNode *node); void ETSWarningRemoveAsync(const ir::AstNode *node); void ETSWarningRemoveLambda(const ir::AstNode *node); - void ETSWarningImplicitBoxingUnboxing(const ir::AstNode *node); parser::Program *program_; util::DiagnosticEngine &diagnosticEngine_; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index adeea4b940ed1d850b018bb20284a82b3b58659c..f42c123c760130414ae1a5beef82b2a2157f2fe3 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -13,13 +13,22 @@ * limitations under the License. */ +#include + +#include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/etsTupleType.h" +#include "generated/signatures.h" +#include "checker/ets/wideningConverter.h" +#include "ir/astNodeFlags.h" #include "varbinder/ETSBinder.h" #include "checker/ETSchecker.h" #include "checker/ets/function_helpers.h" #include "checker/ets/typeRelationContext.h" -#include "checker/types/ets/etsAsyncFuncReturnType.h" +#include "checker/types/ets/etsAwaitedType.h" #include "checker/types/ets/etsObjectType.h" +#include "checker/types/ets/etsPartialTypeParameter.h" +#include "checker/types/gradualType.h" +#include "checker/types/typeError.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "ir/base/catchClause.h" #include "ir/base/classDefinition.h" @@ -29,8 +38,6 @@ #include "ir/base/spreadElement.h" #include "ir/ets/etsFunctionType.h" #include "ir/ets/etsParameterExpression.h" -#include "ir/ets/etsTypeReference.h" -#include "ir/ets/etsTypeReferencePart.h" #include "ir/expressions/arrowFunctionExpression.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/callExpression.h" @@ -52,6 +59,7 @@ #include "ir/ts/tsTypeParameterInstantiation.h" #include "parser/program/program.h" #include "util/helpers.h" +#include "util/nameMangler.h" namespace ark::es2panda::checker { @@ -77,50 +85,58 @@ bool ETSChecker::IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typ bool ETSChecker::EnhanceSubstitutionForReadonly(const ArenaVector &typeParams, ETSReadonlyType *paramType, Type *argumentType, Substitution *substitution) { - return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), GetReadonlyType(argumentType), - substitution); + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying()->MaybeBaseTypeOfGradualType(), + GetReadonlyType(argumentType), substitution); } /* A very rough and imprecise partial type inference */ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution) { + ES2PANDA_ASSERT(argumentType != nullptr); if (argumentType->IsETSPrimitiveType()) { argumentType = MaybeBoxInRelation(argumentType); } if (paramType->IsETSTypeParameter()) { - auto *const tparam = paramType->AsETSTypeParameter(); - auto *const originalTparam = tparam->GetOriginal(); + auto *const originalTparam = paramType->AsETSTypeParameter()->GetOriginal(); if (std::find(typeParams.begin(), typeParams.end(), originalTparam) != typeParams.end() && substitution->count(originalTparam) == 0) { - if (!IsReferenceType(argumentType)) { - LogError(diagnostic::INFERENCE_TYPE_INCOMPAT, {tparam, argumentType}, tparam->GetDeclNode()->Start()); - return false; - } - - // #23068 substitution happens before the constraint check, should be restored - EmplaceSubstituted(substitution, originalTparam, argumentType); - return IsCompatibleTypeArgument(tparam, argumentType, substitution); + return EnhanceSubstitutionTypeParameter(paramType->AsETSTypeParameter(), argumentType, substitution); } } - + if (paramType->IsETSNonNullishType()) { + return EnhanceSubstitutionForNonNullish(typeParams, paramType->AsETSNonNullishType(), argumentType, + substitution); + } if (paramType->IsETSFunctionType()) { return EnhanceSubstitutionForFunction(typeParams, paramType->AsETSFunctionType(), argumentType, substitution); } if (paramType->IsETSReadonlyType()) { return EnhanceSubstitutionForReadonly(typeParams, paramType->AsETSReadonlyType(), argumentType, substitution); } + if (paramType->IsETSPartialTypeParameter()) { + return EnhanceSubstitutionForPartialTypeParam(typeParams, paramType->AsETSPartialTypeParameter(), argumentType, + substitution); + } + if (paramType->IsGradualType()) { + return EnhanceSubstitutionForType(typeParams, paramType->AsGradualType()->GetBaseType(), argumentType, + substitution); + } 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); } if (paramType->IsETSArrayType()) { return EnhanceSubstitutionForArray(typeParams, paramType->AsETSArrayType(), argumentType, substitution); } - if (paramType->IsETSFunctionType()) { - return EnhanceSubstitutionForFunction(typeParams, paramType->AsETSFunctionType(), argumentType, substitution); + if (paramType->IsETSAwaitedType()) { + return EnhanceSubstitutionForAwaited(typeParams, paramType->AsETSAwaitedType(), argumentType, substitution); } return true; @@ -143,14 +159,15 @@ bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typePara if (!argumentType->IsETSUnionType()) { bool foundValid = false; for (Type *ctype : paramUn->ConstituentTypes()) { - foundValid |= ValidateTypeSubstitution(typeParams, ctype, argumentType, substitution); + foundValid |= + ValidateTypeSubstitution(typeParams, ctype->MaybeBaseTypeOfGradualType(), 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()) { @@ -221,7 +238,7 @@ static void ResetInferredNode(ETSChecker *checker) auto resetFuncState = [](ir::ArrowFunctionExpression *expr) { auto *func = expr->Function(); func->SetSignature(nullptr); - func->ReturnStatements().clear(); + func->ClearReturnStatements(); expr->SetTsType(nullptr); }; @@ -238,6 +255,31 @@ static void ResetInferredNode(ETSChecker *checker) arrowFunc->Check(checker); } +bool ETSChecker::EnhanceSubstitutionForNonNullish(const ArenaVector &typeParams, ETSNonNullishType *paramType, + Type *argumentType, Substitution *substitution) +{ + if (argumentType->IsETSNonNullishType()) { + ES2PANDA_ASSERT(argumentType->AsETSNonNullishType()->GetUnderlying() != nullptr); + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), + argumentType->AsETSNonNullishType()->GetUnderlying(), substitution); + } + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), argumentType, substitution); +} + +bool ETSChecker::EnhanceSubstitutionTypeParameter(ETSTypeParameter *paramType, Type *argumentType, + Substitution *substitution) +{ + auto *const originalTparam = paramType->GetOriginal(); + if (!IsReferenceType(argumentType)) { + LogError(diagnostic::INFERENCE_TYPE_INCOMPAT, {paramType, argumentType}, paramType->GetDeclNode()->Start()); + return false; + } + + // #23068 substitution happens before the constraint check, should be restored + EmplaceSubstituted(substitution, originalTparam, argumentType); + return IsCompatibleTypeArgument(paramType, argumentType, substitution); +} + bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeParams, ETSFunctionType *paramType, Type *argumentType, Substitution *substitution) { @@ -277,6 +319,27 @@ bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeP return res; } +bool ETSChecker::EnhanceSubstitutionForAwaited(const ArenaVector &typeParams, ETSAwaitedType *paramType, + Type *argumentType, Substitution *substitution) +{ + auto *argumentAwaitedType = + argumentType->IsETSAwaitedType() ? argumentType->AsETSAwaitedType()->GetUnderlying() : argumentType; + auto *paramAwaitedType = paramType->GetUnderlying(); + return EnhanceSubstitutionForType(typeParams, paramAwaitedType, argumentAwaitedType, substitution); +} + +bool ETSChecker::EnhanceSubstitutionForPartialTypeParam(const ArenaVector &typeParams, + ETSPartialTypeParameter *paramType, Type *argumentType, + Substitution *substitution) +{ + if (!argumentType->IsETSObjectType() || !argumentType->AsETSObjectType()->IsPartial()) { + return false; + } + ES2PANDA_ASSERT(argumentType->AsETSObjectType()->GetBaseType() != nullptr); + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), + argumentType->AsETSObjectType()->GetBaseType(), substitution); +} + // Try to find the base type somewhere in object subtypes. Incomplete, yet safe static ETSObjectType *FindEnhanceTargetInSupertypes(ETSObjectType *object, ETSObjectType *base) { @@ -333,6 +396,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) { @@ -352,7 +425,7 @@ bool ETSChecker::CheckOptionalLambdaFunction(ir::Expression *argument, Signature auto *const arrowFuncExpr = argument->AsArrowFunctionExpression(); if (ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); - CheckLambdaAssignable(substitutedSig->Function()->Params()[index], lambda)) { + CheckLambdaAssignable(substitutedSig->Params()[index]->Declaration()->Node()->AsExpression(), lambda)) { return true; } } @@ -360,28 +433,136 @@ bool ETSChecker::CheckOptionalLambdaFunction(ir::Expression *argument, Signature return false; } -bool ETSChecker::ValidateArgumentAsIdentifier(const ir::Identifier *identifier) +static bool IsInvalidArgumentAsIdentifier(varbinder::Scope *scope, const ir::Identifier *identifier) { - auto result = Scope()->Find(identifier->Name()); - return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)); + auto result = scope->Find(identifier->Name()); + return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE | + varbinder::VariableFlags::TYPE_ALIAS)); } +static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Expression *argument, Type *paramType, + TypeRelationFlag flags, bool needRecheck) +{ + if (argument->IsArrayExpression()) { + // fixed array and resizeable array will cause problem here, so clear it. + argument->AsArrayExpression()->CleanCheckInformation(); + argument->AsArrayExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); + } else if (argument->IsETSNewArrayInstanceExpression()) { + argument->AsETSNewArrayInstanceExpression()->CleanCheckInformation(); + argument->AsETSNewArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); + } else if (argument->IsETSNewMultiDimArrayInstanceExpression()) { + argument->AsETSNewMultiDimArrayInstanceExpression()->CleanCheckInformation(); + argument->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, + flags); + } else { + return; + } + if (needRecheck) { + argument->Check(checker); + } +} + +static bool CheckArrowFunctionParamIfNeeded(ETSChecker *checker, Signature *substitutedSig, + const ArenaVector &arguments, TypeRelationFlag flags) +{ + 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 (!checker->CheckLambdaAssignable(targetParm->AsETSParameterExpression(), lambda)) { + return false; + } + } + return true; +} + +// Note: (Issue27688) if lambda is trailing lambda transferred, it must be in recheck. +// in signature matching, foo(()=>void) should be the same with foo() {} +static bool HasTransferredTrailingLambda(const ArenaVector &arguments) +{ + return !arguments.empty() && arguments.back()->IsArrowFunctionExpression() && + arguments.back()->AsArrowFunctionExpression()->Function()->IsTrailingLambda(); +} + +bool ValidateRestParameter(ETSChecker *checker, Signature *signature, const ArenaVector &arguments, + const lexer::SourcePosition &pos, TypeRelationFlag flags) +{ + size_t const argCount = arguments.size(); + size_t compareCount = argCount; + auto const hasRestParameter = signature->HasRestParameter(); + auto const reportError = (flags & TypeRelationFlag::NO_THROW) == 0; + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && !signature->Params().empty() && + signature->Params().back()->Declaration()->Node()->AsETSParameterExpression()->IsOptional()) { + compareCount = compareCount - 1; + } + + if (!hasRestParameter && argCount > 0 && arguments[argCount - 1]->IsSpreadElement()) { + if (reportError) { + checker->LogError(diagnostic::ERROR_ARKTS_SPREAD_ONLY_WITH_REST, {}, pos); + } + return false; + } + if (compareCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { + if (reportError) { + checker->LogError(diagnostic::PARAM_COUNT_MISMATCH, {signature->MinArgCount(), argCount}, pos); + } + return false; + } + if (hasRestParameter && + (((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0) || HasTransferredTrailingLambda(arguments))) { + return false; + } + return !(argCount > signature->ArgCount() && hasRestParameter && + (flags & TypeRelationFlag::IGNORE_REST_PARAM) != 0); +} + +// NOTE(dkofanov): Mimics type inferrence for integer literals. Also relies on the implicit widening which occurs +// later in checker and 'CheckCastLiteral' during 'ConstantExpressionLowering'. +static void InferTypeForNumberLiteral(ETSChecker *checker, ir::NumberLiteral *argumentLiteral, Type *paramType) +{ + argumentLiteral->SetTsType(nullptr); + argumentLiteral->SetPreferredType(paramType); + auto &number = argumentLiteral->AsNumberLiteral()->Number(); + + auto *typeRel = checker->Relation(); + if (typeRel->IsSupertypeOf(checker->GlobalLongBuiltinType(), paramType)) { + number.TryNarrowTo(); + } else if (typeRel->IsSupertypeOf(checker->GlobalIntBuiltinType(), paramType)) { + number.TryNarrowTo(); + } else if (typeRel->IsSupertypeOf(checker->GlobalShortBuiltinType(), paramType)) { + number.TryNarrowTo(); + } else if (typeRel->IsSupertypeOf(checker->GlobalByteBuiltinType(), paramType)) { + number.TryNarrowTo(); + } +} + +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic 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 || HasTransferredTrailingLambda(arguments)) { + if (commonArity == 0) { + ES2PANDA_ASSERT(substitutedSig->GetSignatureInfo()->params.empty()); + return true; + } + commonArity = commonArity - 1; + } for (size_t index = 0; index < commonArity; ++index) { auto &argument = arguments[index]; // #22952: infer optional parameter heuristics - auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType()); + auto const paramType = + GetNonNullishType(substitutedSig->Params()[index]->TsType())->MaybeBaseTypeOfGradualType(); if (argument->IsObjectExpression()) { - if (paramType->IsETSObjectType()) { - // No chance to check the argument at this point - continue; + ES2PANDA_ASSERT(paramType != nullptr); + if (!paramType->IsETSObjectType()) { + return false; } - return false; + if (paramType->AsETSObjectType()->IsBoxedPrimitive()) { + return false; + } + argument->SetPreferredType(paramType); } if (argument->IsMemberExpression()) { @@ -391,25 +572,25 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, LogError(diagnostic::SPREAD_ONTO_SINGLE_PARAM, {}, argument->Start()); } return false; + } else if (argument->IsNumberLiteral()) { + InferTypeForNumberLiteral(this, argument->AsNumberLiteral(), paramType); } if (argTypeInferenceRequired[index]) { ES2PANDA_ASSERT(argument->IsArrowFunctionExpression()); - auto *const arrowFuncExpr = argument->AsArrowFunctionExpression(); // Note: If the signatures are from lambdas, then they have no `Function`. - ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); + ir::ScriptFunction *const lambda = argument->AsArrowFunctionExpression()->Function(); auto targetParm = substitutedSig->GetSignatureInfo()->params[index]->Declaration()->Node(); + ERROR_SANITY_CHECK(this, targetParm->IsETSParameterExpression(), return false); 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())) { + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); return false; } @@ -420,7 +601,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, } } - return true; + return CheckArrowFunctionParamIfNeeded(this, substitutedSig, arguments, flags); } bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, @@ -430,7 +611,7 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Type *argumentType = argument->Check(this); - flags |= TypeRelationFlag::ONLY_CHECK_WIDENING; + flags |= (TypeRelationFlag::ONLY_CHECK_WIDENING); auto const invocationCtx = checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), @@ -442,13 +623,29 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i bool ETSChecker::IsValidRestArgument(ir::Expression *const argument, Signature *const substitutedSig, const TypeRelationFlag flags, const std::size_t index) { - const auto argumentType = argument->Check(this); - auto *targetType = substitutedSig->RestVar()->TsType(); - if (targetType->IsETSTupleType()) { + auto *restParamType = substitutedSig->RestVar()->TsType(); + if (restParamType->IsETSTupleType()) { return false; } + if (argument->IsObjectExpression()) { + argument->SetPreferredType(GetElementTypeOfArray(restParamType)); + // Object literals should be checked separately afterwards after call resolution + return true; + } + + // Set preferred type for array expressions before checking, similar to spread elements + if (argument->IsArrayExpression()) { + if (!SetPreferredTypeForArrayArgument(argument->AsArrayExpression(), substitutedSig)) { + return false; + } + } - targetType = substitutedSig->RestVar()->TsType()->AsETSArrayType()->ElementType(); + const auto argumentType = argument->Check(this); + if (argument->HasAstNodeFlags(ir::AstNodeFlags::RESIZABLE_REST)) { + return true; + } + + auto targetType = GetElementTypeOfArray(restParamType); if (substitutedSig->OwnerVar() == nullptr) { targetType = MaybeBoxType(targetType); } @@ -456,7 +653,35 @@ bool ETSChecker::IsValidRestArgument(ir::Expression *const argument, Signature * Relation(), argument, argumentType, targetType, argument->Start(), {{diagnostic::REST_PARAM_INCOMPAT_AT, {argumentType, targetType, index + 1}}}, flags); - return invocationCtx.IsInvocable(); + bool result = invocationCtx.IsInvocable(); + // Clear preferred type if invocation fails, similar to spread elements + if (!result && argument->IsArrayExpression()) { + ModifyPreferredType(argument->AsArrayExpression(), nullptr); + } + + return result; +} + +bool ETSChecker::SetPreferredTypeForArrayArgument(ir::ArrayExpression *arrayExpr, Signature *substitutedSig) +{ + auto *const restVarType = substitutedSig->RestVar()->TsType(); + if (!restVarType->IsETSArrayType() && !restVarType->IsETSResizableArrayType()) { + return true; + } + auto targetType = GetElementTypeOfArray(restVarType); + if (substitutedSig->OwnerVar() == nullptr) { + targetType = MaybeBoxType(targetType); + } + // Validate tuple size before setting preferred type + if (targetType->IsETSTupleType()) { + auto *tupleType = targetType->AsETSTupleType(); + if (tupleType->GetTupleSize() != arrayExpr->Elements().size()) { + // Size mismatch - don't set preferred type, this will cause a type error + return false; + } + } + arrayExpr->SetPreferredType(targetType); + return true; } bool ETSChecker::ValidateSignatureRestParams(Signature *substitutedSig, const ArenaVector &arguments, @@ -491,10 +716,9 @@ 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 (restArgument->IsArrayExpression()) { - restArgument->AsArrayExpression()->SetPreferredType(targetType); - } - auto const argumentType = restArgument->Check(this); + restArgument->SetPreferredType(targetType); + argument->Check(this); + auto const argumentType = restArgument->TsType(); auto const invocationCtx = checker::InvocationContext( Relation(), restArgument, argumentType, substitutedSig->RestVar()->TsType(), argument->Start(), @@ -521,7 +745,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) + ((flags & TypeRelationFlag::NO_SUBSTITUTION_NEEDED) != 0U) ? baseSignature : MaybeSubstituteTypeParameters(this, baseSignature, typeArguments, arguments, pos, flags); if (signature == nullptr) { @@ -529,20 +753,12 @@ Signature *ETSChecker::ValidateSignature( } size_t const argCount = arguments.size(); - auto const hasRestParameter = signature->RestVar() != nullptr; + auto const hasRestParameter = signature->HasRestParameter(); auto const reportError = (flags & TypeRelationFlag::NO_THROW) == 0; - if (argCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { - if (reportError) { - LogError(diagnostic::PARAM_COUNT_MISMATCH, {signature->MinArgCount(), argCount}, pos); - } - return nullptr; - } - - if (argCount > signature->ArgCount() && hasRestParameter && (flags & TypeRelationFlag::IGNORE_REST_PARAM) != 0) { + if (!ValidateRestParameter(this, signature, arguments, pos, flags)) { return nullptr; } - auto count = std::min(signature->ArgCount(), argCount); // Check all required formal parameter(s) first // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -602,35 +818,43 @@ 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, }; } +// CC-OFFNXT(huge_method) solid logic ArenaVector ETSChecker::CollectSignatures(ArenaVector &signatures, const ir::TSTypeParameterInstantiation *typeArguments, 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; + if (signatures.size() > 1) { + resolveFlags |= TypeRelationFlag::OVERLOADING_CONTEXT; + } + auto collectSignatures = [&](TypeRelationFlag relationFlags) { for (auto *sig : signatures) { if (notVisibleSignature != nullptr && !IsSignatureAccessible(sig, Context().ContainingClass(), Relation())) { continue; } + if (sig->HasSignatureFlag(SignatureFlags::BRIDGE)) { + // Bridges are never invoked direcly + continue; + } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *concreteSig = ValidateSignature(std::make_tuple(sig, typeArguments, relationFlags), arguments, pos, argTypeInferenceRequired, signatures.size() == 1); @@ -649,25 +873,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; } } @@ -678,6 +892,19 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector return compatibleSignatures; } +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); + } +} + Signature *ETSChecker::GetMostSpecificSignature(ArenaVector &compatibleSignatures, const ArenaVector &arguments, const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags) @@ -696,10 +923,13 @@ Signature *ETSChecker::GetMostSpecificSignature(ArenaVector &compat return nullptr; } + // revalidate signature for arrays + UpdateArrayArgsAndUnboxingFlags(this, mostSpecificSignature, arguments); + return mostSpecificSignature; } -void ETSChecker::ThrowSignatureMismatch(ArenaVector &signatures, +void ETSChecker::ThrowSignatureMismatch(ArenaVector const &signatures, const ArenaVector &arguments, const lexer::SourcePosition &pos, std::string_view signatureKind) { @@ -709,7 +939,7 @@ void ETSChecker::ThrowSignatureMismatch(ArenaVector &signatures, if (someSignature->HasFunction()) { if (someSignature->Function()->IsConstructor()) { - msg.append(util::Helpers::GetClassDefiniton(someSignature->Function())->InternalName().Mutf8()); + msg.append(util::Helpers::GetClassDefinition(someSignature->Function())->InternalName().Mutf8()); } else { msg.append(someSignature->Function()->Id()->Name().Mutf8()); } @@ -750,7 +980,18 @@ Signature *ETSChecker::ValidateSignatures(ArenaVector &signatures, auto compatibleSignatures = CollectSignatures(signatures, typeArguments, arguments, pos, resolveFlags); if (!compatibleSignatures.empty()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return GetMostSpecificSignature(compatibleSignatures, arguments, pos, resolveFlags); + auto *sig = GetMostSpecificSignature(compatibleSignatures, arguments, pos, resolveFlags); + // NOTE (DZ): skip Promise constructor/then/catch check - + // temporary solution, need to be removed after fixing OHOS code! + if (sig == nullptr || !sig->HasFunction() || + !(sig->Function()->IsConstructor() || sig->Function()->Id()->Name().Is("then") || + sig->Function()->Id()->Name().Is("catch")) || + !sig->Owner()->Name().Is("Promise")) { + // May need to re-check the arguments now that we know the particular signature to call. + ValidateSignature({sig, nullptr, TypeRelationFlag::WIDENING | TypeRelationFlag::NO_SUBSTITUTION_NEEDED}, + arguments, pos, FindTypeInferenceArguments(arguments), true); + } + return sig; } if ((resolveFlags & TypeRelationFlag::NO_THROW) == 0) { @@ -760,6 +1001,16 @@ Signature *ETSChecker::ValidateSignatures(ArenaVector &signatures, return nullptr; } +// Excluded from 'FindMostSpecificSignature' to reduce its size due to code-style check +static std::size_t GetParameterNumber(Signature const *const sig) +{ + if (sig->HasFunction()) { + return sig->Function()->Params().size(); + } + auto num = sig->Params().size(); + return !sig->HasRestParameter() ? num : ++num; +} + Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector &signatures, const ArenaMultiMap &bestSignaturesForParameter, size_t paramCount) @@ -774,6 +1025,8 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector return true; }; + auto isGeneric = [](const Signature *sig) { return sig->TypeParams().empty(); }; + Signature *result = nullptr; size_t currentMinLength = SIZE_MAX; @@ -782,23 +1035,34 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector continue; } - const auto candidateLength = candidate->Function()->Params().size(); - if (candidateLength > currentMinLength) { + const auto candidateLength = GetParameterNumber(candidate); + if (candidateLength > currentMinLength && !candidate->HasRestParameter()) { continue; } if (result == nullptr) { result = candidate; // First valid candidate - currentMinLength = result->Function()->Params().size(); + currentMinLength = GetParameterNumber(result); continue; } - const auto currentLength = result->Function()->Params().size(); - if (candidateLength < currentLength) { + const auto currentLength = GetParameterNumber(result); + 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) { - // Ambiguous resolution for same-length params + currentMinLength = GetParameterNumber(result); + } else if (candidateLength >= currentLength) { + continue; + // NOTE (smartin): all other cases below are unreachable code + } else if (!isGeneric(candidate) && isGeneric(result)) { + result = candidate; + } else if (isGeneric(candidate) && !isGeneric(result)) { + continue; + } else { + // Ambiguous resolution for same-length params, same genericity if (result->Owner() == candidate->Owner()) { result = nullptr; } @@ -808,44 +1072,121 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector return result; } -static Type *GetParatmeterTypeOrRestAtIdx(Signature *sig, const size_t idx) +static Type *GetParameterTypeOrRestAtIdx(checker::ETSChecker *checker, Signature *sig, const size_t idx) { - return idx < sig->ArgCount() ? sig->Params().at(idx)->TsType() - : sig->RestVar()->TsType()->AsETSArrayType()->ElementType(); + return idx < sig->ArgCount() + ? sig->Params().at(idx)->TsType()->MaybeBaseTypeOfGradualType() + : checker->GetElementTypeOfArray(sig->RestVar()->TsType())->MaybeBaseTypeOfGradualType(); } -static void InitMostSpecificType(const ArenaVector &signatures, [[maybe_unused]] Type *&mostSpecificType, - [[maybe_unused]] Signature *&prevSig, const size_t idx) +static void InitMostSpecificType(TypeRelation *relation, const ArenaVector &signatures, + Type *&mostSpecificType, Signature *&prevSig, const size_t idx) { + // Attempt to choose the widest type of available ones + SavedTypeRelationFlagsContext ctx {relation, TypeRelationFlag::WIDENING | TypeRelationFlag::ONLY_CHECK_WIDENING}; + auto checker = relation->GetChecker()->AsETSChecker(); for (auto *sig : signatures) { - if (Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, idx); - sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + Type *sigType = GetParameterTypeOrRestAtIdx(checker, sig, idx); + relation->Result(false); + + if (sigType->IsETSObjectType()) { + if (sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + continue; + } + if (!sigType->AsETSObjectType()->IsBoxedPrimitive()) { + // Found "non-primitive" ref type + mostSpecificType = sigType; + prevSig = sig; + return; + } + relation->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + if (relation->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { + mostSpecificType = sigType; + prevSig = sig; + continue; + } + } + if (sigType->IsETSFunctionType() && relation->IsSupertypeOf(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; - return; + continue; + } + relation->Result(false); + WideningConverter(checker, relation, sigType, mostSpecificType); + if (relation->IsTrue()) { + mostSpecificType = sigType; + prevSig = sig; + continue; } } } +void ETSChecker::CheckAmbiguousCall(Type *&mostSpecificType, Type *sigType, Signature *prevSig, Signature *sig, + const lexer::SourcePosition &pos) +{ + if (((sigType->IsETSObjectType() && mostSpecificType->IsETSObjectType()) || + (sigType->IsETSUnionType() && mostSpecificType->IsETSUnionType() && + ((Relation()->IsSupertypeOf(sigType->AsETSUnionType(), GlobalETSNullType()) && + Relation()->IsSupertypeOf(mostSpecificType->AsETSUnionType(), GlobalETSNullType())) || + // CC-OFFNXT(G.FMT.02-CPP) project code style + (Relation()->IsSupertypeOf(sigType->AsETSUnionType(), GlobalETSUndefinedType()) && + Relation()->IsSupertypeOf(mostSpecificType->AsETSUnionType(), GlobalETSUndefinedType()))))) && + !Relation()->IsAssignableTo(mostSpecificType, sigType) && + !Relation()->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { + auto funcName = sig->Function()->Id()->Name(); + LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); + } +} + void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType) { auto [pos, idx, sig] = info; - Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, idx); + Type *sigType = GetParameterTypeOrRestAtIdx(this, sig, idx); + if (prevSig->HasFunction() && prevSig->Function()->Params()[idx]->IsETSParameterExpression()) { + Relation()->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + } const bool isClassType = sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE); if (isClassType == lookForClassType) { if (Relation()->IsIdenticalTo(sigType, mostSpecificType)) { + Relation()->SetNode(nullptr); return; } + + if (idx >= prevSig->MinArgCount() && idx < sig->MinArgCount()) { + // NOTE (smartin): prefer non-optional parameters over optional ones + Relation()->Result(true); + mostSpecificType = sigType; + prevSig = sig; + return; + } + + if (isClassType && sigType->AsETSObjectType()->IsBoxedPrimitive() && mostSpecificType->IsETSObjectType() && + mostSpecificType->AsETSObjectType()->IsBoxedPrimitive()) { + // NOTE (smartin): when a param with type int is available, make it more specific than other primitive + // types. The making of correct rules for this is still in progress in spec, so this is a temp solution. + if (mostSpecificType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { + return; + } + + TypeRelationFlag flags = TypeRelationFlag::NO_THROW | TypeRelationFlag::UNBOXING | + TypeRelationFlag::BOXING | TypeRelationFlag::WIDENING; + Relation()->SetFlags(flags); + if (sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_INT) || + Relation()->IsLegalBoxedPrimitiveConversion(mostSpecificType, sigType)) { + Relation()->Result(true); + mostSpecificType = sigType; + prevSig = sig; + return; + } + } if (Relation()->IsAssignableTo(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; - } else if (sigType->IsETSObjectType() && mostSpecificType->IsETSObjectType() && - !Relation()->IsAssignableTo(mostSpecificType, sigType)) { - auto funcName = sig->Function()->Id()->Name(); - LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); + } else { + CheckAmbiguousCall(mostSpecificType, sigType, prevSig, sig, pos); } } } @@ -862,6 +1203,7 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( for (auto *sig : signatures) { auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + ES2PANDA_ASSERT(sigParamType != nullptr); if (!sigParamType->IsETSFunctionType()) { continue; } @@ -874,6 +1216,7 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( for (auto *sig : signatures) { auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + ES2PANDA_ASSERT(sigParamType != nullptr); if (!sigParamType->IsETSFunctionType()) { continue; } @@ -888,8 +1231,9 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( } for (auto *sig : signatures) { - if (paramIdx >= sig->Params().size() || !sig->Params().at(paramIdx)->TsType()->IsETSObjectType() || - !sig->Params().at(paramIdx)->TsType()->AsETSObjectType()->IsGlobalETSObjectType()) { + auto paramType = sig->Params().at(paramIdx)->TsType()->MaybeBaseTypeOfGradualType(); + if (paramIdx >= sig->Params().size() || !paramType->IsETSObjectType() || + !paramType->AsETSObjectType()->IsGlobalETSObjectType()) { bestSignaturesForParameter.insert({paramIdx, sig}); } } @@ -900,7 +1244,7 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter 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); @@ -920,7 +1264,9 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter Type *mostSpecificType = signatures.front()->Params().at(i)->TsType(); Signature *prevSig = signatures.front(); - InitMostSpecificType(signatures, mostSpecificType, prevSig, i); + // NOTE: first we choose the some signature with possibly widest argumetns' types + // Then we search for the most specific signature + InitMostSpecificType(Relation(), signatures, mostSpecificType, prevSig, i); for (auto *sig : signatures) { SearchAmongMostSpecificTypes(mostSpecificType, prevSig, std::make_tuple(pos, i, sig), true); } @@ -929,8 +1275,9 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter } for (auto *sig : signatures) { - Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, i); - if (Relation()->IsIdenticalTo(sigType, mostSpecificType)) { + Type *sigType = GetParameterTypeOrRestAtIdx(this, sig, i); + if (Relation()->IsIdenticalTo(sigType, mostSpecificType) || + (sigType->IsETSFunctionType() && Relation()->IsSupertypeOf(sigType, mostSpecificType))) { bestSignaturesForParameter.insert({i, sig}); } } @@ -966,8 +1313,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; @@ -986,7 +1337,7 @@ Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &sig return mostSpecificSignature; } -static bool IsLastParameterLambdaWithReceiver(Signature *sig) +static bool IsLastParameterLambdaWithReceiver(Signature const *sig) { auto const ¶ms = sig->Function()->Params(); @@ -1000,10 +1351,14 @@ 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 (!sig->HasFunction()) { + continue; + } + if (!IsLastParameterLambdaWithReceiver(sig)) { normalSig.emplace_back(sig); continue; @@ -1012,7 +1367,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, @@ -1022,7 +1377,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", @@ -1058,13 +1413,40 @@ 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); + newVar->SetTsType(declNode->AsMethodDefinition()->TsType()->Clone(this)); callIdentifier->SetVariable(newVar); } +Signature *ETSChecker::MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr) +{ + if (sig == nullptr) { + return nullptr; + } + std::size_t const argumentCount = callExpr->Arguments().size(); + std::size_t const parameterCount = sig->Params().size(); + auto count = std::min(parameterCount, argumentCount); + for (std::size_t idx = 0; idx < count; ++idx) { + // Kludge to make promise code compile + if (callExpr->Arguments().at(idx)->IsArrowFunctionExpression()) { + continue; + } + + auto ctx = checker::AssignmentContext( + Relation(), callExpr->Arguments().at(idx), callExpr->Arguments().at(idx)->TsType(), + sig->Params().at(idx)->TsType(), callExpr->Arguments().at(idx)->Start(), + {{diagnostic::INVALID_ASSIGNMNENT, + {callExpr->Arguments().at(idx)->TsType(), sig->Params().at(idx)->TsType()}}}); + if (!ctx.IsAssignable()) { + return nullptr; + } + } + return sig; +} + Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, @@ -1074,6 +1456,7 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorTypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); UpdateDeclarationFromSignature(callExpr, sig); return sig; } @@ -1086,13 +1469,15 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorArguments()); + TrailingLambdaTypeInference(sig, callExpr->Arguments()); UpdateDeclarationFromSignature(callExpr, sig); + callExpr->SetIsTrailingCall(true); return sig; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) sig = ValidateSignatures(signatures, callExpr->TypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); if (sig != nullptr) { EnsureValidCurlyBrace(callExpr); } @@ -1104,6 +1489,15 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVector &arguments, const lexer::SourcePosition &pos) { + auto *var = type->GetProperty(compiler::Signatures::CONSTRUCTOR_NAME, PropertySearchFlags::SEARCH_STATIC_METHOD); + if (var != nullptr && var->TsType()->IsETSFunctionType()) { + auto sig = MatchOrderSignatures(var->TsType()->AsETSFunctionType()->CallSignatures(), nullptr, arguments, pos, + TypeRelationFlag::NONE); + if (sig == nullptr) { + ThrowOverloadMismatch(type->Name(), arguments, pos, "construct"); + } + return sig; + } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return ValidateSignatures(type->ConstructSignatures(), nullptr, arguments, pos, "construct"); } @@ -1122,13 +1516,14 @@ 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()); } - arguments[index]->AsObjectExpression()->SetPreferredType(tp); + arguments[index]->SetPreferredType(tp); arguments[index]->Check(this); } } @@ -1136,23 +1531,35 @@ 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(); - + if (currentFunc->IsDeclare() != ldInfo.isDeclare) { + checker->LogError(diagnostic::AMBIGUOUS_AMBIENT, {currentFunc->Id()->Name()}, currentFunc->Start()); + method->Id()->Variable()->SetTsType(checker->GlobalTypeError()); + return false; + } + ES2PANDA_ASSERT(currentFunc->Function() != nullptr); + ES2PANDA_ASSERT(currentFunc->Id() != nullptr); currentFunc->Function()->Id()->SetVariable(currentFunc->Id()->Variable()); checker->BuildFunctionSignature(currentFunc->Function(), method->IsConstructor()); if (currentFunc->Function()->Signature() == nullptr) { - method->Id()->Variable()->SetTsType(checker->GlobalTypeError()); + auto *methodId = method->Id(); + ES2PANDA_ASSERT(methodId != nullptr); + methodId->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()) { @@ -1185,30 +1592,35 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) if (method->TsType() != nullptr) { return method->TsType()->AsETSFunctionType(); } - - method->Function()->Id()->SetVariable(method->Id()->Variable()); + auto *methodId = method->Id(); + ES2PANDA_ASSERT(methodId != nullptr); + ES2PANDA_ASSERT(method->Function() != nullptr); + if (methodId->AsIdentifier()->IsErrorPlaceHolder()) { + return methodId->Variable()->SetTsType(GlobalTypeError()); + } + method->Function()->Id()->SetVariable(methodId->Variable()); BuildFunctionSignature(method->Function(), method->IsConstructor()); if (method->Function()->Signature() == nullptr) { - return method->Id()->Variable()->SetTsType(GlobalTypeError()); + return methodId->Variable()->SetTsType(GlobalTypeError()); } auto *funcType = BuildMethodType(method->Function()); method->InitializeOverloadInfo(); 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); + return methodId->Variable()->SetTsType(funcType); } bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *const currentFunc, bool omitSameAsm) + const ir::MethodDefinition *const currentFunc, bool omitSameAsm, + TypeRelationFlag relationFlags) { // Don't necessary to check overload for invalid functions if (func->Name().Is(ERROR_LITERAL)) { @@ -1216,7 +1628,7 @@ bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType return false; } - SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), TypeRelationFlag::NO_RETURN_TYPE_CHECK); + SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), relationFlags); Relation()->SignatureIsIdenticalTo(func->CallSignatures()[0], overload->CallSignatures()[0]); if (Relation()->IsTrue() && func->CallSignatures()[0]->GetSignatureInfo()->restVar == @@ -1290,10 +1702,6 @@ static varbinder::LocalVariable *SetupSignatureParameter(ir::ETSParameterExpress // Should be moved to original ComposeSignatureInfo after AST fix static bool AppendSignatureInfoParam(ETSChecker *checker, SignatureInfo *sigInfo, ir::ETSParameterExpression *param) { - if (param->IsRestParameter()) { - return true; - } - auto variable = SetupSignatureParameter(param, [checker, param]() { if (param->TypeAnnotation() != nullptr) { auto type = param->TypeAnnotation()->GetType(checker); @@ -1312,13 +1720,19 @@ static bool AppendSignatureInfoParam(ETSChecker *checker, SignatureInfo *sigInfo if (variable == nullptr) { // #23134 return false; } + if (param->IsRestParameter()) { + return true; + } sigInfo->params.push_back(variable); if (!param->IsOptional()) { ++sigInfo->minArgCount; } - ES2PANDA_ASSERT(!param->IsOptional() || - checker->Relation()->IsSupertypeOf(param->Ident()->TsType(), checker->GlobalETSUndefinedType())); + ERROR_SANITY_CHECK( + checker, + !param->IsOptional() || param->Ident()->TsType()->IsTypeError() || + checker->Relation()->IsSupertypeOf(param->Ident()->TsType(), checker->GlobalETSUndefinedType()), + return false); return true; } @@ -1329,6 +1743,7 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::TSTypeParameterDeclaration * if (typeParams != nullptr) { auto [typeParamTypes, ok] = CreateUnconstrainedTypeParameters(typeParams); + ES2PANDA_ASSERT(signatureInfo != nullptr); signatureInfo->typeParams = std::move(typeParamTypes); if (ok) { AssignTypeParameterConstraints(typeParams); @@ -1345,11 +1760,21 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::TSTypeParameterDeclaration * if (!params.empty()) { if (auto param = params.back()->AsETSParameterExpression(); param->IsRestParameter()) { - if (param->TypeAnnotation() == nullptr) { // #23134 - ES2PANDA_ASSERT(IsAnyError()); + checker::Type *restParamType = nullptr; + if (param->TypeAnnotation() != nullptr) { + restParamType = param->RestParameter()->TypeAnnotation()->GetType(this); + } else if (param->Ident()->TsType() != nullptr) { + restParamType = param->Ident()->TsType(); + } else { + ES2PANDA_ASSERT(IsAnyError()); // #23134 return nullptr; } - signatureInfo->restVar = SetupSignatureParameter(param, param->TypeAnnotation()->GetType(this)); + ES2PANDA_ASSERT(restParamType != nullptr); + if (!restParamType->IsAnyETSArrayOrTupleType()) { + LogError(diagnostic::ONLY_ARRAY_OR_TUPLE_FOR_REST, {}, param->Start()); + restParamType = GlobalTypeError(); + } + signatureInfo->restVar = SetupSignatureParameter(param, restParamType); ES2PANDA_ASSERT(signatureInfo->restVar != nullptr); } } @@ -1380,10 +1805,20 @@ void ETSChecker::ValidateMainSignature(ir::ScriptFunction *func) void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig) { + ES2PANDA_ASSERT(func != nullptr); bool isArrow = func->IsArrow(); + // note(Ekko): For extenal function overload, need to not change ast tree, for arrow type, need perferred type. + if (func->Signature() != nullptr && !isArrow) { + 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()); @@ -1415,19 +1850,16 @@ void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstru } VarBinder()->AsETSBinder()->BuildFunctionName(func); + Program()->AddToFunctionScopes(func->Scope()); } checker::ETSFunctionType *ETSChecker::BuildMethodType(ir::ScriptFunction *func) { ES2PANDA_ASSERT(!func->IsArrow()); + ES2PANDA_ASSERT(func != nullptr); auto *nameVar = func->Id()->Variable(); - ETSFunctionType *funcType; - if (func->IsDynamic()) { - funcType = CreateETSDynamicMethodType(nameVar->Name(), {{func->Signature()}, Allocator()->Adapter()}, - func->Language()); - } else { - funcType = CreateETSMethodType(nameVar->Name(), {{func->Signature()}, Allocator()->Adapter()}); - } + ETSFunctionType *funcType = + CreateETSMethodType(nameVar->Name(), {{func->Signature()}, ProgramAllocator()->Adapter()}); funcType->SetVariable(nameVar); return funcType; } @@ -1443,7 +1875,7 @@ Signature *ETSChecker::CheckEveryAbstractSignatureIsOverridden(ETSFunctionType * for (auto sourceSig : source->CallSignatures()) { if ((*targetSig)->Function()->Id()->Name() == sourceSig->Function()->Id()->Name() && Relation()->SignatureIsSupertypeOf(*targetSig, sourceSig)) { - target->CallSignatures().erase(targetSig); + targetSig = target->CallSignatures().erase(targetSig); isOverridden = true; break; } @@ -1555,14 +1987,14 @@ Signature *ETSChecker::AdjustForTypeParameters(Signature *source, Signature *tar if (sourceTypeParams.empty()) { return target; } - auto *substitution = NewSubstitution(); + auto substitution = Substitution {}; for (size_t ix = 0; ix < sourceTypeParams.size(); ix++) { if (!targetTypeParams[ix]->IsETSTypeParameter()) { continue; } - EmplaceSubstituted(substitution, targetTypeParams[ix]->AsETSTypeParameter(), sourceTypeParams[ix]); + EmplaceSubstituted(&substitution, targetTypeParams[ix]->AsETSTypeParameter(), sourceTypeParams[ix]); } - return target->Substitute(Relation(), substitution); + return target->Substitute(Relation(), &substitution); } void ETSChecker::ReportOverrideError(Signature *signature, Signature *overriddenSignature, @@ -1634,7 +2066,7 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) auto *target = site->GetProperty(signature->Function()->Id()->Name(), flags); bool isOverridingAnySignature = false; - if (target == nullptr) { + if (target == nullptr || target->TsType() == nullptr || target->TsType()->IsTypeError()) { return isOverridingAnySignature; } @@ -1679,7 +2111,9 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) void ETSChecker::CheckOverride(Signature *signature) { + ES2PANDA_ASSERT(signature != nullptr); auto *owner = signature->Owner(); + ES2PANDA_ASSERT(owner != nullptr); bool isOverriding = false; if (!owner->HasObjectFlag(ETSObjectFlags::CLASS | ETSObjectFlags::INTERFACE)) { @@ -1887,49 +2321,43 @@ bool ETSChecker::IsReturnTypeSubstitutable(Signature *const s1, Signature *const std::string ETSChecker::GetAsyncImplName(const util::StringView &name) { - std::string implName(name); - implName += "$asyncimpl"; - return implName; + std::string newName = + util::NameMangler::GetInstance()->CreateMangledNameByTypeAndName(util::NameMangler::ASYNC, name); + return newName; } std::string ETSChecker::GetAsyncImplName(ir::MethodDefinition *asyncMethod) { - ir::Identifier *asyncName = asyncMethod->Function()->Id(); + ir::ScriptFunction *scriptFunc = asyncMethod->Function(); + CHECK_NOT_NULL(scriptFunc); + ir::Identifier *asyncName = scriptFunc->Id(); ES2PANDA_ASSERT_POS(asyncName != nullptr, asyncMethod->Start()); return GetAsyncImplName(asyncName->Name()); } -bool ETSChecker::IsAsyncImplMethod(ir::MethodDefinition const *method) -{ - auto methodName = method->Key()->AsIdentifier()->Name().Utf8(); - std::string_view asyncSuffix = "$asyncimpl"; - if (methodName.size() < asyncSuffix.size()) { - return false; - } - return methodName.substr(methodName.size() - asyncSuffix.size()) == asyncSuffix; -} - ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir::ModifierFlags modifiers, ir::ScriptFunctionFlags flags, ArenaVector &¶ms, varbinder::FunctionParamScope *paramScope, ir::TypeNode *returnType, 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 + ES2PANDA_ASSERT(func != nullptr); func->SetScope(scope); func->SetIdent(nameId); if (body != nullptr && body->IsBlockStatement()) { body->AsBlockStatement()->SetScope(scope); } + ES2PANDA_ASSERT(scope != nullptr); scope->BindNode(func); paramScope->BindNode(func); scope->BindParamScope(paramScope); @@ -1942,12 +2370,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; } @@ -1960,7 +2390,9 @@ varbinder::FunctionParamScope *ETSChecker::CopyParams( for (auto *const it : params) { auto *const paramOld = it->AsETSParameterExpression(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const paramNew = paramOld->Clone(Allocator(), paramOld->Parent())->AsETSParameterExpression(); + auto *typeOld = paramOld->Clone(ProgramAllocator(), paramOld->Parent()); + ES2PANDA_ASSERT(typeOld != nullptr); + auto *const paramNew = typeOld->AsETSParameterExpression(); varbinder::Variable *var = VarBinder()->AddParamDecl(paramNew); Type *paramType = paramOld->Variable()->TsType(); @@ -2026,11 +2458,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); @@ -2048,17 +2477,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); @@ -2067,8 +2497,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); @@ -2076,14 +2506,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); } @@ -2091,22 +2532,25 @@ 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)); + ES2PANDA_ASSERT(body != nullptr); 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}); + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetScope(funcScope); funcScope->BindNode(funcNode); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *arrowFuncNode = AllocNode(funcNode, Allocator()); + auto *arrowFuncNode = ProgramAllocNode(funcNode, ProgramAllocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetParent(callExpr); ArenaVector fakeArguments = callExpr->Arguments(); @@ -2145,13 +2589,19 @@ void ETSChecker::CacheFunctionalInterface(ir::ETSFunctionType *type, ETSObjectTy functionalInterfaceCache_.emplace(hash, ifaceType); } -void ETSChecker::CollectReturnStatements(ir::AstNode *parent) +void ETSChecker::CollectReturnStatements(ir::AstNode *parent) // NOTE: remove with #28178 { parent->Iterate([this](ir::AstNode *childNode) -> void { if (childNode->IsScriptFunction()) { return; } + auto scope = Scope(); + if (childNode->IsBlockStatement()) { + scope = childNode->AsBlockStatement()->Scope(); + } + checker::ScopeContext scopeCtx(this, scope); + if (childNode->IsReturnStatement()) { ir::ReturnStatement *returnStmt = childNode->AsReturnStatement(); returnStmt->Check(this); @@ -2161,7 +2611,7 @@ void ETSChecker::CollectReturnStatements(ir::AstNode *parent) }); } -ArenaVector &ETSChecker::PendingConstraintCheckRecords() +std::vector &ETSChecker::PendingConstraintCheckRecords() { return pendingConstraintCheckRecords_; } @@ -2171,30 +2621,23 @@ size_t &ETSChecker::ConstraintCheckScopesCount() return constraintCheckScopesCount_; } -bool ETSChecker::CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept +bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept { - for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { - std::stringstream s1; - std::stringstream s2; - sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s1); - sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s2); - if (s1.str() != s2.str()) { - return false; - break; - } + if (sig1->ReturnType()->ToAssemblerTypeWithRank() != sig2->ReturnType()->ToAssemblerTypeWithRank()) { + return false; } - return true; -} -bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept -{ if (sig1->ArgCount() != sig2->ArgCount()) { return false; } - if (!CmpAssemblerTypesWithRank(sig1, sig2)) { - return false; + for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { + if (sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank() != + sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank()) { + return false; + } } + auto *rv1 = sig1->RestVar(); auto *rv2 = sig2->RestVar(); if (rv1 == nullptr && rv2 == nullptr) { @@ -2203,11 +2646,8 @@ bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature if (rv1 == nullptr || rv2 == nullptr) { // exactly one of them is null return false; } - std::stringstream s1; - std::stringstream s2; - rv1->TsType()->ToAssemblerTypeWithRank(s1); - rv2->TsType()->ToAssemblerTypeWithRank(s2); - return s1.str() == s2.str(); + + return (rv1->TsType()->ToAssemblerTypeWithRank() == rv2->TsType()->ToAssemblerTypeWithRank()); } bool ETSChecker::HasSameAssemblySignatures(ETSFunctionType const *const func1, @@ -2222,4 +2662,328 @@ bool ETSChecker::HasSameAssemblySignatures(ETSFunctionType const *const func1, } return false; } + +Signature *ETSChecker::FirstMatchSignatures(ir::CallExpression *expr, checker::Type *calleeType) +{ + if (expr->TrailingBlock() == nullptr) { + auto *signature = + MatchOrderSignatures(calleeType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow(), expr->TypeParams(), + expr->Arguments(), expr->Start(), TypeRelationFlag::NONE); + if (signature == nullptr) { + ThrowOverloadMismatch(calleeType->AsETSFunctionType()->Name(), expr->Arguments(), expr->Start(), "call"); + return nullptr; + } + UpdateDeclarationFromSignature(expr, signature); + return signature; + } + + auto &signatures = expr->IsETSConstructorCall() ? calleeType->AsETSObjectType()->ConstructSignatures() + : calleeType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow(); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return ResolveTrailingLambda(signatures, expr, expr->Start()); +} + +Signature *ETSChecker::MatchOrderSignatures(ArenaVector &signatures, + const ir::TSTypeParameterInstantiation *typeArguments, + const ArenaVector &arguments, + const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags) +{ + Signature *compatibleSignatures = nullptr; + Signature *notVisibleSignature = nullptr; + std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); + + auto collectSignatures = [&](TypeRelationFlag relationFlags) { + for (auto *sig : signatures) { + if (notVisibleSignature != nullptr && + !IsSignatureAccessible(sig, Context().ContainingClass(), Relation())) { + continue; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *concreteSig = ValidateOrderSignature(std::make_tuple(sig, typeArguments, relationFlags), arguments, + pos, argTypeInferenceRequired, signatures.size() == 1); + + if (concreteSig == nullptr) { + CleanArgumentsInformation(arguments); + continue; + } + if (notVisibleSignature == nullptr && + !IsSignatureAccessible(sig, Context().ContainingClass(), Relation())) { + CleanArgumentsInformation(arguments); + notVisibleSignature = concreteSig; + } else { + compatibleSignatures = concreteSig; + return; + } + } + }; + + collectSignatures(signatures.size() == 1 ? TypeRelationFlag::WIDENING | resolveFlags + : TypeRelationFlag::WIDENING | TypeRelationFlag::NO_THROW | resolveFlags); + + if (compatibleSignatures != nullptr) { + return compatibleSignatures; + } + + if (notVisibleSignature != nullptr && ((resolveFlags & TypeRelationFlag::NO_THROW) == 0)) { + LogError(diagnostic::SIG_INVISIBLE, {notVisibleSignature->Function()->Id()->Name(), notVisibleSignature}, pos); + } + + return nullptr; +} + +Signature *ETSChecker::ValidateOrderSignature( + std::tuple info, + const ArenaVector &arguments, const lexer::SourcePosition &pos, + const std::vector &argTypeInferenceRequired, const bool unique) +{ + auto [baseSignature, typeArguments, flags] = info; + // In case of overloads, it is necessary to iterate through the compatible signatures again, + // 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 = + MaybeSubstituteTypeParameters(this, baseSignature, typeArguments, arguments, pos, flags); + if (signature == nullptr) { + return nullptr; + } + + // When process first match, if current signature is not matched, do not log TypeError + SignatureMatchContext signatureMatchContext(this, util::DiagnosticType::SEMANTIC, + (flags & TypeRelationFlag::NO_THROW) == 0); + + size_t const argCount = arguments.size(); + auto const hasRestParameter = signature->RestVar() != nullptr; + 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 (compareCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { + LogError(diagnostic::PARAM_COUNT_MISMATCH, {signature->MinArgCount(), argCount}, pos); + return nullptr; + } + + if (argCount > signature->ArgCount() && hasRestParameter && (flags & TypeRelationFlag::IGNORE_REST_PARAM) != 0) { + return nullptr; + } + + auto count = std::min(signature->ArgCount(), argCount); + // Check all required formal parameter(s) first + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + if (!ValidateOrderSignatureRequiredParams(signature, arguments, flags, argTypeInferenceRequired) || + !signatureMatchContext.ValidSignatureMatchStatus()) { + return nullptr; + } + + // Check rest parameter(s) if any exists + if (!hasRestParameter || (count >= argCount && !signature->RestVar()->TsType()->IsETSTupleType())) { + return signature; + } + if (!ValidateSignatureRestParams(signature, arguments, flags, true, unique) || + !signatureMatchContext.ValidSignatureMatchStatus()) { + return nullptr; + } + + return signature; +} + +bool ETSChecker::SetPreferredTypeBeforeValidate(Signature *substitutedSig, ir::Expression *argument, size_t index, + TypeRelationFlag flags, + const std::vector &argTypeInferenceRequired) +{ + auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType()); + if (argument->IsObjectExpression()) { + argument->AsObjectExpression()->SetPreferredType(paramType); + } + + if (argument->IsMemberExpression()) { + SetArrayPreferredTypeForNestedMemberExpressions(argument->AsMemberExpression(), paramType); + } + + if (argTypeInferenceRequired[index]) { + if (!paramType->IsETSFunctionType()) { + return false; + } + ES2PANDA_ASSERT(argument->IsArrowFunctionExpression()); + auto *param = substitutedSig->Params()[index]->Declaration()->Node()->AsETSParameterExpression(); + auto *lambda = argument->AsArrowFunctionExpression(); + if (lambda->Function()->Params().size() > + paramType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().front()->Params().size()) { + return false; + } + return CheckLambdaInfer(param->TypeAnnotation(), argument->AsArrowFunctionExpression(), paramType); + } + + if (argument->IsArrayExpression()) { + argument->AsArrayExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); + } + + if (argument->IsETSNewArrayInstanceExpression()) { + argument->AsETSNewArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); + } + + if (argument->IsETSNewMultiDimArrayInstanceExpression()) { + argument->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); + } + + return true; +} + +bool ETSChecker::ValidateOrderSignatureRequiredParams(Signature *substitutedSig, + const ArenaVector &arguments, + TypeRelationFlag flags, + const std::vector &argTypeInferenceRequired) +{ + auto commonArity = std::min(arguments.size(), substitutedSig->ArgCount()); + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0) { + if (commonArity == 0) { + ES2PANDA_ASSERT(substitutedSig->GetSignatureInfo()->params.empty()); + return false; + } + commonArity = commonArity - 1; + } + for (size_t index = 0; index < commonArity; ++index) { + auto &argument = arguments[index]; + if (!SetPreferredTypeBeforeValidate(substitutedSig, argument, index, flags, argTypeInferenceRequired)) { + return false; + } + + if (argument->IsSpreadElement()) { + LogError(diagnostic::SPREAD_ONTO_SINGLE_PARAM, {}, argument->Start()); + return false; + } + + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { + LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); + return false; + } + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + if (!ValidateOrderSignatureInvocationContext(substitutedSig, argument, index, flags)) { + return false; + } + } + + 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; +} + +void ETSChecker::CleanArgumentsInformation(const ArenaVector &arguments) +{ + if (arguments.empty()) { + return; + } + for (auto *argument : arguments) { + argument->CleanCheckInformation(); + } +} + +bool ETSChecker::ValidateOrderSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, + std::size_t index, TypeRelationFlag flags) +{ + Type *targetType = substitutedSig->Params()[index]->TsType(); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + Type *argumentType = argument->Check(this); + + flags |= TypeRelationFlag::ONLY_CHECK_WIDENING; + + auto const invocationCtx = + checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), + {{diagnostic::TYPE_MISMATCH_AT_IDX, {argumentType, targetType, index + 1}}}, flags); + + return invocationCtx.IsInvocable(); +} + +Signature *ETSChecker::ResolveTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, + const lexer::SourcePosition &pos, const TypeRelationFlag reportFlag) +{ + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto arguments = ExtendArgumentsWithFakeLamda(callExpr); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto sig = ResolvePotentialTrailingLambda(callExpr, signatures, arguments); + if (sig != nullptr) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + TransformTraillingLambda(callExpr, sig); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + TrailingLambdaTypeInference(sig, callExpr->Arguments()); + UpdateDeclarationFromSignature(callExpr, sig); + callExpr->SetIsTrailingCall(true); + return sig; + } + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + sig = MatchOrderSignatures(signatures, callExpr->TypeParams(), callExpr->Arguments(), pos, reportFlag); + if (sig != nullptr) { + EnsureValidCurlyBrace(callExpr); + } + + UpdateDeclarationFromSignature(callExpr, sig); + return sig; +} + +Signature *ETSChecker::ResolvePotentialTrailingLambda(ir::CallExpression *callExpr, + ArenaVector const &signatures, + ArenaVector &arguments) +{ + auto *trailingLambda = arguments.back()->AsArrowFunctionExpression(); + ArenaVector normalSig(ProgramAllocator()->Adapter()); + ArenaVector sigContainLambdaWithReceiverAsParam(ProgramAllocator()->Adapter()); + Signature *signature = nullptr; + for (auto sig : signatures) { + if (!IsLastParameterLambdaWithReceiver(sig)) { + normalSig.emplace_back(sig); + continue; + } + + auto *candidateFunctionType = + sig->Function()->Params().back()->AsETSParameterExpression()->TypeAnnotation()->AsETSFunctionType(); + auto *currentReceiver = candidateFunctionType->Params()[0]; + trailingLambda->Function()->EmplaceParams(currentReceiver); + sigContainLambdaWithReceiverAsParam.emplace_back(sig); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + signature = MatchOrderSignatures(sigContainLambdaWithReceiverAsParam, callExpr->TypeParams(), arguments, + callExpr->Start(), + TypeRelationFlag::NO_THROW | TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA); + if (signature != nullptr) { + return signature; + } + sigContainLambdaWithReceiverAsParam.clear(); + trailingLambda->Function()->ClearParams(); + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return MatchOrderSignatures(normalSig, callExpr->TypeParams(), arguments, callExpr->Start(), + TypeRelationFlag::NO_THROW | TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA); +} + +void ETSChecker::ThrowOverloadMismatch(util::StringView callName, const ArenaVector &arguments, + const lexer::SourcePosition &pos, std::string_view signatureKind) +{ + std::string msg {}; + msg.append(callName.Mutf8()); + msg += "("; + + for (std::size_t index = 0U; index < arguments.size(); ++index) { + auto const &argument = arguments[index]; + Type const *const argumentType = argument->Check(this); + if (!argumentType->IsTypeError()) { + msg += argumentType->ToString(); + } else { + // NOTE (DZ): extra cases for some specific nodes can be added here (as for 'ArrowFunctionExpression') + msg += argument->ToString(); + } + + if (index != arguments.size() - 1U) { + msg += ", "; + } + } + msg += ")"; + LogError(diagnostic::NO_MATCHING_SIG, {signatureKind, msg.c_str()}, pos); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index 1051bb4987d10b76828e144a04417304b9908502..7730c65f761e4decde9ef61df925a6af35a41b56 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -54,6 +54,7 @@ namespace ark::es2panda::checker { static Type *MaybeBoxedType(ETSChecker *checker, Type *type, ir::Expression *expr) { + ES2PANDA_ASSERT(type != nullptr); if (!type->IsETSPrimitiveType()) { return type; } @@ -77,6 +78,7 @@ static void InferUntilFail(Signature const *const signature, const ArenaVectorAddStatus(checker::CheckerStatus::IN_TYPE_INFER); // some ets lib files require type infer from arg index 0,1,... , not fit to build graph + ES2PANDA_ASSERT(substitution != nullptr); while (anyChange && substitution->size() < sigParams.size()) { anyChange = false; for (size_t ix = 0; ix < arguments.size(); ++ix) { @@ -116,82 +118,82 @@ static void InferUntilFail(Signature const *const signature, const ArenaVectorRemoveStatus(checker::CheckerStatus::IN_TYPE_INFER); } -static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *checker, Signature *signature, - const ArenaVector &arguments) +static std::optional BuildImplicitSubstitutionForArguments(ETSChecker *checker, Signature *signature, + const ArenaVector &arguments) { - Substitution *substitution = checker->NewSubstitution(); + auto substitution = Substitution {}; auto *sigInfo = signature->GetSignatureInfo(); auto &sigParams = signature->GetSignatureInfo()->typeParams; - InferUntilFail(signature, arguments, checker, substitution); + InferUntilFail(signature, arguments, checker, &substitution); - if (substitution->size() != sigParams.size()) { + if (substitution.size() != sigParams.size()) { for (const auto typeParam : sigParams) { auto newTypeParam = typeParam->AsETSTypeParameter(); - if (auto it = substitution->find(newTypeParam); it != substitution->cend()) { + if (auto it = substitution.find(newTypeParam); it != substitution.cend()) { continue; } if (newTypeParam->GetDefaultType() == nullptr) { - checker->EmplaceSubstituted(substitution, newTypeParam, checker->GlobalETSNeverType()); + checker->EmplaceSubstituted(&substitution, newTypeParam, checker->GlobalETSNeverType()); continue; } - auto dflt = newTypeParam->GetDefaultType()->Substitute(checker->Relation(), substitution); - if (!checker->EnhanceSubstitutionForType(sigInfo->typeParams, newTypeParam, dflt, substitution)) { - return nullptr; + auto dflt = newTypeParam->GetDefaultType()->Substitute(checker->Relation(), &substitution); + if (!checker->EnhanceSubstitutionForType(sigInfo->typeParams, newTypeParam, dflt, &substitution)) { + return std::nullopt; } } - - 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 std::nullopt; } return substitution; } -static const Substitution *BuildExplicitSubstitutionForArguments(ETSChecker *checker, Signature *signature, - const ArenaVector ¶ms, - const lexer::SourcePosition &pos, - TypeRelationFlag flags) +static std::optional BuildExplicitSubstitutionForArguments(ETSChecker *checker, Signature *signature, + const ArenaVector ¶ms, + const lexer::SourcePosition &pos, + TypeRelationFlag flags) { auto &sigParams = signature->GetSignatureInfo()->typeParams; - auto *substitution = checker->NewSubstitution(); - auto *constraintsSubstitution = checker->NewSubstitution(); + auto substitution = Substitution {}; + auto constraintsSubstitution = Substitution {}; ArenaVector instArgs {checker->Allocator()->Adapter()}; for (size_t ix = 0; ix < params.size(); ++ix) { instArgs.push_back(MaybeBoxedType(checker, params[ix]->GetType(checker), params[ix])); if (ix < sigParams.size()) { - checker->EmplaceSubstituted(constraintsSubstitution, sigParams[ix]->AsETSTypeParameter(), instArgs[ix]); + checker->EmplaceSubstituted(&constraintsSubstitution, sigParams[ix]->AsETSTypeParameter(), instArgs[ix]); } } for (size_t ix = instArgs.size(); ix < sigParams.size(); ++ix) { - auto *dflt = sigParams[ix]->AsETSTypeParameter()->GetDefaultType(); + auto typeParam = sigParams[ix]->AsETSTypeParameter(); + auto *dflt = typeParam->GetDefaultType(); if (dflt == nullptr) { break; } - dflt = dflt->Substitute(checker->Relation(), constraintsSubstitution); + dflt = dflt->Substitute(checker->Relation(), &constraintsSubstitution); instArgs.push_back(dflt); - checker->EmplaceSubstituted(constraintsSubstitution, sigParams[ix]->AsETSTypeParameter(), instArgs[ix]); + checker->EmplaceSubstituted(&constraintsSubstitution, typeParam, instArgs[ix]); } if (sigParams.size() != instArgs.size()) { if ((flags & TypeRelationFlag::NO_THROW) == static_cast>(0U)) { checker->LogError(diagnostic::RTYPE_PARAM_COUNT_MISMATCH, {sigParams.size(), instArgs.size()}, pos); } - return nullptr; + return std::nullopt; } for (size_t ix = 0; ix < sigParams.size(); ix++) { if (!checker->IsCompatibleTypeArgument(sigParams[ix]->AsETSTypeParameter(), instArgs[ix], - constraintsSubstitution)) { - return nullptr; + &constraintsSubstitution)) { + return std::nullopt; } - checker->EmplaceSubstituted(substitution, sigParams[ix]->AsETSTypeParameter(), instArgs[ix]); + checker->EmplaceSubstituted(&substitution, sigParams[ix]->AsETSTypeParameter(), instArgs[ix]); } return substitution; } @@ -205,12 +207,12 @@ static Signature *MaybeSubstituteTypeParameters(ETSChecker *checker, Signature * return signature; } - const Substitution *substitution = + const std::optional substitution = (typeArguments != nullptr) ? BuildExplicitSubstitutionForArguments(checker, signature, typeArguments->Params(), pos, flags) : BuildImplicitSubstitutionForArguments(checker, signature, arguments); - return (substitution == nullptr) ? nullptr : signature->Substitute(checker->Relation(), substitution); + return (!substitution.has_value()) ? nullptr : signature->Substitute(checker->Relation(), &substitution.value()); } static bool CheckInterfaceOverride(ETSChecker *const checker, ETSObjectType *const interface, diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 10699774ace58c5846edbd15eb6fcf0c65e15723..259e0032e0c495742122f420e60cccde06df7411 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -13,21 +13,32 @@ * limitations under the License. */ +#include +#include #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" +#include "checker/types/gradualType.h" +#include "checker/checkerContext.h" +#include "checker/ETSAnalyzerHelpers.h" +#include "checker/types/ets/etsEnumType.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 "generated/diagnostic.h" +#include "util/es2pandaMacros.h" +#include "util/helpers.h" +#include "util/nameMangler.h" namespace ark::es2panda::checker { -varbinder::Variable *ETSChecker::FindVariableInFunctionScope(const util::StringView name) + +varbinder::Variable *ETSChecker::FindVariableInFunctionScope(const util::StringView name, + const varbinder::ResolveBindingOptions options) { - return Scope() != nullptr ? Scope()->FindInFunctionScope(name, varbinder::ResolveBindingOptions::ALL).variable - : nullptr; + return Scope() != nullptr ? Scope()->FindInFunctionScope(name, options).variable : nullptr; } std::pair ETSChecker::FindVariableInClassOrEnclosing( @@ -38,7 +49,8 @@ std::pair ETSChecker::FindVariable return {nullptr, nullptr}; } const auto searchFlags = PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE | - PropertySearchFlags::SEARCH_IN_INTERFACES; + PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; auto *resolved = classType->GetProperty(name, searchFlags); while (classType->EnclosingType() != nullptr && resolved == nullptr) { classType = classType->EnclosingType(); @@ -48,17 +60,18 @@ std::pair ETSChecker::FindVariable return {resolved, classType}; } -varbinder::Variable *ETSChecker::FindVariableInGlobal(const ir::Identifier *const identifier) +varbinder::Variable *ETSChecker::FindVariableInGlobal(const ir::Identifier *const identifier, + const varbinder::ResolveBindingOptions options) { - return Scope() != nullptr - ? Scope()->FindInGlobal(identifier->Name(), varbinder::ResolveBindingOptions::ALL).variable - : nullptr; + return Scope() != nullptr ? Scope()->FindInGlobal(identifier->Name(), options).variable : nullptr; } bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) { + CHECK_NOT_NULL(var); if (var->HasFlag(varbinder::VariableFlags::METHOD)) { - return var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); + return var->TsType()->IsETSFunctionType() && + var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); } return var->HasFlag(varbinder::VariableFlags::STATIC); } @@ -68,6 +81,12 @@ bool ETSChecker::IsVariableGetterSetter(const varbinder::Variable *var) return var != nullptr && var->TsType() != nullptr && var->TsType()->HasTypeFlag(TypeFlag::GETTER_SETTER); } +bool ETSChecker::IsVariableOverloadDeclaration(const varbinder::Variable *var) +{ + return var != nullptr && var->Declaration() != nullptr && var->Declaration()->Node() != nullptr && + var->Declaration()->Node()->IsOverloadDeclaration(); +} + bool ETSChecker::IsVariableExtensionAccessor(const varbinder::Variable *var) { return var != nullptr && var->TsType() != nullptr && var->TsType()->IsETSFunctionType() && @@ -96,11 +115,13 @@ void ETSChecker::WrongContextErrorClassifyByType(ir::Identifier *ident) varbinder::VariableFlags::TYPE))) { case varbinder::VariableFlags::CLASS: identCategoryName = "Class"; - break; + LogError(diagnostic::NOT_AS_OBJECT, {identCategoryName}, ident->Start()); + return; case varbinder::VariableFlags::NAMESPACE: identCategoryName = "Namespace"; - break; + LogError(diagnostic::NOT_AS_OBJECT, {identCategoryName}, ident->Start()); + return; case varbinder::VariableFlags::METHOD: identCategoryName = "Function"; @@ -130,13 +151,19 @@ void ETSChecker::WrongContextErrorClassifyByType(ir::Identifier *ident) LogError(diagnostic::ID_WRONG_CTX, {ident->Name()}, ident->Start()); return; } + ident->SetTsType(GlobalTypeError()); LogError(diagnostic::ID_IN_WRONG_CTX, {identCategoryName.c_str(), ident->Name()}, ident->Start()); } void ETSChecker::NotResolvedError(ir::Identifier *const ident, const varbinder::Variable *classVar, const ETSObjectType *classType) { - if (classVar == nullptr) { + if (classVar == nullptr || (classVar->TsType() != nullptr && classVar->TsType()->IsTypeError())) { + if (ident->Name() == compiler::Signatures::DELETE) { + LogError(diagnostic::TYPES_CANNOT_BE_MODIFIED_AT_RUNTIME, {ident->Name()}, ident->Start()); + return; + } + LogUnresolvedReferenceError(ident); return; } @@ -272,11 +299,14 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *ident) return GetTypeOfVariable(resolved); } - auto *resolved = FindVariableInFunctionScope(ident->Name()); + const auto options = varbinder::ResolveBindingOptions::ALL_VARIABLES | + varbinder::ResolveBindingOptions::ALL_METHOD | + varbinder::ResolveBindingOptions::ALL_DECLARATION; + auto *resolved = FindVariableInFunctionScope(ident->Name(), options); if (resolved == nullptr) { // If the reference is not found already in the current class, then it is not bound to the class, so we have to // find the reference in the global class first, then in the global scope - resolved = FindVariableInGlobal(ident); + resolved = FindVariableInGlobal(ident, options); if (UNLIKELY(resolved == nullptr && debugInfoPlugin_ != nullptr)) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) resolved = debugInfoPlugin_->FindIdentifier(ident); @@ -286,8 +316,12 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *ident) if (resolved == nullptr) { resolved = ExtraCheckForResolvedError(ident); if (resolved == nullptr) { + if (VarBinder()->GetScope()->IsClassScope() && this->IsAnyError()) { + return ident->SetTsType(GlobalTypeError()); + } 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); @@ -367,31 +401,55 @@ checker::Type *ETSChecker::ApplyConditionalOperatorPromotion(checker::ETSChecker ES2PANDA_UNREACHABLE(); } -Type *ETSChecker::ApplyUnaryOperatorPromotion(Type *type, const bool createConst, const bool doPromotion, - const bool isCondExpr) +Type *ETSChecker::GetUnaryOperatorPromotedType(Type *type, const bool doPromotion) +{ + auto globalTypesHolder = GetGlobalTypesHolder(); + + if (doPromotion) { + // NOTE(dkofanov): Deprecated operations on 'char' #28006 + if (type == globalTypesHolder->GlobalByteBuiltinType() || type == globalTypesHolder->GlobalShortBuiltinType() || + type == globalTypesHolder->GlobalCharBuiltinType() || + type == globalTypesHolder->GlobalIntegerBuiltinType()) { + return GlobalIntBuiltinType(); + } + + // NOTE(dkofanov): Deprecated operations on 'char' #28006 + if (type->IsIntType() || type->IsByteType() || type->IsShortType() || type->IsCharType()) { + return GlobalIntBuiltinType(); + } + } + + return type; +} + +Type *ETSChecker::ApplyUnaryOperatorPromotion(ir::Expression *expr, Type *type, const bool isCondExpr) { Type *unboxedType = isCondExpr ? MaybeUnboxConditionalInRelation(type) : MaybeUnboxInRelation(type); + if (type != nullptr && type->IsETSIntEnumType()) { + expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + unboxedType = type->AsETSEnumType()->GetBaseEnumElementType(this); + } + if (unboxedType == nullptr) { return nullptr; } - if (doPromotion) { - switch (ETSType(unboxedType)) { - case TypeFlag::BYTE: - case TypeFlag::SHORT: - case TypeFlag::CHAR: { - if (!createConst) { - return GlobalIntType(); - } - return CreateIntTypeFromType(unboxedType); - } - default: { - break; - } - } + switch (ETSType(unboxedType)) { + case TypeFlag::BYTE: + [[fallthrough]]; + case TypeFlag::SHORT: + [[fallthrough]]; + case TypeFlag::CHAR: + [[fallthrough]]; + case TypeFlag::INT: + return GlobalIntBuiltinType(); + + default: + break; } - return unboxedType; + + return type; } bool ETSChecker::IsNullLikeOrVoidExpression(const ir::Expression *expr) const @@ -403,7 +461,7 @@ bool ETSChecker::IsNullLikeOrVoidExpression(const ir::Expression *expr) const std::tuple ETSChecker::IsResolvedAndValue(const ir::Expression *expr, Type *type) const { auto [isResolve, isValue] = - IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : type->ResolveConditionExpr(); + IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : IsConstantTestValue(expr); const Type *tsType = expr->TsType(); if (tsType->DefinitelyNotETSNullish() && !type->IsETSPrimitiveOrEnumType()) { @@ -450,30 +508,6 @@ Type *ETSChecker::HandleBooleanLogicalOperators(Type *leftType, Type *rightType, return nullptr; } -bool ETSChecker::HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, - checker::Type *leftType) -{ - if (leftType->IsConstantType() && leftType->IsETSBooleanType()) { - if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? right : left); - return true; - } - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? left : right); - return true; - } - - if (!leftType->IsETSPrimitiveType() && !leftType->PossiblyETSValueTyped()) { - expr->SetResult(expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND ? right : left); - return true; - } - if (leftType->IsETSNullType() || leftType->IsETSUndefinedType()) { - expr->SetResult(expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND ? left : right); - return true; - } - - return false; -} - void ETSChecker::ResolveReturnStatement(checker::Type *funcReturnType, checker::Type *argumentType, ir::ScriptFunction *containingFunc, ir::ReturnStatement *st) { @@ -498,8 +532,6 @@ void ETSChecker::ResolveReturnStatement(checker::Type *funcReturnType, checker:: argumentType = MaybeBoxInRelation(argumentType); if (argumentType == nullptr) { LogError(diagnostic::INVALID_EXPR_IN_RETURN, {}, st->Argument()->Start()); - } else { - st->Argument()->AddBoxingUnboxingFlags(GetBoxingFlag(argumentType)); } } @@ -523,7 +555,7 @@ void ETSChecker::ResolveReturnStatement(checker::Type *funcReturnType, checker:: checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) { - ArenaVector elementTypes(Allocator()->Adapter()); + ArenaVector elementTypes(ProgramAllocator()->Adapter()); for (auto *elementNode : init->AsArrayExpression()->Elements()) { Type *elementType = elementNode->Check(this); if (elementType->IsTypeError()) { @@ -534,7 +566,6 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { elementTypes.emplace_back(typeFromTuple); } - continue; } @@ -542,22 +573,90 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) elementType = elementType->AsETSArrayType()->ElementType(); } - elementTypes.push_back(GetNonConstantType(elementType)); + elementTypes.emplace_back(elementType); } if (elementTypes.empty()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return Allocator()->New(GlobalETSObjectType()); + if (init->PreferredType() != nullptr) { + return init->PreferredType(); + } + LogError(diagnostic::UNRESOLVABLE_ARRAY, {}, init->Start()); + return GetGlobalTypesHolder()->GlobalTypeError(); } - 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 arrayElementType = - std::all_of(elementTypes.begin(), elementTypes.end(), isNumeric) - ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) ? GlobalCharType() : GlobalDoubleType() - : CreateETSUnionType(std::move(elementTypes)); + auto const isNumericLiteral = [this](checker::Type *&ct) { + auto const rc = + ct->IsConstantType() && Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalNumericBuiltinType(), ct); + ct = GetNonConstantType(ct); + return rc; + }; + auto const isChar = [this](checker::Type *ct) { + return Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalCharBuiltinType(), ct); + }; + auto const elementType = std::all_of(elementTypes.begin(), elementTypes.end(), isNumericLiteral) + ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) + ? GlobalCharBuiltinType() + : GlobalDoubleBuiltinType() + : CreateETSUnionType(std::move(elementTypes)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return Allocator()->New(arrayElementType); + return CreateETSResizableArrayType(elementType); +} + +static void SetTypeforLambdaParamWithoutTypeAnnotation(ir::ETSParameterExpression *param, Type *type) +{ + auto *const lambdaParam = param->Ident(); + if (lambdaParam->TypeAnnotation() != nullptr) { + return; + } + if (lambdaParam->Variable() != nullptr) { + lambdaParam->Variable()->SetTsType(type); + } + lambdaParam->SetTsType(type); +} + +void ETSChecker::InferLambdaInAssignmentExpression(ir::AssignmentExpression *const expr) +{ + auto *left = expr->Left(); + auto *right = expr->Right(); + + if (!right->IsArrowFunctionExpression()) { + return; + } + + if (left->TsType() == nullptr || !left->TsType()->IsETSFunctionType() || + left->TsType()->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { + return; + } + + ArenaVector lambdaParams = right->AsArrowFunctionExpression()->Function()->Params(); + Signature *sig = left->TsType()->AsETSFunctionType()->CallSignaturesOfMethodOrArrow()[0]; + + size_t paramCount = sig->Params().size(); + if (sig->RestVar() != nullptr) { + paramCount++; + } + + if (paramCount != lambdaParams.size()) { + return; + } + + if (std::any_of(lambdaParams.begin(), lambdaParams.end(), + [](auto ¶m) { return !param->IsETSParameterExpression(); })) { + return; + } + + if (sig->RestVar() != nullptr) { + if (!lambdaParams.back()->AsETSParameterExpression()->IsRestParameter()) { + return; + } + SetTypeforLambdaParamWithoutTypeAnnotation(lambdaParams.back()->AsETSParameterExpression(), + sig->RestVar()->TsType()); + paramCount--; + } + for (size_t i = 0; i < paramCount; i++) { + auto *inferredType = sig->Params()[i]->TsType(); + SetTypeforLambdaParamWithoutTypeAnnotation(lambdaParams[i]->AsETSParameterExpression(), inferredType); + } } void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init) @@ -592,15 +691,13 @@ void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Arr } } -checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags, - ir::Expression *init) +checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags) { if ((flags & ir::ModifierFlags::OPTIONAL) != 0) { - if (init != nullptr && bindingVar->TsType()->IsETSPrimitiveType()) { - init->SetBoxingUnboxingFlags(GetBoxingFlag(bindingVar->TsType())); - } + ES2PANDA_ASSERT(bindingVar != nullptr); auto *variableType = bindingVar->TsType() != nullptr ? bindingVar->TsType() : GlobalTypeError(); - bindingVar->SetTsType(CreateETSUnionType({GlobalETSUndefinedType(), variableType})); + bindingVar->SetTsType( + !variableType->IsTypeError() ? CreateETSUnionType({GlobalETSUndefinedType(), variableType}) : variableType); } return bindingVar->TsType(); } @@ -612,37 +709,37 @@ 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; +} + +// CC-OFFNXT(huge_cyclomatic_complexity, huge_cca_cyclomatic_complexity[C++]) solid logic +static 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)) { @@ -650,12 +747,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 (init->IsArrayExpression() && (annotationType != nullptr)) { if (annotationType->IsETSTupleType() && - !IsArrayExprSizeValidForTuple(init->AsArrayExpression(), annotationType->AsETSTupleType())) { + !checker->IsArrayExprSizeValidForTuple(init->AsArrayExpression(), annotationType->AsETSTupleType())) { return false; } @@ -663,17 +760,70 @@ bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, } if (init->IsObjectExpression() && annotationType != nullptr) { - init->AsObjectExpression()->SetPreferredType(PreferredObjectTypeFromAnnotation(annotationType)); + init->SetPreferredType(PreferredObjectTypeFromAnnotation(annotationType)); + } + + if (init->IsETSNewArrayInstanceExpression() && annotationType != nullptr) { + init->SetPreferredType(annotationType); + } + if (init->IsETSNewMultiDimArrayInstanceExpression() && annotationType != nullptr) { + init->SetPreferredType(annotationType); + } + if (init->IsNumberLiteral() && annotationType != nullptr) { + init->SetPreferredType(annotationType); + } + if (init->IsBinaryExpression() && annotationType != nullptr) { + auto *binExpr = init->AsBinaryExpression(); + if (binExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING && + !binExpr->Right()->IsLiteral()) { + binExpr->Right()->SetPreferredType(annotationType); + } + } + if (init->IsConditionalExpression() && annotationType != nullptr) { + auto *conditionalExpr = init->AsConditionalExpression(); + if (!conditionalExpr->Consequent()->IsLiteral()) { + conditionalExpr->Consequent()->SetPreferredType(annotationType); + } + if (!conditionalExpr->Alternate()->IsLiteral()) { + conditionalExpr->Alternate()->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 (init->IsETSTypeReference()) { + LogError(diagnostic::INVALID_TYPE_AS_VALUE, {init->DumpEtsSrc()}, init->Start()); + } + 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) && @@ -723,6 +873,7 @@ static void CheckAssignForDeclare(ir::Identifier *ident, ir::TypeNode *typeAnnot return; } const bool isConst = (flags & ir::ModifierFlags::CONST) != 0; + ES2PANDA_ASSERT(init != nullptr); bool numberLiteralButNotBigInt = init->IsNumberLiteral() && !init->IsBigIntLiteral(); bool multilineLiteralWithNoEmbedding = init->IsTemplateLiteral() && init->AsTemplateLiteral()->Expressions().empty(); @@ -731,38 +882,87 @@ static void CheckAssignForDeclare(ir::Identifier *ident, ir::TypeNode *typeAnnot } } +static void CheckRecordSpreadElement(ir::SpreadElement *spreadElement, ArenaVector &typeArguments, + ETSChecker *checker, const lexer::SourcePosition &start) +{ + auto spreadArg = spreadElement->Argument(); + auto spreadType = spreadArg->Check(checker); + // Verify spread source is also a Record type + if (!spreadType->IsETSObjectType()) { + checker->LogError(diagnostic::INVALID_RECORD_PROPERTY, start); + return; + } + // Check if spread type is Record or Map using proper type identity checking + auto *spreadObjType = spreadType->AsETSObjectType(); + auto *spreadOriginalBaseType = spreadObjType->GetOriginalBaseType(); + auto *globalTypes = checker->GetGlobalTypesHolder(); + if (!checker->IsTypeIdenticalTo(spreadOriginalBaseType, globalTypes->GlobalMapBuiltinType()) && + !checker->IsTypeIdenticalTo(spreadOriginalBaseType, globalTypes->GlobalRecordBuiltinType())) { + checker->LogError(diagnostic::INVALID_RECORD_PROPERTY, start); + return; + } + // Verify type parameters match + auto spreadTypeArgs = spreadType->AsETSObjectType()->TypeArguments(); + constexpr size_t EXPECTED_TYPE_ARGUMENTS_SIZE = 2; + if (spreadTypeArgs.size() != EXPECTED_TYPE_ARGUMENTS_SIZE) { + checker->LogError(diagnostic::INVALID_RECORD_PROPERTY, start); + return; + } + // Checking if the key type is a subtype of the type argument + if (!checker->Relation()->IsSupertypeOf(typeArguments[0], spreadTypeArgs[0])) { + checker->LogError(diagnostic::TYPE_MISMATCH_AT_IDX, {spreadTypeArgs[0], typeArguments[0], size_t(1)}, start); + } + checker::AssignmentContext(checker->Relation(), spreadArg, spreadTypeArgs[1], typeArguments[1], start, + util::DiagnosticWithParams {diagnostic::TYPE_MISMATCH_AT_IDX, + {spreadTypeArgs[1], typeArguments[1], size_t(2)}}); +} + +static void CheckRecordProperty(ir::Property *p, ArenaVector &typeArguments, ETSChecker *checker) +{ + p->Key()->SetPreferredType(typeArguments[0]); + p->Value()->SetPreferredType(typeArguments[1]); + + checker::Type *keyType = p->Key()->Check(checker); + checker::Type *valueType = p->Value()->Check(checker); + + // Checking if the key type is a subtype of the type argument + if (!checker->Relation()->IsSupertypeOf(typeArguments[0], keyType)) { + checker->LogError(diagnostic::TYPE_MISMATCH_AT_IDX, {keyType, typeArguments[0], size_t(1)}, p->Key()->Start()); + } + checker::AssignmentContext( + checker->Relation(), p->Value(), valueType, typeArguments[1], p->Value()->Start(), + util::DiagnosticWithParams {diagnostic::TYPE_MISMATCH_AT_IDX, {valueType, typeArguments[1], size_t(2)}}); +} + static void CheckRecordType(ir::Expression *init, checker::Type *annotationType, ETSChecker *checker) { if (!annotationType->IsETSObjectType() || !init->IsObjectExpression()) { return; } + // Check if this is actually a Record or Map type using proper type identity checking + auto *objType = annotationType->AsETSObjectType(); + auto *originalBaseType = objType->GetOriginalBaseType(); + auto *globalTypes = checker->GetGlobalTypesHolder(); - std::stringstream ss; - init->TsType()->ToAssemblerType(ss); - if (ss.str() != "escompat.Record" && ss.str() != "escompat.Map") { + if (!checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalMapBuiltinType()) && + !checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalRecordBuiltinType())) { return; } auto objectExpr = init->AsObjectExpression(); auto typeArguments = annotationType->AsETSObjectType()->TypeArguments(); auto properties = objectExpr->Properties(); - for (const auto &property : properties) { - ES2PANDA_ASSERT(property->IsProperty()); - auto p = property->AsProperty(); - - ETSChecker::SetPreferredTypeIfPossible(p->Key(), typeArguments[0]); - ETSChecker::SetPreferredTypeIfPossible(p->Value(), typeArguments[1]); - - Type *keyType = p->Key()->Check(checker); - Type *valueType = p->Value()->Check(checker); + if (property->IsSpreadElement()) { + CheckRecordSpreadElement(property->AsSpreadElement(), typeArguments, checker, property->Start()); + continue; + } + if (!property->IsProperty()) { + checker->LogError(diagnostic::INVALID_RECORD_PROPERTY, property->Start()); + continue; + } - checker::AssignmentContext( - checker->Relation(), p->Key(), keyType, typeArguments[0], p->Key()->Start(), - 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(), - util::DiagnosticWithParams {diagnostic::TYPE_MISMATCH_AT_IDX, {valueType, typeArguments[1], size_t(2)}}); + CheckRecordProperty(property->AsProperty(), typeArguments, checker); } } @@ -770,6 +970,7 @@ static void CheckRecordType(ir::Expression *init, checker::Type *annotationType, checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, ir::ModifierFlags const flags) { + ES2PANDA_ASSERT(ident != nullptr); varbinder::Variable *const bindingVar = ident->Variable(); checker::Type *annotationType = nullptr; @@ -781,7 +982,7 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T } if (init == nullptr) { - return FixOptionalVariableType(bindingVar, flags, init); + return FixOptionalVariableType(bindingVar, flags); } CheckAssignForDeclare(ident, typeAnnotation, init, flags, this); } else { @@ -800,11 +1001,15 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T ES2PANDA_ASSERT(IsAnyError()); } - // initType should not be nullptr. If an error occurs during check, set it to GlobalTypeError(). - if (bindingVar == nullptr || initType == nullptr || initType->IsTypeError()) { + if (bindingVar == nullptr) { return annotationType != nullptr ? annotationType : GlobalTypeError(); } + // initType should not be nullptr. If an error occurs during check, set it to GlobalTypeError(). + if (initType == nullptr || initType->IsTypeError()) { + return bindingVar->SetTsType(annotationType != nullptr ? annotationType : GlobalTypeError()); + } + if (typeAnnotation == nullptr && initType->IsETSFunctionType()) { annotationType = initType->AsETSFunctionType(); bindingVar->SetTsType(annotationType); @@ -831,7 +1036,7 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T bindingVar->SetTsType(needWidening ? GetNonConstantType(initType) : initType); } - return FixOptionalVariableType(bindingVar, flags, init); + return FixOptionalVariableType(bindingVar, flags); } void ETSChecker::VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType) @@ -847,7 +1052,7 @@ void ETSChecker::VariableTypeFromInitializer(varbinder::Variable *variable, Type 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, Allocator())); + variable->SetTsType(TypeConverter::ConvertConstantTypes(initType, annotationType, ProgramAllocator())); } static checker::Type *ResolveGetter(checker::ETSChecker *checker, ir::MemberExpression *const expr, @@ -887,7 +1092,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(), @@ -909,7 +1114,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()); @@ -954,8 +1159,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()); @@ -978,64 +1183,50 @@ checker::Type *ETSChecker::GetExtensionAccessorReturnType(ir::MemberExpression * // Smart cast support //==============================================================================// -checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType) +static checker::Type *MaybeReadonlyType(ETSChecker *checker, checker::Type *sourceType, checker::Type *targetType) { - // For left-hand variable of primitive type leave it as is. - if (targetType->IsETSPrimitiveType()) { + // For left-hand variable of builtin type leave it as is. + if (targetType->IsBuiltinNumeric()) { return targetType; } - // For left-hand variable of tuple type leave it as is. - if (targetType->IsETSTupleType()) { - return targetType; + // Preserve 'Readonly' type flag in smart type if it exists in declared type + if (targetType->HasTypeFlag(TypeFlag::READONLY) && !sourceType->HasTypeFlag(TypeFlag::READONLY)) { + sourceType = sourceType->Clone(checker); + sourceType->AddTypeFlag(TypeFlag::READONLY); } + return sourceType; +} + +checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, + std::optional value) +{ + // For left-hand variable of primitive type leave it as is. + ES2PANDA_ASSERT(!targetType->IsETSPrimitiveType() && !sourceType->IsETSPrimitiveType()); // For left-hand invalid variable set smart type to right-hand type. if (targetType->IsTypeError()) { return sourceType; } - // For left-hand variable of builtin type leave it as is. - if (targetType->IsETSObjectType() && targetType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - return targetType; - } - - // Nothing to do with identical types: - auto *nonConstSourceType = GetNonConstantType(sourceType); - auto *nonConstTargetType = GetNonConstantType(targetType); - - if (Relation()->IsIdenticalTo(nonConstSourceType, nonConstTargetType) || - Relation()->IsIdenticalTo(GlobalBuiltinJSValueType(), nonConstTargetType)) { - return targetType; - } - // For type parameter, null or undefined source type return it as is. if (sourceType->IsETSTypeParameter() || sourceType->DefinitelyETSNullish()) { return sourceType; } - // In case of Union left-hand type we have to select the proper type from the Union - // Because now we have logging of errors we have to continue analyze incorrect program, for - // this case we change typeError to source type. - if (targetType->IsETSUnionType()) { - auto component = targetType->AsETSUnionType()->GetAssignableType(this, sourceType); - return component->IsTypeError() ? MaybeBoxType(sourceType) : component; - } - - // If source is reference type, set it as the current and use it for identifier smart cast - if (sourceType->IsETSReferenceType()) { - return sourceType; + // In case of Union left-hand type we try to select the proper type from the Union + if (targetType->IsETSUnionType() && !sourceType->IsUnionType()) { + auto *constituentType = targetType->AsETSUnionType()->GetAssignableType(this, sourceType, value); + if (constituentType != nullptr) { + return MaybeReadonlyType(this, sourceType, constituentType); + } } - // For right-hand variable of primitive type apply boxing conversion (case: 'let x: Object = 5', then x => Int). - if (sourceType->IsETSPrimitiveType() && !sourceType->IsETSVoidType() && targetType->IsETSObjectType()) { - return MaybeBoxInRelation(sourceType); + // General case - return more specific subtype + if (Relation()->IsSupertypeOf(targetType, sourceType)) { + return MaybeReadonlyType(this, sourceType, targetType); } - // NOTE - it seems that all the other possible cases are assignments like: - // 'Object = ObjectLiteral' or smth similar ??? - // thus for such cases also leave the target type as is. - // Possible errors in tests should clarify this hypothesis sooner or later :) return targetType; } @@ -1054,7 +1245,7 @@ std::pair ETSChecker::CheckTestNullishCondition(Type *testedType return {GlobalETSUndefinedType(), RemoveUndefinedType(actualType)}; } - return {GlobalETSNullishType(), GetNonNullishType(actualType)}; + return {GlobalETSUnionUndefinedNull(), GetNonNullishType(actualType)}; } // Auxiliary method to reduce the size of common 'CheckTestSmartCastConditions' function. @@ -1088,8 +1279,7 @@ std::pair ETSChecker::CheckTestObjectCondition(ETSArrayType *tes } // Auxiliary method to reduce the size of common 'CheckTestSmartCastConditions' function. -std::pair ETSChecker::CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType, - bool const strict) +std::pair ETSChecker::CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType) { if (actualType->IsETSUnionType()) { return actualType->AsETSUnionType()->GetComplimentaryType(this, testedType); @@ -1102,7 +1292,7 @@ std::pair ETSChecker::CheckTestObjectCondition(ETSObjectType *te if (Relation()->IsIdenticalTo(objectType, testedType) || objectType->AssemblerName() == testedType->AssemblerName()) { - return {testedType, strict ? GetGlobalTypesHolder()->GlobalETSNeverType() : actualType}; + return {testedType, actualType}; } if (Relation()->IsSupertypeOf(objectType, testedType)) { @@ -1137,6 +1327,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}); } @@ -1173,9 +1368,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(); @@ -1345,8 +1540,7 @@ std::optional CheckerContext::ResolveSmartCastTypes() checker->CheckTestNullishCondition(testCondition_.testedType, smartType, testCondition_.strict); } else if (testCondition_.testedType->IsETSObjectType()) { auto *const testedType = testCondition_.testedType->AsETSObjectType(); - std::tie(consequentType, alternateType) = - checker->CheckTestObjectCondition(testedType, smartType, testCondition_.strict); + std::tie(consequentType, alternateType) = checker->CheckTestObjectCondition(testedType, smartType); } else if (testCondition_.testedType->IsETSArrayType()) { auto *const testedType = testCondition_.testedType->AsETSArrayType(); std::tie(consequentType, alternateType) = checker->CheckTestObjectCondition(testedType, smartType); @@ -1460,47 +1654,6 @@ void ETSChecker::SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpre } } -// 22955: type alias should be instantiated with Substitute -static void CollectAliasParametersForBoxing(Type *expandedAliasType, std::set ¶metersNeedToBeBoxed, - bool needToBeBoxed) -{ - if (expandedAliasType->IsETSTypeParameter() && needToBeBoxed) { - parametersNeedToBeBoxed.insert(expandedAliasType); - } else if (expandedAliasType->IsETSObjectType()) { - auto objectType = expandedAliasType->AsETSObjectType(); - needToBeBoxed = - objectType->GetDeclNode()->IsClassDefinition() || objectType->GetDeclNode()->IsTSInterfaceDeclaration(); - for (const auto typeArgument : objectType->TypeArguments()) { - CollectAliasParametersForBoxing(typeArgument, parametersNeedToBeBoxed, needToBeBoxed); - } - } else if (expandedAliasType->IsETSTupleType()) { - auto tupleType = expandedAliasType->AsETSTupleType(); - needToBeBoxed = false; - for (auto type : tupleType->GetTupleTypesList()) { - CollectAliasParametersForBoxing(type, parametersNeedToBeBoxed, needToBeBoxed); - } - } else if (expandedAliasType->IsETSArrayType()) { - auto arrayType = expandedAliasType->AsETSArrayType(); - needToBeBoxed = false; - auto elementType = arrayType->ElementType(); - CollectAliasParametersForBoxing(elementType, parametersNeedToBeBoxed, needToBeBoxed); - } else if (expandedAliasType->IsETSUnionType()) { - auto unionType = expandedAliasType->AsETSUnionType(); - needToBeBoxed = false; - for (auto type : unionType->ConstituentTypes()) { - CollectAliasParametersForBoxing(type, parametersNeedToBeBoxed, needToBeBoxed); - } - } else if (expandedAliasType->IsETSFunctionType()) { - auto functionType = expandedAliasType->AsETSFunctionType(); - needToBeBoxed = true; - for (auto param : functionType->ArrowSignature()->Params()) { - CollectAliasParametersForBoxing(param->TsType(), parametersNeedToBeBoxed, needToBeBoxed); - } - CollectAliasParametersForBoxing(functionType->ArrowSignature()->ReturnType(), parametersNeedToBeBoxed, - needToBeBoxed); - } -} - bool ETSChecker::CheckMinimumTypeArgsPresent(const ir::TSTypeAliasDeclaration *typeAliasNode, const ir::TSTypeParameterInstantiation *typeParams) { @@ -1520,7 +1673,7 @@ bool ETSChecker::CheckMinimumTypeArgsPresent(const ir::TSTypeAliasDeclaration *t ir::TypeNode *ETSChecker::ResolveTypeNodeForTypeArg(const ir::TSTypeAliasDeclaration *typeAliasNode, const ir::TSTypeParameterInstantiation *typeParams, size_t idx) { - if (typeParams->Params().size() > idx) { + if (typeParams != nullptr && typeParams->Params().size() > idx) { return typeParams->Params().at(idx); } @@ -1530,60 +1683,67 @@ ir::TypeNode *ETSChecker::ResolveTypeNodeForTypeArg(const ir::TSTypeAliasDeclara Type *ETSChecker::HandleTypeAlias(ir::Expression *const name, const ir::TSTypeParameterInstantiation *const typeParams, ir::TSTypeAliasDeclaration *const typeAliasNode) { - // NOTE (mmartin): modify for default params - if ((typeParams == nullptr) != (typeAliasNode->TypeParams() == nullptr)) { - if (typeParams == nullptr) { + if (typeParams == nullptr && typeAliasNode->TypeParams() != nullptr) { + auto const ¶ms = typeAliasNode->TypeParams()->Params(); + auto isAllTypeParamsHasDefaultType = std::find_if(params.begin(), params.end(), [](ir::TSTypeParameter *param) { + return param->DefaultType() == nullptr; + }) == params.end(); + if (!isAllTypeParamsHasDefaultType) { LogError(diagnostic::GENERIC_ALIAS_WITHOUT_PARAMS, {}, name->Start()); return GlobalTypeError(); } + } + if (typeParams != nullptr && typeAliasNode->TypeParams() == nullptr) { LogError(diagnostic::NON_GENERIC_ALIAS_WITH_PARAMS, {}, typeParams->Start()); return GlobalTypeError(); } - if (typeParams == nullptr) { + if (typeParams == nullptr && typeAliasNode->TypeParams() == nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return GetReferencedTypeBase(name); } - for (auto *const origTypeParam : typeParams->Params()) { - origTypeParam->Check(this); + if (typeParams != nullptr) { + for (auto *const origTypeParam : typeParams->Params()) { + origTypeParam->Check(this); + } + if (CheckMinimumTypeArgsPresent(typeAliasNode, typeParams)) { + return GlobalTypeError(); + } } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Type *const aliasType = GetReferencedTypeBase(name); - auto *substitution = NewSubstitution(); + auto substitution = Substitution {}; + auto relation = Relation(); - if (CheckMinimumTypeArgsPresent(typeAliasNode, typeParams)) { - return GlobalTypeError(); - } - - std::set parametersNeedToBeBoxed; - auto expandedAliasType = aliasType->Substitute(Relation(), substitution); - CollectAliasParametersForBoxing(expandedAliasType, parametersNeedToBeBoxed, false); - - for (std::size_t idx = 0; idx < typeAliasNode->TypeParams()->Params().size(); ++idx) { + for (std::size_t idx = 0U; idx < typeAliasNode->TypeParams()->Params().size(); ++idx) { auto *typeAliasTypeName = typeAliasNode->TypeParams()->Params().at(idx)->Name(); - auto *typeAliasType = typeAliasTypeName->Variable()->TsType(); - if (!typeAliasType->IsETSTypeParameter()) { - continue; - } + auto *typeAliasType = typeAliasTypeName->Variable()->TsType()->MaybeBaseTypeOfGradualType(); + if (typeAliasType->IsETSTypeParameter()) { + ir::TypeNode *typeNode = ResolveTypeNodeForTypeArg(typeAliasNode, typeParams, idx); + auto paramType = typeNode->GetType(this); + + EmplaceSubstituted(&substitution, typeAliasType->AsETSTypeParameter(), paramType); - ir::TypeNode *typeNode = ResolveTypeNodeForTypeArg(typeAliasNode, typeParams, idx); - auto paramType = typeNode->GetType(this); + auto *const maybeIrrelevantTypeArg = paramType->IsETSVoidType() ? GlobalETSUndefinedType() : paramType; + auto *constraintType = typeAliasType->AsETSTypeParameter()->GetConstraintType(); + if (maybeIrrelevantTypeArg->IsTypeError() || constraintType->IsTypeError()) { + continue; // Don't issue extra error notification! + } - if (parametersNeedToBeBoxed.find(typeAliasType) != parametersNeedToBeBoxed.end()) { - if (const auto boxedType = MaybeBoxInRelation(typeNode->GetType(this)); boxedType != nullptr) { - paramType = boxedType; + constraintType = constraintType->Substitute(relation, &substitution); + if (!relation->IsSupertypeOf(constraintType, maybeIrrelevantTypeArg)) { + LogError(diagnostic::TYPEARG_TYPEPARAM_SUBTYPING, {paramType, constraintType}, typeNode->Start()); } } - substitution->insert({typeAliasType->AsETSTypeParameter(), paramType}); // #21835: type argument is not boxed } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ValidateGenericTypeAliasForClonedNode(typeAliasNode->AsTSTypeAliasDeclaration(), typeParams); - return aliasType->Substitute(Relation(), substitution); + return aliasType->Substitute(Relation(), &substitution); } std::vector ETSChecker::GetNameForSynteticObjectType(const util::StringView &source) @@ -1597,7 +1757,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()); } } @@ -1623,6 +1783,26 @@ std::pair FindSpecifierForModuleObject(ir::ETSImportDecl return std::make_pair(false, util::StringView()); } +static void BuildExportedFunctionSignature(ETSChecker *checker, varbinder::Variable *var) +{ + auto method = var->AsLocalVariable()->Declaration()->Node()->AsMethodDefinition(); + ES2PANDA_ASSERT(method->Parent()->IsClassDefinition() && + method->Parent()->AsClassDefinition()->Ident()->Name().Is(compiler::Signatures::ETS_GLOBAL)); + auto classDef = method->Parent()->AsClassDefinition(); + if (classDef->TsType() == nullptr) { + checker->BuildBasicClassProperties(classDef); + } + + auto containingClass = classDef->TsType()->IsGradualType() + ? classDef->TsType()->AsGradualType()->GetBaseType()->AsETSObjectType() + : classDef->TsType()->AsETSObjectType(); + SavedCheckerContext scc(checker, checker->Context().Status(), containingClass); + auto funcType = checker->BuildMethodSignature(method); + funcType->SetVariable(var); + var->SetTsType(funcType); + method->SetTsType(funcType); +} + template void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleObjType, ir::ETSImportDeclaration *importDecl, @@ -1632,9 +1812,16 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO for (auto [_, var] : bindings) { (void)_; auto [found, aliasedName] = FindSpecifierForModuleObject(importDecl, var->AsLocalVariable()->Name()); + if (!var->AsLocalVariable()->Declaration()->Node()->IsValidInCurrentPhase()) { + continue; + } if ((var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->IsExportedType()) && + var->AsLocalVariable()->Declaration()->Node()->HasExportAlias()) && found) { + if (var->AsLocalVariable()->Declaration()->Node()->IsMethodDefinition()) { + BuildExportedFunctionSignature(this, var); + } + if (!aliasedName.Empty()) { moduleObjType->AddReExportAlias(var->Declaration()->Name(), aliasedName); } @@ -1644,6 +1831,11 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO } } +template void ETSChecker::BindingsModuleObjectAddProperty( + ETSObjectType *, ir::ETSImportDeclaration *, const varbinder::Scope::VariableMap &, const util::StringView &); +template void ETSChecker::BindingsModuleObjectAddProperty( + ETSObjectType *, ir::ETSImportDeclaration *, const varbinder::Scope::VariableMap &, const util::StringView &); + util::StringView ETSChecker::FindPropNameForNamespaceImport(const util::StringView &originalName, const util::StringView &importPath) { @@ -1661,8 +1853,8 @@ util::StringView ETSChecker::FindPropNameForNamespaceImport(const util::StringVi } // Helps to prevent searching for the imported file among external sources if it is the entry program -static parser::Program *SelectEntryOrExternalProgram(varbinder::ETSBinder *etsBinder, - const util::StringView &importPath) +parser::Program *ETSChecker::SelectEntryOrExternalProgram(varbinder::ETSBinder *etsBinder, + const util::StringView &importPath) { if (importPath.Is(etsBinder->GetGlobalRecordTable()->Program()->AbsoluteName().Mutf8())) { return etsBinder->GetGlobalRecordTable()->Program(); @@ -1678,10 +1870,22 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT parser::Program *program = SelectEntryOrExternalProgram(static_cast(VarBinder()), importPath); // Check imported properties before assigning them to module object + ES2PANDA_ASSERT(program != nullptr); if (!program->IsASTChecked()) { // NOTE: helps to avoid endless loop in case of recursive imports that uses all bindings - program->MarkASTAsChecked(); + varbinder::RecordTableContext recordTableCtx(VarBinder()->AsETSBinder(), program); + // If external program import current program, the checker status should not contain external + checker::SavedCheckerContext savedContext(this, Context().Status(), Context().ContainingClass()); + if (!VarBinder()->AsETSBinder()->GetGlobalRecordTable()->IsExternal()) { + RemoveStatus(CheckerStatus::IN_EXTERNAL); + } + auto savedProgram = Program(); + VarBinder()->AsETSBinder()->SetProgram(program); + VarBinder()->AsETSBinder()->ResetTopScope(program->GlobalScope()); + program->SetASTChecked(); program->Ast()->Check(this); + VarBinder()->AsETSBinder()->SetProgram(savedProgram); + VarBinder()->AsETSBinder()->ResetTopScope(savedProgram->GlobalScope()); } BindingsModuleObjectAddProperty( @@ -1722,7 +1926,19 @@ Type *ETSChecker::GetReferencedTypeBase(ir::Expression *name) return name->Check(this); } + if (name->IsMemberExpression()) { + return name->Check(this); + } + + if (name->IsLiteral()) { + return name->Check(this); + } + ES2PANDA_ASSERT(name->IsIdentifier()); + if (name->AsIdentifier()->Variable() == nullptr) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + VarBinder()->AsETSBinder()->LookupTypeReference(name->AsIdentifier()); + } auto *const var = name->AsIdentifier()->Variable(); ES2PANDA_ASSERT(var != nullptr); @@ -1731,11 +1947,6 @@ Type *ETSChecker::GetReferencedTypeBase(ir::Expression *name) return name->SetTsType(GlobalTypeError()); } - auto *importData = VarBinder()->AsETSBinder()->DynamicImportDataForVar(var); - if (importData != nullptr && importData->import->IsPureDynamic()) { - return name->SetTsType(GlobalBuiltinDynamicType(importData->import->Language())); - } - return name->SetTsType(ResolveReferencedType(var->AsLocalVariable(), name)); } @@ -1744,10 +1955,13 @@ 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: - if (refVar->Declaration()->Node()->AsClassDefinition()->IsNamespaceTransformed()) { + if (refVar->Declaration()->Node()->IsClassDefinition() && + refVar->Declaration()->Node()->AsClassDefinition()->IsNamespaceTransformed()) { LogError(diagnostic::NAMESPACE_AS_TYPE, {refVar->Name()}, name->Start()); return GlobalTypeError(); } @@ -1765,11 +1979,37 @@ Type *ETSChecker::ResolveReferencedType(varbinder::LocalVariable *refVar, const } } +checker::Type *ETSChecker::GetElementTypeOfArray(checker::Type *type) const +{ + if (type->IsTypeError()) { + return GlobalTypeError(); + } + if (type->IsETSArrayType()) { + return type->AsETSArrayType()->ElementType(); + } + if (type->IsETSResizableArrayType()) { + return type->AsETSResizableArrayType()->ElementType(); + } + if (type->IsETSReadonlyArrayType()) { + auto const &typeArgs = type->AsETSObjectType()->TypeArguments(); + ES2PANDA_ASSERT(!typeArgs.empty()); + return typeArgs.front(); + } + ES2PANDA_UNREACHABLE(); +} + +const checker::Type *ETSChecker::GetElementTypeOfArray(const checker::Type *type) const +{ + return GetElementTypeOfArray(const_cast(type)); +} + void ETSChecker::ConcatConstantString(util::UString &target, Type *type) { switch (ETSType(type)) { case TypeFlag::ETS_OBJECT: { - ES2PANDA_ASSERT(type->IsETSStringType()); + if (!type->IsETSStringType()) { + break; + } target.Append(type->AsETSStringType()->GetValue()); break; } @@ -1821,7 +2061,7 @@ Type *ETSChecker::HandleStringConcatenation(Type *leftType, Type *rightType) return GlobalETSStringLiteralType(); } - util::UString concatenated(Allocator()); + util::UString concatenated(ProgramAllocator()); ConcatConstantString(concatenated, leftType); ConcatConstantString(concatenated, rightType); @@ -1954,8 +2194,9 @@ varbinder::VariableFlags ETSChecker::GetAccessFlagFromNode(const ir::AstNode *no Type *ETSChecker::CheckSwitchDiscriminant(ir::Expression *discriminant) { - discriminant->Check(this); - auto *discriminantType = GetNonConstantType(MaybeUnboxExpression(discriminant)); + Type *discriminantType = discriminant->Check(this); + discriminantType = GetNonConstantType(MaybeUnboxType(discriminantType)); + ES2PANDA_ASSERT(discriminantType != nullptr); if (!discriminantType->HasTypeFlag(TypeFlag::VALID_SWITCH_TYPE)) { if (!(discriminantType->IsETSObjectType() && discriminantType->AsETSObjectType()->HasObjectFlag( @@ -1967,33 +2208,12 @@ Type *ETSChecker::CheckSwitchDiscriminant(ir::Expression *discriminant) return discriminantType; } -void ETSChecker::AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType) -{ - if (boxingUnboxingType->IsETSObjectType()) { - node->AddBoxingUnboxingFlags(GetBoxingFlag(boxingUnboxingType)); - } else if (!boxingUnboxingType->IsETSUnionType()) { - node->AddBoxingUnboxingFlags(GetUnboxingFlag(boxingUnboxingType)); - } -} - Type *ETSChecker::MaybeBoxExpression(ir::Expression *expr) { auto *promoted = MaybeBoxType(expr->TsType()); - if (promoted != expr->TsType()) { - expr->AddBoxingUnboxingFlags(GetBoxingFlag(promoted)); - } return promoted; } -Type *ETSChecker::MaybeUnboxExpression(ir::Expression *expr) -{ - auto *primitive = MaybeUnboxType(expr->TsType()); - if (primitive != expr->TsType()) { - expr->AddBoxingUnboxingFlags(GetUnboxingFlag(primitive)); - } - return primitive; -} - void ETSChecker::CheckForSameSwitchCases(ArenaVector const &cases) { CheckItemCasesConstant(cases); @@ -2024,7 +2244,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: { @@ -2033,7 +2253,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()) { @@ -2041,8 +2261,14 @@ 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; + } + ES2PANDA_ASSERT(var->TsType() != nullptr); + 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) @@ -2083,7 +2309,7 @@ void ETSChecker::CheckItemCasesConstant(ArenaVector c if (caseTest == nullptr) { continue; } - auto *caseType = caseTest->TsType(); + auto *caseType = MaybeUnboxType(caseTest->TsType()); if (caseType->HasTypeFlag(TypeFlag::TYPE_ERROR)) { continue; } @@ -2161,7 +2387,7 @@ void ETSChecker::CheckItemCasesDuplicate(ArenaVector } if (caseTest->IsLiteral() && compareCaseTest->IsLiteral() && - GetStringFromLiteral(caseTest) != GetStringFromLiteral(compareCaseTest)) { + caseTest->AsLiteral()->ToString() != compareCaseTest->AsLiteral()->ToString()) { continue; } @@ -2191,7 +2417,7 @@ bool ETSChecker::CompareIdentifiersValuesAreDifferent(ir::Expression *compareVal return caseValue != compareCaseValue; } - return caseValue != GetStringFromLiteral(compareValue); + return caseValue != compareValue->ToString(); } void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, @@ -2199,7 +2425,7 @@ void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expr { currentCase->Check(this); - if (!IsConstantMemberOrIdentifierExpression(currentCase)) { + if (!IsConstantMemberOrIdentifierExpression(currentCase, true)) { return; } @@ -2215,23 +2441,6 @@ void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expr } } -std::string ETSChecker::GetStringFromLiteral(ir::Expression *caseTest) const -{ - switch (caseTest->Type()) { - case ir::AstNodeType::CHAR_LITERAL: { - return std::to_string(caseTest->AsCharLiteral()->Char()); - } - case ir::AstNodeType::STRING_LITERAL: - case ir::AstNodeType::NULL_LITERAL: - case ir::AstNodeType::UNDEFINED_LITERAL: - case ir::AstNodeType::NUMBER_LITERAL: { - return util::Helpers::LiteralToPropName(caseTest).Mutf8(); - } - default: - ES2PANDA_UNREACHABLE(); - } -} - bool ETSChecker::IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare) { return target->Declaration()->Type() == compare->Declaration()->Type(); @@ -2262,7 +2471,7 @@ ETSObjectType *ETSChecker::GetRelevantArgumentedTypeFromChild(ETSObjectType *con auto *relevantType = CreateETSObjectType(child->GetDeclNode(), child->ObjectFlags()); ArenaVector params = child->TypeArguments(); - + ES2PANDA_ASSERT(relevantType != nullptr); relevantType->SetTypeArguments(std::move(params)); relevantType->SetEnclosingType(child->EnclosingType()); relevantType->SetSuperType(child->SuperType()); @@ -2275,7 +2484,22 @@ ETSObjectType *ETSChecker::GetRelevantArgumentedTypeFromChild(ETSObjectType *con return GetRelevantArgumentedTypeFromChild(child->SuperType(), target); } +Substitution ETSChecker::ArenaSubstitutionToSubstitution(const ArenaSubstitution *orig) +{ + Substitution copied {}; + std::copy(orig->begin(), orig->end(), std::inserter(copied, copied.end())); + return copied; +} + void ETSChecker::EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg) +{ + // *only* reference type may be substituted, no exceptions + ES2PANDA_ASSERT(typeArg->IsETSReferenceType()); + ES2PANDA_ASSERT(substitution != nullptr); + substitution->emplace(tparam, typeArg); +} + +void ETSChecker::EmplaceSubstituted(ArenaSubstitution *substitution, ETSTypeParameter *tparam, Type *typeArg) { // *only* reference type may be substituted, no exceptions ES2PANDA_ASSERT(typeArg->IsETSReferenceType()); @@ -2298,7 +2522,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) @@ -2324,7 +2548,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) @@ -2332,7 +2556,9 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) std::stringstream ss; for (auto *p : type->Params()) { auto *const param = p->AsETSParameterExpression(); - param->TypeAnnotation()->GetType(this)->ToString(ss, true); + auto *paramType = param->TypeAnnotation()->GetType(this); + ES2PANDA_ASSERT(paramType != nullptr); + paramType->ToString(ss, true); ss << ";"; } @@ -2340,24 +2566,20 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) if (type->ReturnType()->IsTSThisType()) { type->Params()[0]->AsETSParameterExpression()->TypeAnnotation()->TsType()->ToString(ss, true); } else { - type->ReturnType()->GetType(this)->ToString(ss, true); + auto *returnType = type->ReturnType()->GetType(this); + ES2PANDA_ASSERT(returnType != nullptr); + returnType->ToString(ss, true); } ss << "extensionFunction;"; } else { - type->ReturnType()->GetType(this)->ToString(ss, true); + auto *returnType = type->ReturnType()->GetType(this); + ES2PANDA_ASSERT(returnType != nullptr); + returnType->ToString(ss, true); } ss << ";"; - if (type->IsThrowing()) { - ss << "throws;"; - } - - if (type->IsRethrowing()) { - ss << "rethrows;"; - } - - return util::UString(ss.str(), Allocator()).View(); + return util::UString(ss.str(), ProgramAllocator()).View(); } ETSObjectType *ETSChecker::GetOriginalBaseType(Type *const object) @@ -2437,35 +2659,55 @@ std::vector ETSChecker::FindTypeInferenceArguments(const ArenaVectorAsETSUnionType()->Types()) { if (type->IsETSFunctionType()) { - return lambda->Params().size() == type->AsETSFunctionType()->Params().size(); + assignable |= lambda->Params().size() <= type->AsETSFunctionType()->Params().size(); + continue; + } + + if (type->IsETSTypeReference()) { + auto aliasType = util::Helpers::DerefETSTypeReference(type); + assignable |= aliasType->IsETSFunctionType() && + lambda->Params().size() <= aliasType->AsETSFunctionType()->Params().size(); } } - return false; + return assignable; } void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType, Signature *maybeSubstitutedFunctionSig) { for (size_t i = 0; i < lambda->Params().size(); ++i) { + if (!lambda->Params().at(i)->IsETSParameterExpression()) { + LogError(diagnostic::INVALID_LAMBDA_PARAMETER, lambda->Params().at(i)->Start()); + continue; + } auto *const lambdaParam = lambda->Params().at(i)->AsETSParameterExpression()->Ident(); - if (lambdaParam->TypeAnnotation() == nullptr) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - Type *inferredType = calleeType->Params()[i]->AsETSParameterExpression()->TypeAnnotation()->Check(this); - bool isPrimitive = inferredType != nullptr && inferredType->IsETSPrimitiveType(); - if (!isPrimitive && maybeSubstitutedFunctionSig != nullptr) { - ES2PANDA_ASSERT(maybeSubstitutedFunctionSig->Params().size() == calleeType->Params().size()); + if (lambdaParam->TypeAnnotation() != nullptr) { + continue; + } + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + Type *inferredType = calleeType->Params()[i]->AsETSParameterExpression()->TypeAnnotation()->Check(this); + bool isPrimitive = inferredType != nullptr && inferredType->IsETSPrimitiveType(); + if (!isPrimitive && maybeSubstitutedFunctionSig != nullptr) { + auto sigParamSize = maybeSubstitutedFunctionSig->Params().size(); + ES2PANDA_ASSERT( + sigParamSize == calleeType->Params().size() || + (maybeSubstitutedFunctionSig->HasRestParameter() && sigParamSize <= calleeType->Params().size())); + if (i < sigParamSize) { inferredType = maybeSubstitutedFunctionSig->Params()[i]->TsType(); + } else if (!maybeSubstitutedFunctionSig->RestVar()->TsType()->IsETSTupleType()) { + inferredType = GetElementTypeOfArray(maybeSubstitutedFunctionSig->RestVar()->TsType()); } - lambdaParam->Variable()->SetTsType(inferredType); - lambdaParam->SetTsType(inferredType); } + lambdaParam->Variable()->SetTsType(inferredType); + lambdaParam->SetTsType(inferredType); } if (lambda->ReturnTypeAnnotation() == nullptr) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Type *inferredReturnType = calleeType->ReturnType()->GetType(this); bool isPrimitive = inferredReturnType != nullptr && inferredReturnType->IsETSPrimitiveType(); if (!isPrimitive && maybeSubstitutedFunctionSig != nullptr) { @@ -2479,16 +2721,18 @@ void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, Signature *sign { ES2PANDA_ASSERT(signature->Params().size() >= lambda->Params().size()); for (size_t i = 0; i < lambda->Params().size(); ++i) { + if (!lambda->Params().at(i)->IsETSParameterExpression()) { + LogError(diagnostic::INVALID_LAMBDA_PARAMETER, lambda->Params().at(i)->Start()); + continue; + } auto *const lambdaParam = lambda->Params().at(i)->AsETSParameterExpression()->Ident(); if (lambdaParam->TypeAnnotation() == nullptr) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) lambdaParam->Variable()->SetTsType(signature->Params().at(i)->TsType()); lambdaParam->SetTsType(signature->Params().at(i)->TsType()); } } if (lambda->ReturnTypeAnnotation() == nullptr) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) lambda->SetPreferredReturnType(signature->ReturnType()); } } @@ -2534,7 +2778,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); @@ -2561,16 +2805,17 @@ static void ReInitScopesForTypeAnnotation(ETSChecker *checker, ir::TypeNode *typ 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()) - .View()); + std::string newName = util::NameMangler::GetInstance()->CreateMangledNameByTypeAndName( + util::NameMangler::PROPERTY, classProp->Key()->AsIdentifier()->Name()); + + classProp->Key()->AsIdentifier()->SetName(util::UString(newName, ProgramAllocator()).View()); classProp->AddModifier(ir::ModifierFlags::PRIVATE); - auto *fieldDecl = Allocator()->New(classProp->Key()->AsIdentifier()->Name()); + auto *fieldDecl = ProgramAllocator()->New(classProp->Key()->AsIdentifier()->Name()); + ES2PANDA_ASSERT(fieldDecl != nullptr); 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()); @@ -2580,10 +2825,12 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), scope); ReInitScopesForTypeAnnotation(this, classProp->TypeAnnotation(), scope); compiler::InitScopesPhaseETS::RunExternalNode(classProp->Value(), VarBinder()); + VarBinder()->AsETSBinder()->ResolveReferencesForScopeWithContext(classProp, scope); 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) @@ -2593,18 +2840,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()); @@ -2614,15 +2863,15 @@ 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 { @@ -2630,12 +2879,12 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A } // 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(), VarBinder(), 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); @@ -2643,19 +2892,20 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A 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()); + ident->SetTsTypeAnnotation(nullptr); 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, @@ -2665,7 +2915,8 @@ 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)); + ES2PANDA_ASSERT(body != nullptr); body->SetScope(functionScope); return body; } @@ -2675,14 +2926,17 @@ static std::tupleAllocator()->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); + auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); - 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) @@ -2691,7 +2945,7 @@ static std::tupleTypeAnnotation() == nullptr ? nullptr // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - : field->TypeAnnotation()->Clone(checker->Allocator(), nullptr); + : field->TypeAnnotation()->Clone(checker->ProgramAllocator(), nullptr); ReInitScopesForTypeAnnotation(checker, returnTypeAnn, paramScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::ModifierFlags modifierFlag = @@ -2699,8 +2953,8 @@ static std::tuple(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), @@ -2720,34 +2974,40 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty 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); + CHECK_NOT_NULL(funcExpr); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = checker->AllocNode( + auto *method = checker->ProgramAllocNode( isSetter ? ir::MethodDefinitionKind::SET : ir::MethodDefinitionKind::GET, 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); + checker->ProgramAllocator(), false); + auto *decl = checker->ProgramAllocator()->New( + checker->ProgramAllocator(), property->Key()->AsIdentifier()->Name(), method); + auto *var = checker->ProgramAllocator()->New(decl, varbinder::VariableFlags::VAR); + CHECK_NOT_NULL(var); var->AddFlag(varbinder::VariableFlags::METHOD); methodIdent->SetVariable(var); - method->Id()->SetMutator(); + auto *methodId = method->Id(); + CHECK_NOT_NULL(methodId); + methodId->SetMutator(); method->SetRange(field->Range()); + auto *methodFunc = method->Function(); + CHECK_NOT_NULL(methodFunc); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - method->Function()->SetIdent(method->Id()->Clone(checker->Allocator(), nullptr)); - method->Function()->AddModifier(method->Modifiers()); + methodFunc->SetIdent(methodId->Clone(checker->ProgramAllocator(), nullptr)); + methodFunc->AddModifier(method->Modifiers()); method->SetVariable(var); method->SetParent(field->Parent()); 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); @@ -2764,18 +3024,19 @@ 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; } - auto *const classProp = classType - ->GetProperty(interfaceProp->Key()->AsIdentifier()->Name(), - PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE) - ->Declaration() - ->Node() - ->AsClassProperty(); + auto *const classProp = + classType + ->GetProperty(interfaceProp->Key()->AsIdentifier()->Name(), + PropertySearchFlags::SEARCH_INSTANCE_FIELD | PropertySearchFlags::SEARCH_IN_BASE) + ->Declaration() + ->Node() + ->AsClassProperty(); classProp->AddModifier(ir::ModifierFlags::SUPER_OWNER); return classProp; } @@ -2784,6 +3045,8 @@ void ETSChecker::SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObje ir::MethodDefinition *getter, ir::MethodDefinition *setter, const bool inExternal) { + auto getProgram = [](ir::AstNode *node) { return node->Range().start.Program(); }; + auto *const classDef = classType->GetDeclNode()->AsClassDefinition(); for (auto &method : {getter, setter}) { if (method == nullptr) { @@ -2795,19 +3058,21 @@ void ETSChecker::SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObje method->TsType()->AddTypeFlag(tflag); method->Variable()->SetTsType(method->TsType()); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); if (((originalProp->Modifiers() & mflag) != 0U)) { - method->Function()->AddModifier(ir::ModifierFlags::OVERRIDE); + func->AddModifier(ir::ModifierFlags::OVERRIDE); } - if (inExternal) { - method->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + if (inExternal && !getProgram(originalProp)->IsGenAbcForExternal()) { + func->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } if (originalProp->IsDeclare()) { method->AddModifier(ir::ModifierFlags::DECLARE); - method->Function()->AddModifier(ir::ModifierFlags::DECLARE); + func->AddModifier(ir::ModifierFlags::DECLARE); } - this->CheckOverride(method->Function()->Signature()); + this->CheckOverride(func->Signature()); method->SetParent(classDef); classType->AddProperty(method->Variable()->AsLocalVariable()); } @@ -2817,7 +3082,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(); @@ -2833,7 +3098,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(); @@ -2844,9 +3109,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}) { @@ -2866,13 +3131,45 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin getter->Variable()->TsType()->AsETSFunctionType()->AddCallSignature( setter->TsType()->AsETSFunctionType()->CallSignatures()[0]); getter->AddOverload(setter); + setter->SetParent(getter); + } +} + +void ETSChecker::CreateTransformedCallee(ir::Identifier *ident, ir::Identifier *classId, ir::Identifier *methodId, + ir::CallExpression *callExpr) +{ + ir::MemberExpression *transformedCallee = nullptr; + classId->SetRange(ident->Range()); + if (ident->Parent()->IsMemberExpression()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + transformedCallee = ProgramAllocNode( + ident->Parent()->AsMemberExpression(), methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ident->Parent()->AsMemberExpression()->SetParent(transformedCallee); + } else { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + transformedCallee = ProgramAllocNode( + classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + transformedCallee->SetParent(callExpr); } + + methodId->SetRange(ident->Range()); + transformedCallee->SetRange(ident->Range()); + // Note: Should not modify the AST + // Related issue: #issue27122 + callExpr->SetCallee(transformedCallee); } +// 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()); - ES2PANDA_ASSERT(ident->Parent()->AsCallExpression()->Callee() == ident); + ir::CallExpression *callExpr = nullptr; + if (ident->Parent()->IsMemberExpression()) { + callExpr = ident->Parent()->Parent()->AsCallExpression(); + } else { + ES2PANDA_ASSERT(ident->Parent()->IsCallExpression()); + ES2PANDA_ASSERT(ident->Parent()->AsCallExpression()->Callee() == ident); + callExpr = ident->Parent()->AsCallExpression(); + } if (!resolvedType->IsETSObjectType()) { return false; @@ -2899,28 +3196,18 @@ 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) { methodId->SetVariable(invokeMethod); } - - auto *transformedCallee = - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - - classId->SetRange(ident->Range()); - methodId->SetRange(ident->Range()); - transformedCallee->SetRange(ident->Range()); - - auto *callExpr = ident->Parent()->AsCallExpression(); - transformedCallee->SetParent(callExpr); - callExpr->SetCallee(transformedCallee); - + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + CreateTransformedCallee(ident, classId, methodId, callExpr); if (instantiateMethod != nullptr) { + auto lexScope {varbinder::LexicalScope::Enter(VarBinder(), compiler::NearestScope(callExpr))}; // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *argExpr = GenerateImplicitInstantiateArg(std::string(className)); @@ -2948,6 +3235,7 @@ void ETSChecker::ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclarati if (reExportType->IsTypeError()) { continue; } + ES2PANDA_ASSERT(lastObjectType != nullptr); lastObjectType->AddReExports(reExportType->AsETSObjectType()); for (auto node : importDecl->Specifiers()) { if (node->IsImportSpecifier()) { @@ -2960,7 +3248,7 @@ void ETSChecker::ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclarati Type *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration *importDecl, ir::Identifier *ident) { - auto importPath = importDecl->ResolvedSource(); + auto importPath = importDecl->IsPureDynamic() ? importDecl->DeclPath() : importDecl->ResolvedSource(); parser::Program *program = SelectEntryOrExternalProgram(static_cast(VarBinder()), importPath); if (program == nullptr) { @@ -2971,15 +3259,17 @@ 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); + ES2PANDA_ASSERT(rootVar != nullptr); rootVar->SetTsType(moduleObjectType); ImportNamespaceObjectTypeAddReExportType(importDecl, moduleObjectType, ident); @@ -2992,9 +3282,12 @@ Type *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration *importD ETSChecker::NamedAccessMeta ETSChecker::FormNamedAccessMetadata(varbinder::Variable const *prop) { + CHECK_NOT_NULL(prop); const auto *field = prop->Declaration()->Node()->AsClassProperty(); const auto *owner = field->Parent()->AsClassDefinition(); - return {owner->TsType()->AsETSObjectType(), field->TsType(), field->Id()->Name()}; + auto *fieldId = field->Id(); + CHECK_NOT_NULL(fieldId); + return {owner->TsType()->AsETSObjectType(), field->TsType(), fieldId->Name()}; } void ETSChecker::ETSObjectTypeDeclNode(ETSChecker *checker, ETSObjectType *const objectType) @@ -3016,12 +3309,14 @@ 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); } + ES2PANDA_ASSERT(callExpr != nullptr); callExpr->SetRange(expr->Range()); return callExpr->AsCallExpression(); } @@ -3032,7 +3327,7 @@ void ETSChecker::CheckTypeParameterVariance(ir::ClassDefinition *classDef) return; } - Context().SetContainingClass(classDef->TsType()->AsETSObjectType()); + Context().SetContainingClass(classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()); auto checkVariance = [this](VarianceFlag varianceFlag, ir::Expression *expression, Type *type) { Relation()->Result(RelationResult::TRUE); Relation()->SetNode(expression); @@ -3066,19 +3361,6 @@ void ETSChecker::CheckTypeParameterVariance(ir::ClassDefinition *classDef) } } -void ETSChecker::SetPreferredTypeIfPossible(ir::Expression *const expr, Type *const targetType) -{ - // Object expression requires that its type be set by the context before checking. in this case, the target type - // provides that context. - if (expr->IsObjectExpression()) { - expr->AsObjectExpression()->SetPreferredType(targetType); - } - - if (expr->IsArrayExpression()) { - expr->AsArrayExpression()->SetPreferredType(targetType); - } -} - checker::ETSFunctionType *ETSChecker::IntersectSignatureSets(const checker::ETSFunctionType *left, const checker::ETSFunctionType *right) { @@ -3095,7 +3377,7 @@ checker::ETSFunctionType *ETSChecker::IntersectSignatureSets(const checker::ETSF std::swap(left, right); } - ArenaVector intersection {Allocator()->Adapter()}; + ArenaVector intersection {ProgramAllocator()->Adapter()}; for (const auto sig : left->CallSignatures()) { auto found = right->FindSpecificSignature( diff --git a/ets2panda/checker/ets/narrowingConverter.cpp b/ets2panda/checker/ets/narrowingConverter.cpp deleted file mode 100644 index 3b2d1cf9e0b4134083188b7a9ede2a7c6df0e92e..0000000000000000000000000000000000000000 --- a/ets2panda/checker/ets/narrowingConverter.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "narrowingConverter.h" - -namespace ark::es2panda::checker { -} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/narrowingConverter.h b/ets2panda/checker/ets/narrowingConverter.h deleted file mode 100644 index f42051d88b9042d717680e29e899a2d0f472c87b..0000000000000000000000000000000000000000 --- a/ets2panda/checker/ets/narrowingConverter.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_CONVERTER_H -#define ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_CONVERTER_H - -#include "checker/ETSchecker.h" -#include "checker/ets/typeConverter.h" -#include "util/helpers.h" - -namespace ark::es2panda::checker { -class NarrowingConverter : public TypeConverter { -public: - static constexpr TypeFlag NARROWABLE_TO_FLOAT = TypeFlag::DOUBLE; - static constexpr TypeFlag NARROWABLE_TO_LONG = TypeFlag::FLOAT | NARROWABLE_TO_FLOAT; - static constexpr TypeFlag NARROWABLE_TO_INT = TypeFlag::LONG | NARROWABLE_TO_LONG; - static constexpr TypeFlag NARROWABLE_TO_CHAR = TypeFlag::SHORT | TypeFlag::INT | NARROWABLE_TO_INT; - static constexpr TypeFlag NARROWABLE_TO_SHORT = TypeFlag::CHAR | TypeFlag::INT | NARROWABLE_TO_INT; - static constexpr TypeFlag NARROWABLE_TO_BYTE = TypeFlag::CHAR | NARROWABLE_TO_CHAR; - - explicit NarrowingConverter(ETSChecker *checker, TypeRelation *relation, Type *target, Type *source) - : TypeConverter(checker, relation, target, source) - { - if (!relation->ApplyNarrowing()) { - return; - } - - ES2PANDA_ASSERT(relation->GetNode()); - - switch (ETSChecker::ETSChecker::ETSType(target)) { - case TypeFlag::BYTE: { - ApplyNarrowing(NARROWABLE_TO_BYTE); - break; - } - case TypeFlag::CHAR: { - ApplyNarrowing(NARROWABLE_TO_CHAR); - break; - } - case TypeFlag::SHORT: { - ApplyNarrowing(NARROWABLE_TO_SHORT); - break; - } - case TypeFlag::INT: { - ApplyNarrowing(NARROWABLE_TO_INT); - break; - } - case TypeFlag::LONG: { - ApplyNarrowing(NARROWABLE_TO_LONG); - break; - } - case TypeFlag::FLOAT: { - ApplyNarrowing(NARROWABLE_TO_FLOAT); - break; - } - - default: { - break; - } - } - } - -private: - template - void ApplyNarrowing(TypeFlag flag) - { - if (!Source()->HasTypeFlag(flag)) { - return; - } - - switch (ETSChecker::ETSChecker::ETSType(Source())) { - case TypeFlag::CHAR: { - ApplyNarrowing(); - break; - } - case TypeFlag::SHORT: { - ApplyNarrowing(); - break; - } - case TypeFlag::INT: { - ApplyNarrowing(); - break; - } - case TypeFlag::LONG: { - ApplyNarrowing(); - break; - } - case TypeFlag::FLOAT: { - ApplyNarrowing(); - break; - } - case TypeFlag::DOUBLE: { - ApplyNarrowing(); - break; - } - default: { - break; - } - } - } - - template - To CastFloatingPointToIntOrLong(From value) - { - if (std::isinf(value)) { - if (std::signbit(value)) { - return std::numeric_limits::min(); - } - return std::numeric_limits::max(); - } - ES2PANDA_ASSERT(std::is_floating_point_v); - ES2PANDA_ASSERT(std::is_integral_v); - To minInt = std::numeric_limits::min(); - To maxInt = std::numeric_limits::max(); - auto floatMinInt = static_cast(minInt); - auto floatMaxInt = static_cast(maxInt); - - if (value > floatMinInt) { - if (value < floatMaxInt) { - return static_cast(value); - } - return maxInt; - } - if (std::isnan(value)) { - return 0; - } - return minInt; - } - - template - TType CalculateNarrowedValue(Type *target, Type *source, SType value) - { - switch (ETSChecker::ETSChecker::ETSType(target)) { - case TypeFlag::BYTE: - case TypeFlag::CHAR: - case TypeFlag::SHORT: { - if (source->HasTypeFlag(checker::TypeFlag::DOUBLE) || source->HasTypeFlag(checker::TypeFlag::FLOAT)) { - return static_cast(CastFloatingPointToIntOrLong(value)); - } - return static_cast(value); - } - case TypeFlag::INT: - case TypeFlag::LONG: { - if (source->HasTypeFlag(checker::TypeFlag::DOUBLE) || source->HasTypeFlag(checker::TypeFlag::FLOAT)) { - return CastFloatingPointToIntOrLong(value); - } - return static_cast(value); - } - case TypeFlag::FLOAT: - case TypeFlag::DOUBLE: { - return static_cast(value); - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - } - - template - void ApplyNarrowing() - { - using SType = typename SourceType::UType; - using TType = typename TargetType::UType; - - if (Source()->HasTypeFlag(TypeFlag::CONSTANT)) { - SType value = reinterpret_cast(Source())->GetValue(); - if (!Relation()->InCastingContext() && Source()->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT) && - Target()->HasTypeFlag(TypeFlag::ETS_INTEGRAL)) { - auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); - if (narrowedValue != value) { - Relation()->Result(RelationResult::ERROR); - return; - } - } - - if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { - Relation()->Result(true); - return; - } - - Relation()->Result(RelationResult::ERROR); - return; - } - - Relation()->Result(true); - } -}; -} // namespace ark::es2panda::checker - -#endif diff --git a/ets2panda/checker/ets/narrowingWideningConverter.cpp b/ets2panda/checker/ets/narrowingWideningConverter.cpp deleted file mode 100644 index 41ed3aeb8cf47902ad35907f636e97f771c1ffd2..0000000000000000000000000000000000000000 --- a/ets2panda/checker/ets/narrowingWideningConverter.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "narrowingWideningConverter.h" - -namespace ark::es2panda::checker { -} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 9b36448b0bcfbaeae96b279b35ce235a4e10d262..3a2c876796b279d11c1623da93556dec47c02a82 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -13,12 +13,16 @@ * limitations under the License. */ +#include #include "checker/ETSchecker.h" +#include "checker/checkerContext.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 "checker/types/ets/etsAwaitedType.h" +#include "checker/types/gradualType.h" +#include "compiler/lowering/phase.h" #include "ir/base/classDefinition.h" #include "ir/base/classElement.h" #include "ir/base/classProperty.h" @@ -29,6 +33,7 @@ #include "ir/ets/etsTypeReference.h" #include "ir/ets/etsTypeReferencePart.h" #include "ir/ets/etsUnionType.h" +#include "ir/expression.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/callExpression.h" #include "ir/expressions/functionExpression.h" @@ -42,17 +47,21 @@ #include "ir/ts/tsInterfaceHeritage.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ts/tsTypeParameterDeclaration.h" +#include "util/diagnostic.h" #include "varbinder/declaration.h" #include "varbinder/variableFlags.h" #include "generated/signatures.h" #include "generated/diagnostic.h" +#include "util/helpers.h" namespace ark::es2panda::checker { +static constexpr std::string_view SET_PROTOTYPE_OF = "setPrototypeOf"; + 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; } @@ -79,10 +88,42 @@ static bool CheckGetterSetterDecl(varbinder::LocalVariable const *child, varbind return checkChild && checkParent && (child->TsType()->IsETSFunctionType() || parent->TsType()->IsETSFunctionType()); } +static bool CheckOverloadDecl(varbinder::LocalVariable *child, varbinder::LocalVariable *parent) +{ + if (!child->Declaration()->Node()->IsOverloadDeclaration() && + !parent->Declaration()->Node()->IsOverloadDeclaration()) { + return false; + } + + if (!child->Declaration()->Node()->IsOverloadDeclaration() || + !parent->Declaration()->Node()->IsOverloadDeclaration()) { + return true; + } + + auto *childOverload = child->Declaration()->Node()->AsOverloadDeclaration(); + auto *parentOverload = parent->Declaration()->Node()->AsOverloadDeclaration(); + for (auto *baseMethodName : parentOverload->OverloadedList()) { + ES2PANDA_ASSERT(baseMethodName->IsIdentifier()); + auto res = std::find_if(childOverload->OverloadedList().begin(), childOverload->OverloadedList().end(), + [baseMethodName](ir::Expression *subMethodName) { + return subMethodName->IsIdentifier() && subMethodName->AsIdentifier()->Name() == + baseMethodName->AsIdentifier()->Name(); + }); + if (res == childOverload->OverloadedList().end()) { + return false; + } + } + return true; +} + static bool CheckFunctionDecl(varbinder::LocalVariable *child, varbinder::LocalVariable *parent) { + if (child->Declaration()->Node()->IsOverloadDeclaration() || + parent->Declaration()->Node()->IsOverloadDeclaration()) { + return false; + } ES2PANDA_ASSERT(child->Declaration()->Type() == parent->Declaration()->Type()); - if (!child->TsType()->IsETSFunctionType()) { + if (!child->TsType()->IsETSMethodType() || !parent->TsType()->IsETSMethodType()) { return true; } @@ -115,7 +156,8 @@ static bool CheckObjectTypeAndSuperType(ETSChecker *checker, ETSObjectType *type auto *classDef = type->GetDeclNode()->AsClassDefinition(); auto cName = classDef->Ident()->Name(); if (cName == compiler::Signatures::PARTIAL_TYPE_NAME || cName == compiler::Signatures::READONLY_TYPE_NAME || - cName == compiler::Signatures::REQUIRED_TYPE_NAME || cName == compiler::Signatures::FIXED_ARRAY_TYPE_NAME) { + cName == compiler::Signatures::REQUIRED_TYPE_NAME || cName == compiler::Signatures::FIXED_ARRAY_TYPE_NAME || + cName == compiler::Signatures::AWAITED_TYPE_NAME) { checker->LogError(diagnostic::USING_RESERVED_NAME_AS_VARIABLE_OR_TYPE_NAME, {cName}, type->GetDeclNode()->Start()); type->SetSuperType(checker->GlobalETSObjectType()); @@ -153,7 +195,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) return false; } - Type *superType = classDef->Super()->AsTypeNode()->GetType(this); + auto *superType = classDef->Super()->AsTypeNode()->GetType(this)->MaybeBaseTypeOfGradualType(); if (superType == nullptr) { return true; } @@ -163,7 +205,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) return true; } - ETSObjectType *superObj = superType->AsETSObjectType(); + ETSObjectType *superObj = superType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); // struct node has class definition, too if (superObj->GetDeclNode()->Parent()->IsETSStructDeclaration()) { @@ -185,6 +227,12 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) void ETSChecker::ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos) { + ES2PANDA_ASSERT(interface != nullptr); + interface = interface->MaybeBaseTypeOfGradualType(); + if (interface->IsETSObjectType() && interface->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)) { + LogError(diagnostic::INTERFACE_EXTENDS_CLASS, {}, pos); + return; + } if (!interface->IsETSObjectType() || !interface->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { LogError(diagnostic::NOT_INTERFACE, {}, pos); return; @@ -261,7 +309,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 +358,19 @@ 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()); + variable->SetTsType(GlobalTypeError()); ok = false; - } else if (variable->TsType() != nullptr && variable->TsType()->IsTypeError()) { + } else if (defaultType != nullptr && defaultType->IsTypeError()) { ok = false; } } @@ -325,6 +378,12 @@ bool ETSChecker::CheckDefaultTypeParameter(const ir::TSTypeParameter *param, Typ }; if (param->DefaultType() != nullptr) { + TypeStackElement tse(this, param->DefaultType(), {{diagnostic::TYPE_PARAM_CIRCULAR_DEFAULT_TYPE}}, + param->DefaultType()->Start()); + if (tse.HasTypeError()) { + return false; + } + param->DefaultType()->Iterate(checkDefault); } @@ -369,7 +428,7 @@ void ETSChecker::SetUpTypeParameterConstraint(ir::TSTypeParameter *const param) traverseReferenced(param->Constraint()); paramType->SetConstraintType(param->Constraint()->GetType(this)); } else { - paramType->SetConstraintType(GlobalETSNullishObjectType()); + paramType->SetConstraintType(GlobalETSAnyType()); } if (param->DefaultType() != nullptr) { @@ -389,13 +448,12 @@ ETSTypeParameter *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const para } auto *const paramType = CreateTypeParameter(); - + ES2PANDA_ASSERT(paramType != nullptr); paramType->AddTypeFlag(TypeFlag::GENERIC); paramType->SetDeclNode(param); paramType->SetVariable(param->Variable()); // NOTE: #15026 recursive type parameter workaround - paramType->SetConstraintType(GlobalETSNullishObjectType()); - + paramType->SetConstraintType(GlobalETSAnyType()); var->SetTsType(paramType); return paramType; } @@ -418,6 +476,14 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } +Type *ETSChecker::MaybeGradualType(ir::AstNode *node, ETSObjectType *type) +{ + ES2PANDA_ASSERT(node->IsClassDefinition() || node->IsTSInterfaceDeclaration()); + auto isDynamic = node->IsClassDefinition() ? node->AsClassDefinition()->Language().IsDynamic() + : node->AsTSInterfaceDeclaration()->Language().IsDynamic(); + return isDynamic ? CreateGradualType(type) : type; +} + Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) { auto *var = interfaceDecl->Id()->Variable(); @@ -427,14 +493,27 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte } checker::ETSObjectType *interfaceType {}; + checker::Type *type {}; if (var->TsType() == nullptr) { interfaceType = CreateETSObjectTypeOrBuiltin(interfaceDecl, checker::ETSObjectFlags::INTERFACE); interfaceType->SetVariable(var); - var->SetTsType(interfaceType); + type = MaybeGradualType(interfaceDecl, interfaceType); + var->SetTsType(type); + } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { + interfaceType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + type = MaybeGradualType(interfaceDecl, interfaceType); } else { - interfaceType = var->TsType()->AsETSObjectType(); + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); } + // Save before we mess with savedContext. + bool builtinsInitialized = HasStatus(CheckerStatus::BUILTINS_INITIALIZED); + + auto *enclosingClass = Context().ContainingClass(); + interfaceType->SetEnclosingType(enclosingClass); + CheckerStatus newStatus = CheckerStatus::IN_INTERFACE; + auto savedContext = checker::SavedCheckerContext(this, newStatus, interfaceType); ConstraintCheckScope ctScope(this); if (interfaceDecl->TypeParams() != nullptr) { interfaceType->AddTypeFlag(TypeFlag::GENERIC); @@ -448,11 +527,44 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte // Skip this check if the builtins are not initialized. // They will be initialized in different order, // and it is possible that the FunctionType interface is not yet created. - if (HasStatus(CheckerStatus::BUILTINS_INITIALIZED)) { + if (builtinsInitialized) { CheckInterfaceFunctions(interfaceType); } - return interfaceType; + return type; +} + +void ETSChecker::CheckDynamicInheritanceAndImplement(ETSObjectType *const interfaceOrClassType) +{ + auto getTypeString = [](ETSObjectType *type) { return type->IsInterface() ? "interface" : "class"; }; + auto extendsOrImplements = [](ETSObjectType *type) { return type->IsInterface() ? "extends" : "implements"; }; + auto isFromDynamicDecl = [](ETSObjectType *type) { + auto declNode = type->GetDeclNode(); + if (declNode->IsTSInterfaceDeclaration()) { + return declNode->AsTSInterfaceDeclaration()->Language().IsDynamic(); + } + if (declNode->IsClassDefinition()) { + return declNode->AsClassDefinition()->Language().IsDynamic(); + } + return false; + }; + if (isFromDynamicDecl(interfaceOrClassType)) { + return; + } + for (ETSObjectType *interType : interfaceOrClassType->Interfaces()) { + if (isFromDynamicDecl(interType)) { + LogError(diagnostic::INTERFACE_OR_CLASS_CANNOT_IMPL_OR_EXTEND_DYNAMIC, + {getTypeString(interfaceOrClassType), interfaceOrClassType->Name(), + extendsOrImplements(interfaceOrClassType), getTypeString(interType), interType->Name()}, + interfaceOrClassType->GetDeclNode()->Start()); + } + } + if (interfaceOrClassType->SuperType() != nullptr && isFromDynamicDecl(interfaceOrClassType->SuperType())) { + LogError(diagnostic::INTERFACE_OR_CLASS_CANNOT_IMPL_OR_EXTEND_DYNAMIC, + {getTypeString(interfaceOrClassType), interfaceOrClassType->Name(), "extends", + getTypeString(interfaceOrClassType->SuperType()), interfaceOrClassType->SuperType()->Name()}, + interfaceOrClassType->GetDeclNode()->Start()); + } } Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) @@ -468,21 +580,24 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) } checker::ETSObjectType *classType {}; + checker::Type *type {}; if (var->TsType() == nullptr) { classType = CreateETSObjectTypeOrBuiltin(classDef, checker::ETSObjectFlags::CLASS); + type = MaybeGradualType(classDef, classType); classType->SetVariable(var); - var->SetTsType(classType); + var->SetTsType(type); if (classDef->IsAbstract()) { classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } - } else if (var->TsType()->IsETSObjectType()) { - classType = var->TsType()->AsETSObjectType(); + } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { + classType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + type = MaybeGradualType(classDef, classType); } else { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); } - classDef->SetTsType(classType); + classDef->SetTsType(type); ConstraintCheckScope ctScope(this); if (classDef->TypeParams() != nullptr) { @@ -506,13 +621,14 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) GetInterfaces(classType); } ctScope.TryCheckConstraints(); - return classType; + return type; } ETSObjectType *ETSChecker::BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType) { auto classType = CreateETSObjectType(classDef, checker::ETSObjectFlags::CLASS); classDef->SetTsType(classType); + ES2PANDA_ASSERT(classType != nullptr); classType->SetSuperType(superType); classType->AddObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER); @@ -538,53 +654,63 @@ static void ResolveDeclaredFieldsOfObject(ETSChecker *checker, const ETSObjectTy } } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectType *type, varbinder::ClassScope *scope) { for (auto &[_, it] : scope->InstanceMethodScope()->Bindings()) { (void)_; - auto *method = it->Declaration()->Node()->AsMethodDefinition(); - auto *function = method->Function(); - if (function->IsProxy()) { - continue; - } + if (it->Declaration()->Node()->IsMethodDefinition()) { + auto *method = it->Declaration()->Node()->AsMethodDefinition(); + auto *function = method->Function(); + ES2PANDA_ASSERT(function != nullptr); + if (function->IsProxy()) { + continue; + } - it->AddFlag(checker->GetAccessFlagFromNode(method)); - auto *funcType = checker->BuildMethodSignature(method); - if (!funcType->IsTypeError()) { - funcType->SetVariable(it); + it->AddFlag(checker->GetAccessFlagFromNode(method)); + auto *funcType = checker->BuildMethodSignature(method); + if (!funcType->IsTypeError()) { + funcType->SetVariable(it); + } + it->SetTsType(funcType); + method->SetTsType(funcType); + type->AddProperty(it->AsLocalVariable()); + } else if (it->Declaration()->Node()->IsOverloadDeclaration()) { + type->AddProperty(it->AsLocalVariable()); + } else { + ES2PANDA_UNREACHABLE(); } - it->SetTsType(funcType); - method->SetTsType(funcType); - type->AddProperty(it->AsLocalVariable()); } for (auto &[_, it] : scope->StaticMethodScope()->Bindings()) { (void)_; - if (!it->Declaration()->Node()->IsMethodDefinition()) { - continue; - } - - auto *method = it->Declaration()->Node()->AsMethodDefinition(); - auto *function = method->Function(); + if (it->Declaration()->Node()->IsMethodDefinition()) { + auto *method = it->Declaration()->Node()->AsMethodDefinition(); + auto *function = method->Function(); + ES2PANDA_ASSERT(function != nullptr); + if (function->IsProxy()) { + continue; + } - if (function->IsProxy()) { - continue; - } + it->AddFlag(checker->GetAccessFlagFromNode(method)); + auto *funcType = checker->BuildMethodSignature(method); + if (!funcType->IsTypeError()) { + funcType->SetVariable(it); + } + it->SetTsType(funcType); + method->SetTsType(funcType); - it->AddFlag(checker->GetAccessFlagFromNode(method)); - auto *funcType = checker->BuildMethodSignature(method); - if (!funcType->IsTypeError()) { - funcType->SetVariable(it); - } - it->SetTsType(funcType); - method->SetTsType(funcType); + if (method->IsConstructor() && funcType->IsETSFunctionType()) { + type->AddConstructSignature(funcType->AsETSFunctionType()->CallSignatures()); + continue; + } - if (method->IsConstructor() && funcType->IsETSFunctionType()) { - type->AddConstructSignature(funcType->AsETSFunctionType()->CallSignatures()); + type->AddProperty(it->AsLocalVariable()); + } else if (it->Declaration()->Node()->IsOverloadDeclaration()) { + type->AddProperty(it->AsLocalVariable()); + } else { continue; } - - type->AddProperty(it->AsLocalVariable()); } } @@ -610,6 +736,10 @@ static void ResolveDeclaredDeclsOfObject(ETSChecker *checker, const ETSObjectTyp void ETSChecker::ResolveDeclaredMembersOfObject(const Type *type) { + if (type->IsGradualType()) { + return ResolveDeclaredMembersOfObject(type->AsGradualType()->GetBaseType()); + } + if (!type->IsETSObjectType() || type->AsETSObjectType()->IsPropertiesInstantiated()) { return; } @@ -617,7 +747,9 @@ void ETSChecker::ResolveDeclaredMembersOfObject(const Type *type) auto *objectType = type->AsETSObjectType(); auto *declNode = objectType->GetDeclNode(); - if (declNode == nullptr || !(declNode->IsClassDefinition() || declNode->IsTSInterfaceDeclaration())) { + // Note: the DeclNode of ETSStringLiteralType is totally the same as its super type: `ETSObjectType-String`. + if (objectType->IsETSStringLiteralType() || declNode == nullptr || + !(declNode->IsClassDefinition() || declNode->IsTSInterfaceDeclaration())) { return; } @@ -688,6 +820,10 @@ std::vector ETSChecker::CollectAbstractSignaturesFromObject(const E { std::vector abstracts; for (const auto &prop : objType->Methods()) { + if (prop->Declaration()->Node()->IsOverloadDeclaration()) { + continue; + } + GetTypeOfVariable(prop); if (!prop->TsType()->IsETSFunctionType()) { @@ -713,15 +849,17 @@ 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 cachedComputedAbstracts = GetCachedComputedAbstracts(); + ES2PANDA_ASSERT(cachedComputedAbstracts != nullptr); + auto cached = cachedComputedAbstracts->find(interfaceType); + if (cached != cachedComputedAbstracts->end()) { return; } @@ -729,13 +867,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 = cachedComputedAbstracts->find(interface); + ES2PANDA_ASSERT(found != cachedComputedAbstracts->end()); if (!abstractInheritanceTarget.insert(found->first).second) { continue; @@ -748,18 +886,18 @@ void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) } } - cachedComputedAbstracts_.insert({interfaceType, {merged, abstractInheritanceTarget}}); + cachedComputedAbstracts->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); @@ -770,8 +908,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; @@ -784,7 +922,7 @@ ArenaVector &ETSChecker::GetAbstractsForClass(ETSObjectType * } } - return cachedComputedAbstracts_.insert({classType, {merged, abstractInheritanceTarget}}).first->second.first; + return GetCachedComputedAbstracts()->insert({classType, {merged, abstractInheritanceTarget}}).first->second.first; } [[maybe_unused]] static bool DoObjectImplementInterface(const ETSObjectType *interfaceType, const ETSObjectType *target, @@ -818,7 +956,7 @@ void ETSChecker::GetInterfacesOfClass(ETSObjectType *type, ArenaVectorFunction()->IsStatic() == sig->Function()->IsStatic()) { + if (AreOverrideCompatible(sigFunc, sig) && sigFunc->Function()->IsStatic() == sig->Function()->IsStatic()) { SavedTypeRelationFlagsContext const savedFlags(Relation(), Relation()->GetTypeRelationFlags() | TypeRelationFlag::IGNORE_TYPE_PARAMETERS); if (CheckIfInterfaceCanBeFoundOnDifferentPaths(classType, sigFunc->Owner(), this) && @@ -852,6 +990,7 @@ void ETSChecker::CheckFunctionRedeclarationInInterface(ETSObjectType *classType, if (sig == sigFunc) { return; } + ES2PANDA_ASSERT(sigFunc != nullptr); if (sigFunc->Function()->Id()->Name() == sig->Function()->Id()->Name()) { if (classType->IsSameBasedGeneric(Relation(), sig->Owner())) { return; @@ -871,6 +1010,7 @@ static void CallRedeclarationCheckForCorrectSignature(ir::MethodDefinition *meth ETSObjectType *classType, ETSChecker *checker) { ir::ScriptFunction *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); if (!func->IsAbstract()) { auto *sigFunc = funcType->FindSignature(func); checker->CheckFunctionRedeclarationInInterface(classType, similarSignatures, sigFunc); @@ -879,13 +1019,17 @@ static void CallRedeclarationCheckForCorrectSignature(ir::MethodDefinition *meth 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); GetInterfacesOfClass(classType, interfaces); for (auto *const &interface : interfaces) { for (auto *const &prop : interface->Methods()) { + if (prop->Declaration()->Node()->IsOverloadDeclaration()) { + continue; + } + ir::MethodDefinition *node = prop->Declaration()->Node()->AsMethodDefinition(); if (prop->TsType()->IsTypeError()) { continue; @@ -982,21 +1126,28 @@ void ETSChecker::ValidateNonOverriddenFunction(ETSObjectType *classType, ArenaVe auto superClassType = classType->SuperType(); while (!functionOverridden && superClassType != nullptr) { for (auto *field : superClassType->Fields()) { + if (field->Declaration()->Node()->AsClassProperty()->IsStatic()) { + continue; + } + 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); @@ -1017,6 +1168,10 @@ void ETSChecker::ApplyModifiersAndRemoveImplementedAbstracts(ArenaVectorFields()) { + if (field->Declaration()->Node()->AsClassProperty()->IsStatic()) { + continue; + } + if (field->Name() == (*it)->Name()) { field->Declaration()->Node()->AddModifier(isGetSetExternal.isGetter && isGetSetExternal.isSetter ? ir::ModifierFlags::GETTER_SETTER @@ -1072,6 +1227,9 @@ void ETSChecker::MaybeReportErrorsForOverridingValidation(ArenaVectorCallSignatures().front(); auto containingObjectName = GetContainingObjectNameFromSignature(unimplementedSignature); + if (unimplementedSignature->HasSignatureFlag(SignatureFlags::DEFAULT)) { + return; + } if (unimplementedSignature->HasSignatureFlag(SignatureFlags::GETTER)) { LogError(diagnostic::GETTER_MISSING_IMPL, {classType->Name(), unimplementedSignature->Function()->Id()->Name(), containingObjectName}, pos); @@ -1091,7 +1249,7 @@ void ETSChecker::MaybeReportErrorsForOverridingValidation(ArenaVectorHasObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS)) { + if (GetCachedComputedAbstracts()->find(classType) != GetCachedComputedAbstracts()->end()) { return; } @@ -1123,8 +1281,6 @@ void ETSChecker::ValidateOverriding(ETSObjectType *classType, const lexer::Sourc } while (superIter != nullptr); ValidateAbstractMethodsToBeImplemented(abstractsToBeImplemented, classType, implementedSignatures); MaybeReportErrorsForOverridingValidation(abstractsToBeImplemented, classType, pos, throwError); - - classType->AddObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS); } void ETSChecker::AddImplementedSignature(std::vector *implementedSignatures, @@ -1177,11 +1333,17 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) return; } - auto *classType = classDef->TsType()->AsETSObjectType(); + auto *classType = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); if (classType->SuperType() != nullptr) { classType->SuperType()->GetDeclNode()->Check(this); } + if (classType->GetDeclNode() != classDef) { + ES2PANDA_ASSERT(IsAnyError()); + classDef->SetTsType(GlobalTypeError()); + return; + } + auto newStatus = checker::CheckerStatus::IN_CLASS; if (Context().ContainingClass() != classType) { classType->SetEnclosingType(Context().ContainingClass()); @@ -1214,6 +1376,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); @@ -1228,6 +1391,7 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) return; } + CheckDynamicInheritanceAndImplement(classType); CheckConstructors(classDef, classType); CheckValidInheritance(classType, classDef); CheckConstFields(classType); @@ -1251,20 +1415,20 @@ void ETSChecker::CheckClassElement(ir::ClassDefinition *classDef) void ETSChecker::CheckClassAnnotations(ir::ClassDefinition *classDef) { - CheckAnnotations(classDef->Annotations()); + CheckAnnotations(classDef); if (classDef->TypeParams() != nullptr) { for (auto *param : classDef->TypeParams()->Params()) { - CheckAnnotations(param->Annotations()); + CheckAnnotations(param); } } } void ETSChecker::CheckInterfaceAnnotations(ir::TSInterfaceDeclaration *interfaceDecl) { - CheckAnnotations(interfaceDecl->Annotations()); + CheckAnnotations(interfaceDecl); if (interfaceDecl->TypeParams() != nullptr) { for (auto *param : interfaceDecl->TypeParams()->Params()) { - CheckAnnotations(param->Annotations()); + CheckAnnotations(param); } } } @@ -1336,7 +1500,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()); @@ -1387,7 +1551,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() || @@ -1407,7 +1572,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()) { @@ -1507,46 +1673,64 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { - auto const expressionType = expr->Check(this); + auto const expressionType = expr->Check(this)->MaybeBaseTypeOfGradualType(); if (expressionType->IsTypeError()) { return false; } - Type const *const unboxedExpressionType = MaybeUnboxInRelation(expressionType); - if (expressionType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { - expr->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); + if (!expressionType->IsETSObjectType() || + (!expressionType->AsETSObjectType()->HasObjectFlag(relaxed ? ETSObjectFlags::BUILTIN_ARRAY_NUMERIC + : ETSObjectFlags::BUILTIN_ARRAY_INDEX))) { + LogError(diagnostic::INVALID_INDEX_TYPE, {expressionType->ToString()}, expr->Start()); + return false; } - 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(); - double intpart; - if (std::modf(value, &intpart) != 0.0) { - LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); - return false; - } + if (!relaxed || !expressionType->IsConstantType() || !expr->IsNumberLiteral()) { return true; } - if (indexType == nullptr || !indexType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX)) { - std::stringstream message(""); - expressionType->ToString(message); + ES2PANDA_ASSERT(expr->IsNumberLiteral()); + double value = expr->AsNumberLiteral()->Number().GetDouble(); + + double intPart; + if (std::modf(value, &intPart) != 0.0) { + LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); + return false; + } - LogError(diagnostic::INVALID_INDEX_TYPE, {message.str()}, expr->Start()); + if (intPart < 0.0) { + LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); return false; } return true; } -std::optional ETSChecker::GetTupleElementAccessValue(const Type *const type) +std::optional ETSChecker::GetTupleElementAccessValue(const ir::Expression *expr) { + auto checkLongValBounds = [this](int64_t val, const lexer::SourcePosition &p) -> std::optional { + if (val < 0) { + LogError(diagnostic::TUPLE_INDEX_OOB, {}, p); + return std::nullopt; + } + return static_cast(val); + }; + + if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + if (num.IsInt()) { + return checkLongValBounds(num.GetInt(), expr->Start()); + } + if (num.IsLong()) { + return checkLongValBounds(num.GetLong(), expr->Start()); + } + ES2PANDA_UNREACHABLE(); + } + + // Below code should be unreachable after removing primitives + // #29100: constantExpressionLowering may fail in some cases, and result in the `type` to be ETSObject. + auto type = expr->TsType(); + ES2PANDA_ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); switch (ETSType(type)) { @@ -1567,7 +1751,7 @@ std::optional ETSChecker::GetTupleElementAccessValue(const Type *co return std::nullopt; } default: { - ES2PANDA_UNREACHABLE(); + return std::nullopt; } } } @@ -1575,14 +1759,9 @@ std::optional ETSChecker::GetTupleElementAccessValue(const Type *co 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); + auto const exprType = expr->Property()->Check(this); + auto const *const unboxedExpressionType = MaybeUnboxInRelation(exprType); - if (expressionType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { - expr->Property()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); - } - - const auto *const exprType = expr->Property()->TsType(); ES2PANDA_ASSERT(exprType != nullptr); if (!exprType->HasTypeFlag(TypeFlag::CONSTANT)) { @@ -1595,14 +1774,20 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE return false; } - if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX | TypeFlag::LONG)) { + if (!Relation()->IsSupertypeOf(GlobalIntBuiltinType(), exprType) && + !Relation()->IsSupertypeOf(GlobalLongBuiltinType(), exprType)) { + LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); + return false; + } + + if (expr->Property()->IsAssignmentExpression()) { if (reportError) { - LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); + LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); } return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr->Property()); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { if (reportError) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); @@ -1615,6 +1800,16 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *const expr) { + if (expr->Property() == nullptr || expr->Property()->Variable() == nullptr || + expr->Property()->Variable()->Declaration() == nullptr || + expr->Property()->Variable()->Declaration()->Node() == nullptr || + !(expr->Property()->Variable()->Declaration()->Node()->IsMethodDefinition() || + expr->Property()->Variable()->Declaration()->Node()->IsClassProperty() || + expr->Property()->Variable()->Declaration()->Node()->IsClassStaticBlock() || + expr->Property()->Variable()->Declaration()->Node()->IsOverloadDeclaration())) { + LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Start()); + return false; + } auto *value = expr->Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); if (value == nullptr) { LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); @@ -1632,7 +1827,7 @@ bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); return false; @@ -1641,13 +1836,28 @@ bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple return true; } +namespace { + +bool IsExpressionInClassProperty(ir::Expression const *expr) +{ + for (ir::AstNode const *node = expr; node != nullptr && !node->IsClassDefinition(); node = node->Parent()) { + if (node->IsClassProperty()) { + return true; + } + } + return false; +} + +} // namespace + ETSObjectType *ETSChecker::CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg) { if ((Context().Status() & CheckerStatus::IGNORE_VISIBILITY) != 0U) { 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; @@ -1656,7 +1866,7 @@ ETSObjectType *ETSChecker::CheckThisOrSuperAccess(ir::Expression *node, ETSObjec auto *sig = Context().ContainingSignature(); ES2PANDA_ASSERT(sig->Function()->Body() && sig->Function()->Body()->IsBlockStatement()); - if (!sig->HasSignatureFlag(checker::SignatureFlags::CONSTRUCT)) { + if (!sig->HasSignatureFlag(SignatureFlags::CONSTRUCT)) { LogError(diagnostic::CTOR_CLASS_NOT_FIRST, {msg}, node->Start()); return classType; } @@ -1667,12 +1877,17 @@ ETSObjectType *ETSChecker::CheckThisOrSuperAccess(ir::Expression *node, ETSObjec } } - if (HasStatus(checker::CheckerStatus::IN_STATIC_CONTEXT)) { + if (HasStatus(CheckerStatus::IN_STATIC_CONTEXT)) { LogError(diagnostic::CTOR_REF_IN_STATIC_CTX, {msg}, node->Start()); return classType; } - if (classType->GetDeclNode()->IsClassDefinition() && classType->GetDeclNode()->AsClassDefinition()->IsGlobal()) { + if (node->IsThisExpression() && IsExpressionInClassProperty(node)) { + LogDiagnostic(diagnostic::THIS_IN_FIELD_INITIALIZER, {}, node->Start()); + } + + if (classType == nullptr || + (classType->GetDeclNode()->IsClassDefinition() && classType->GetDeclNode()->AsClassDefinition()->IsGlobal())) { LogError(diagnostic::CTOR_REF_INVALID_CTX_GLOBAL, {msg}, node->Start()); return GlobalBuiltinErrorType(); } @@ -1688,6 +1903,11 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) return; } + // This is a condition set up to handle error scenarios. + if (signature->Function()->Body() == nullptr) { + return; + } + auto *funcBody = signature->Function()->Body()->AsBlockStatement(); TypeStackElement tse(this, signature, {{diagnostic::RECURSIVE_CTOR}}, signature->Function()->Start()); @@ -1715,6 +1935,10 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) ETSObjectType *ETSChecker::CheckExceptionOrErrorType(checker::Type *type, const lexer::SourcePosition pos) { + if (type->IsGradualType()) { + return CheckExceptionOrErrorType(type->AsGradualType()->GetBaseType(), pos); + } + ES2PANDA_ASSERT(type != nullptr); if (!type->IsETSObjectType() || (!Relation()->IsAssignableTo(type, GlobalBuiltinExceptionType()) && !Relation()->IsAssignableTo(type, GlobalBuiltinErrorType()))) { LogError(diagnostic::CATCH_OR_THROW_OF_INVALID_TYPE, @@ -1743,10 +1967,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 = !property->HasFlag(varbinder::VariableFlags::OVERLOAD) + ? funcType->CallSignatures()[0]->OwnerVar() + : property; + 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) { @@ -1764,7 +1995,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()); @@ -1798,7 +2029,11 @@ void ETSChecker::ValidateResolvedProperty(varbinder::LocalVariable **property, c auto *newProp = target->GetProperty(ident->Name(), newFlags); if (newProp == nullptr) { - LogError(diagnostic::PROPERTY_NONEXISTENT, {ident->Name(), target->Name()}, ident->Start()); + if (ident->Name() == SET_PROTOTYPE_OF) { + LogError(diagnostic::ERROR_ARKTS_NO_RUNTIME_PROTOTYPE_INHERITANCE, {}, ident->Start()); + } else { + LogError(diagnostic::PROPERTY_NONEXISTENT, {ident->Name(), target->Name()}, ident->Start()); + } return; } @@ -1817,7 +2052,11 @@ varbinder::Variable *ETSChecker::GetExtensionFuncVarInGlobalFunction(const ir::M { auto propertyName = memberExpr->Property()->AsIdentifier()->Name(); auto *globalFunctionVar = Scope()->FindInGlobal(propertyName, VO::STATIC_METHODS).variable; - if (globalFunctionVar == nullptr || !IsExtensionETSFunctionType(globalFunctionVar->TsType())) { + if (globalFunctionVar == nullptr) { + return nullptr; + } + + if (!IsExtensionETSFunctionType(GetTypeOfVariable(globalFunctionVar))) { return nullptr; } @@ -1870,10 +2109,14 @@ PropertySearchFlags ETSChecker::GetInitialSearchFlags(const ir::MemberExpression switch (memberExpr->Parent()->Type()) { case ir::AstNodeType::CALL_EXPRESSION: { if (memberExpr->Parent()->AsCallExpression()->Callee() == memberExpr) { - return FUNCTIONAL_FLAGS; + return PropertySearchFlags::SEARCH_ALL; } break; } + case ir::AstNodeType::OVERLOAD_DECLARATION: { + return FUNCTIONAL_FLAGS | GETTER_FLAGS; + break; + } case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION: { if (memberExpr->Parent()->AsETSNewClassInstanceExpression()->GetTypeRef() == memberExpr) { return PropertySearchFlags::SEARCH_DECL; @@ -1917,6 +2160,9 @@ static bool ShouldRemoveStaticSearchFlag(const ir::MemberExpression *const membe if (object->IsMemberExpression()) { object = object->AsMemberExpression()->Property(); } + if (object->IsTypeNode()) { + return false; + } if (!object->IsIdentifier() || (object->AsIdentifier()->Variable() == nullptr) || object->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::INITIALIZED)) { return true; @@ -1957,6 +2203,9 @@ const varbinder::Variable *ETSChecker::GetTargetRef(const ir::MemberExpression * if (memberExpr->Object()->IsMemberExpression()) { return memberExpr->Object()->AsMemberExpression()->PropVar(); } + if (memberExpr->Object()->IsTypeNode() && memberExpr->Object()->TsType()->IsETSObjectType()) { + return memberExpr->Object()->TsType()->Variable(); + } return nullptr; } @@ -2052,17 +2301,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()) { @@ -2125,19 +2375,37 @@ static ResolvedKind DecideResolvedKind(Type *typeOfGlobalFunctionVar) return ResolvedKind::EXTENSION_FUNCTION; } -// NOLINTNEXTLINE(readability-function-size) -std::vector ETSChecker::ResolveMemberReference(const ir::MemberExpression *const memberExpr, - const ETSObjectType *const target) +void ETSChecker::CheckAnnotationReference(const ir::MemberExpression *memberExpr, const varbinder::LocalVariable *prop) +{ + // Note: there might be a better way to handle annotations + if (prop != nullptr && prop->Declaration() != nullptr && prop->Declaration()->IsAnnotationDecl() && + memberExpr->Parent()->IsCallExpression()) { + LogError(diagnostic::ANNOTATION_INSTANTIATION, {prop->Declaration()->Name()}, memberExpr->Start()); + } +} + +std::vector ETSChecker::HandlePropertyResolution(varbinder::LocalVariable *const prop, + ir::MemberExpression *const memberExpr, + varbinder::Variable *const globalFunctionVar, + PropertySearchFlags searchFlag) { std::vector resolveRes {}; - 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)); - return resolveRes; + if (prop != nullptr && IsVariableGetterSetter(prop) && + ((searchFlag & PropertySearchFlags::IS_GETTER) != 0 || (searchFlag & PropertySearchFlags::IS_SETTER) != 0)) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return ValidateAccessor(memberExpr, prop, globalFunctionVar, searchFlag); + } + if (prop != nullptr) { + resolveRes.emplace_back(ProgramAllocator()->New(prop, ResolvedKind::PROPERTY)); } + return resolveRes; +} +// NOLINTNEXTLINE(readability-function-size) +std::vector ETSChecker::ResolveMemberReference(const ir::MemberExpression *const memberExpr, + const ETSObjectType *const target) +{ if (target->GetDeclNode() != nullptr && target->GetDeclNode()->IsClassDefinition() && !target->GetDeclNode()->AsClassDefinition()->IsClassDefinitionChecked()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -2145,16 +2413,21 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member } const auto *const targetRef = GetTargetRef(memberExpr); auto searchFlag = GetSearchFlags(memberExpr, targetRef); + if (target->HasObjectFlag(ETSObjectFlags::LAZY_IMPORT_OBJECT)) { + searchFlag |= PropertySearchFlags::SEARCH_INSTANCE; + } auto searchName = target->GetReExportAliasValue(memberExpr->Property()->AsIdentifier()->Name()); auto *prop = target->GetProperty(searchName, searchFlag); + + CheckAnnotationReference(memberExpr, prop); + varbinder::Variable *const globalFunctionVar = ResolveInstanceExtension(memberExpr); if (targetRef != nullptr && targetRef->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)) { // Note: extension function only for instance. ValidateResolvedProperty(&prop, target, memberExpr->Property()->AsIdentifier(), searchFlag); - if (prop != nullptr) { - resolveRes.emplace_back(Allocator()->New(prop, ResolvedKind::PROPERTY)); - } - return resolveRes; + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return HandlePropertyResolution(prop, const_cast(memberExpr), globalFunctionVar, + searchFlag); } if (HasStatus(CheckerStatus::IN_GETTER)) { @@ -2168,23 +2441,35 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member return ValidateAccessor(const_cast(memberExpr), prop, globalFunctionVar, searchFlag); } + std::vector resolveRes {}; if (globalFunctionVar != nullptr) { ResolvedKind resolvedKind = DecideResolvedKind(globalFunctionVar->TsType()); if (IsExtensionAccessorCallUse(this, memberExpr, resolvedKind)) { 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; } +varbinder::LocalVariable *ETSChecker::ResolveOverloadReference(const ir::Identifier *ident, ETSObjectType *objType, + PropertySearchFlags searchFlags) +{ + auto *var = objType->GetProperty(ident->Name(), searchFlags); + if (var == nullptr) { + return nullptr; + } + ValidatePropertyAccess(var, objType, ident->Start()); + return var; +} + void ETSChecker::WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *const memberExpr) { if (!memberExpr->Object()->IsThisExpression() || memberExpr->Property() == nullptr || @@ -2193,18 +2478,17 @@ void ETSChecker::WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *co } auto ident = memberExpr->Property()->AsIdentifier(); auto parent = memberExpr->Parent(); - while (parent != nullptr && - (!parent->IsMethodDefinition() || (!parent->AsMethodDefinition()->Function()->IsGetter() && - !parent->AsMethodDefinition()->Function()->IsSetter()))) { + while (parent != nullptr && (!parent->IsMethodDefinition() || parent->AsMethodDefinition()->Function() == nullptr || + (!parent->AsMethodDefinition()->Function()->IsGetter() && + !parent->AsMethodDefinition()->Function()->IsSetter()))) { parent = parent->Parent(); } - if (parent != nullptr && ident->Name() == parent->AsMethodDefinition()->Function()->Id()->Name()) { + if (parent != nullptr && parent->AsMethodDefinition()->Function() != nullptr && + ident->Name() == parent->AsMethodDefinition()->Function()->Id()->Name()) { if (parent->AsMethodDefinition()->Function()->IsGetter()) { - 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()); } } } @@ -2218,6 +2502,12 @@ void ETSChecker::CheckValidInheritance(ETSObjectType *classType, ir::ClassDefini const auto &allProps = classType->GetAllProperties(); for (auto *it : allProps) { + auto *node = it->Declaration()->Node(); + if (node->IsClassProperty() && node->AsClassProperty()->TsType() != nullptr && + node->AsClassProperty()->TsType()->IsTypeError()) { + continue; + } + const auto searchFlag = PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE | PropertySearchFlags::SEARCH_IN_INTERFACES | PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; @@ -2267,6 +2557,8 @@ void ETSChecker::CheckProperties(ETSObjectType *classType, ir::ClassDefinition * if (CheckGetterSetterDecl(it, found)) { return; } + } else if (CheckOverloadDecl(it, found)) { + return; } else if (CheckFunctionDecl(it, found)) { return; } @@ -2285,6 +2577,8 @@ void ETSChecker::CheckProperties(ETSObjectType *classType, ir::ClassDefinition * targetType = "namespace"; } else if (it->HasFlag(varbinder::VariableFlags::ENUM_LITERAL)) { targetType = "enum"; + } else if (it->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + targetType = "overload"; } else { ES2PANDA_UNREACHABLE(); } @@ -2353,10 +2647,16 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) 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; } @@ -2403,10 +2703,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()); @@ -2418,42 +2717,81 @@ void ETSChecker::AddElementsToModuleObject(ETSObjectType *moduleObj, const util: } } +static Type *GetApparentTypeUtilityTypes(checker::ETSChecker *checker, Type *type) +{ + if (type->IsETSReadonlyType()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return checker->GetApparentType(type->AsETSReadonlyType()->GetUnderlying()->GetConstraintType()); + } + if (type->IsETSAwaitedType()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return checker->GetApparentType(type->AsETSAwaitedType()->GetUnderlying()->GetConstraintType()); + } + if (type->IsETSPartialTypeParameter()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return checker->CreatePartialType( + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + checker->GetApparentType(type->AsETSPartialTypeParameter()->GetUnderlying()->GetConstraintType())); + } + if (type->IsETSNonNullishType()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return checker->GetApparentType(type->AsETSNonNullishType()->GetUnderlying()->GetConstraintType()); + } + return type; +} + // 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}); - return res; + return apparentTypes.insert({res, res}).first->second; }; + ES2PANDA_ASSERT(type != nullptr); + if (type->IsGradualType()) { + return cached(type->AsGradualType()->GetBaseType()); + } + if (type->IsETSTypeParameter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return cached(GetApparentType(type->AsETSTypeParameter()->GetConstraintType())); } + + if (type->IsETSTypeAliasType()) { + // For the recursive type aliases its target type is not ready at the moment of union type creation + // (and assemblyLUB type constructing). + if (auto *targetType = type->AsETSTypeAliasType()->GetTargetType(); targetType != nullptr) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return cached(GetApparentType(targetType)); + } + return type; + } + if (type->IsETSNonNullishType()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return cached( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) GetNonNullishType(GetApparentType(type->AsETSNonNullishType()->GetUnderlying()->GetConstraintType()))); } - if (type->IsETSPartialTypeParameter()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return cached(CreatePartialType( - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - GetApparentType(type->AsETSPartialTypeParameter()->GetUnderlying()->GetConstraintType()))); - } 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)); @@ -2461,26 +2799,14 @@ Type *ETSChecker::GetApparentType(Type *type) } return cached(differ ? CreateETSUnionType(std::move(newConstituent)) : type); } - return cached(type); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return cached(GetApparentTypeUtilityTypes(this, type)); } Type const *ETSChecker::GetApparentType(Type const *type) const { - if (auto it = apparentTypes_.find(type); LIKELY(it != apparentTypes_.end())) { - return it->second; - } - // Relaxed for some types - if (type->IsETSTypeParameter()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return GetApparentType(type->AsETSTypeParameter()->GetConstraintType()); - } - if (type->IsETSArrayType()) { - return type; - } - if (type->IsETSUnionType() || type->IsETSNonNullishType() || type->IsETSPartialTypeParameter()) { - ASSERT_PRINT(false, std::string("Type ") + type->ToString() + " was not found in apparent_types_"); - } - return type; + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return const_cast(const_cast(this)->GetApparentType(const_cast(type))); } ETSObjectType *ETSChecker::GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target) diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index a077b6024fdc9b925cf610346a53633ee73ebfdb..20ea468dcedfeb49f2913116aa694bc23e54b44a 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -14,8 +14,10 @@ */ #include "checker/checker.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/checkerContext.h" +#include "checker/ets/wideningConverter.h" #include "checker/types/globalTypesHolder.h" +#include "checker/types/gradualType.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsPartialTypeParameter.h" #include "ir/base/catchClause.h" @@ -47,6 +49,7 @@ #include "generated/diagnostic.h" namespace ark::es2panda::checker { + void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) { auto const testType = expr->Check(this); @@ -54,20 +57,16 @@ void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) expr->SetTsType(conditionType); - if (conditionType == nullptr || (!conditionType->IsTypeError() && !conditionType->IsConditionalExprType())) { - LogError(diagnostic::NOT_COND_TYPE, {}, expr->Start()); + if (conditionType == nullptr) { return; } + expr->SetTsType(MaybeBoxType(conditionType)); if (conditionType->IsETSVoidType()) { LogError(diagnostic::VOID_IN_LOGIC, {}, expr->Start()); return; } - if (conditionType->IsETSPrimitiveType()) { - FlagExpressionWithUnboxing(testType, conditionType, expr); - } - // For T_S compatibility if (conditionType->IsETSEnumType()) { expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); @@ -76,7 +75,11 @@ void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) bool ETSChecker::CheckNonNullish(ir::Expression const *expr) { - if (!expr->TsType()->PossiblyETSNullish()) { + if (!expr->TsType()->PossiblyETSNullish() || expr->TsType()->IsETSRelaxedAnyType()) { + return true; + } + + if (expr->TsType()->IsETSPartialTypeParameter()) { return true; } @@ -90,11 +93,18 @@ bool ETSChecker::CheckNonNullish(ir::Expression const *expr) Type *ETSChecker::GetNonNullishType(Type *type) { + if (type->IsGradualType()) { + return CreateGradualType(GetNonNullishType(type->AsGradualType()->GetBaseType()), + type->AsGradualType()->Language()); + } if (type->DefinitelyNotETSNullish()) { return type; } + if (type->IsETSAnyType()) { + return type; + } if (type->IsETSTypeParameter()) { - return Allocator()->New(type->AsETSTypeParameter()); + return ProgramAllocator()->New(type->AsETSTypeParameter()); } if (type->IsETSPartialTypeParameter()) { return type->AsETSPartialTypeParameter()->GetUnderlying(); @@ -103,7 +113,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; @@ -115,7 +125,11 @@ Type *ETSChecker::GetNonNullishType(Type *type) Type *ETSChecker::RemoveNullType(Type *const type) { - if (type->DefinitelyNotETSNullish() || type->IsETSUndefinedType()) { + if (type->IsETSAnyType() || type->DefinitelyNotETSNullish() || type->IsETSUndefinedType()) { + return type; + } + + if (type->IsETSPartialTypeParameter()) { return type; } @@ -129,7 +143,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()) { @@ -143,7 +157,7 @@ Type *ETSChecker::RemoveNullType(Type *const type) Type *ETSChecker::RemoveUndefinedType(Type *const type) { - if (type->DefinitelyNotETSNullish() || type->IsETSNullType()) { + if (type->IsETSAnyType() || type->DefinitelyNotETSNullish() || type->IsETSNullType()) { return type; } @@ -152,12 +166,16 @@ Type *ETSChecker::RemoveUndefinedType(Type *const type) return type; } + if (type->IsETSPartialTypeParameter()) { + return type; + } + if (type->IsETSUndefinedType()) { return GetGlobalTypesHolder()->GlobalETSNeverType(); } ES2PANDA_ASSERT(type->IsETSUnionType()); - ArenaVector copiedTypes(Allocator()->Adapter()); + ArenaVector copiedTypes(ProgramAllocator()->Adapter()); for (auto *constituentType : type->AsETSUnionType()->ConstituentTypes()) { if (!constituentType->IsETSUndefinedType()) { @@ -175,9 +193,18 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) return {GetGlobalTypesHolder()->GlobalETSNeverType(), type}; } + if (type->IsETSAnyType()) { + return {type, type}; + } + + if (type->IsETSPartialTypeParameter()) { + return {GetGlobalTypesHolder()->GlobalETSNeverType(), + ProgramAllocator()->New(type->AsETSPartialTypeParameter()->GetUnderlying())}; + } + if (type->IsETSTypeParameter()) { - return {GetGlobalTypesHolder()->GlobalETSNullishType(), - Allocator()->New(type->AsETSTypeParameter())}; + return {GetGlobalTypesHolder()->GlobalETSUnionUndefinedNull(), + ProgramAllocator()->New(type->AsETSTypeParameter())}; } if (type->IsETSUndefinedType() || type->IsETSNullType()) { @@ -185,16 +212,18 @@ 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()) { + for (auto *ctype : type->AsETSUnionType()->ConstituentTypes()) { + auto constituentType = ctype->MaybeBaseTypeOfGradualType(); 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())); } } @@ -209,6 +238,9 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) template static bool MatchConstituentOrConstraint(const Type *type, Pred const &pred, Trv const &trv) { + if (type->IsGradualType()) { + return MatchConstituentOrConstraint(type->AsGradualType()->GetBaseType(), pred, trv); + } auto const traverse = [&pred, &trv](const Type *ttype) { return MatchConstituentOrConstraint(ttype, pred, trv); }; @@ -249,21 +281,45 @@ static bool MatchConstituentOrConstraint(const Type *type, Pred const &pred) bool Type::PossiblyETSNull() const { return MatchConstituentOrConstraint( - this, [](const Type *t) { return t->IsETSNullType(); }, + this, [](const Type *t) { return t->IsETSAnyType() || t->IsETSNullType(); }, [](const Type *t) { return !t->IsETSNonNullishType(); }); } bool Type::PossiblyETSUndefined() const { return MatchConstituentOrConstraint( - this, [](const Type *t) { return t->IsETSUndefinedType(); }, + this, [](const Type *t) { return t->IsETSAnyType() || t->IsETSUndefinedType(); }, [](const Type *t) { return !t->IsETSNonNullishType(); }); } +static bool ObjectPossiblyInForeignDomain(ETSObjectType const *type) +{ + if (type->IsGlobalETSObjectType()) { + return true; + } + auto dnode = type->GetDeclNode(); + if (dnode == nullptr) { + return false; + } + auto lang = dnode->IsClassDefinition() ? dnode->AsClassDefinition()->Language() + : dnode->AsTSInterfaceDeclaration()->Language(); + return lang != Language::Id::ETS; +} + +bool Type::PossiblyInForeignDomain() const +{ + return MatchConstituentOrConstraint( + this, + [](const Type *t) { + return t->IsETSAnyType() || (t->IsETSObjectType() && ObjectPossiblyInForeignDomain(t->AsETSObjectType())); + }, + []([[maybe_unused]] const Type *t) { return true; }); +} + bool Type::PossiblyETSNullish() const { return MatchConstituentOrConstraint( - this, [](const Type *t) { return t->IsETSNullType() || t->IsETSUndefinedType(); }, + this, [](const Type *t) { return t->IsETSAnyType() || t->IsETSNullType() || t->IsETSUndefinedType(); }, [](const Type *t) { return !t->IsETSNonNullishType(); }); } @@ -285,28 +341,31 @@ bool Type::DefinitelyNotETSNullish() const bool Type::PossiblyETSString() const { return MatchConstituentOrConstraint(this, [](const Type *t) { - return t->IsETSStringType() || (t->IsETSObjectType() && t->AsETSObjectType()->IsGlobalETSObjectType()); + return t->IsETSAnyType() || t->IsETSStringType() || + (t->IsETSObjectType() && t->AsETSObjectType()->IsGlobalETSObjectType()); }); } static bool IsValueTypedObjectType(ETSObjectType const *t) { - return t->IsGlobalETSObjectType() || t->HasObjectFlag(ETSObjectFlags::VALUE_TYPED) || - t->HasObjectFlag(ETSObjectFlags::ENUM_OBJECT); + 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->IsETSAnyType() || t->IsETSFunctionType() || + (t->IsETSObjectType() && IsValueTypedObjectType(t->AsETSObjectType())); + }); } bool Type::IsETSArrowType() const @@ -320,13 +379,19 @@ bool Type::IsETSMethodType() const return HasTypeFlag(TypeFlag::ETS_METHOD); } +bool Type::IsETSRelaxedAnyType() const +{ + return IsETSAnyType() && AsETSAnyType()->IsRelaxed(); +} + [[maybe_unused]] static bool IsSaneETSReferenceType(Type const *type) { static constexpr TypeFlag ETS_SANE_REFERENCE_TYPE = 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::ETS_REQUIRED_TYPE_PARAMETER | TypeFlag::ETS_ANY | TypeFlag::ETS_NEVER | TypeFlag::ETS_UNION | + TypeFlag::ETS_ARRAY | TypeFlag::FUNCTION | TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | + TypeFlag::ETS_ENUM | TypeFlag::ETS_READONLY | TypeFlag::GRADUAL_TYPE | TypeFlag::ETS_AWAITED; // Issues if (type->IsETSVoidType()) { // NOTE(vpukhov): #19701 void refactoring @@ -335,9 +400,6 @@ bool Type::IsETSMethodType() const if (type->IsETSTypeAliasType()) { // NOTE(vpukhov): #20561 return true; } - if (type->IsNeverType()) { // NOTE(vpukhov): #20562 We use ets/never and ts/never simultaneously - return true; - } return type->HasTypeFlag(ETS_SANE_REFERENCE_TYPE); } @@ -350,11 +412,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(); @@ -378,6 +435,7 @@ bool ETSChecker::IsConstantExpression(ir::Expression *expr, Type *type) Type *ETSChecker::GetNonConstantType(Type *type) { + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSStringType()) { return GlobalBuiltinETSStringType(); } @@ -387,10 +445,13 @@ Type *ETSChecker::GetNonConstantType(Type *type) } if (type->IsETSUnionType()) { - return CreateETSUnionType(ETSUnionType::GetNonConstantTypes(this, type->AsETSUnionType()->ConstituentTypes())); + return CreateETSUnionType(type->AsETSUnionType()->GetNonConstantTypes(this)); } if (!type->IsETSPrimitiveType()) { + if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { + type->RemoveTypeFlag(TypeFlag::CONSTANT); + } return type; } @@ -432,42 +493,80 @@ Type *ETSChecker::GetTypeOfSetterGetter(varbinder::Variable *const var) { auto *propType = var->TsType()->AsETSFunctionType(); if (propType->HasTypeFlag(checker::TypeFlag::GETTER)) { - return propType->FindGetter()->ReturnType(); + auto *getter = propType->FindGetter(); + ES2PANDA_ASSERT(getter != nullptr); + return getter->ReturnType(); + } + + if (propType->FindSetter()->Params().empty()) { + var->SetTsType(GlobalTypeError()); + return GlobalTypeError(); } return propType->FindSetter()->Params()[0]->TsType(); } -void ETSChecker::IterateInVariableContext(varbinder::Variable *const var) +Type *ETSChecker::CreateSyntheticTypeFromOverload(varbinder::Variable *const var) +{ + auto *overloadDeclaration = var->Declaration()->Node()->AsOverloadDeclaration(); + std::vector signatures; + ETSFunctionType *syntheticFunctionType = + CreateETSMethodType(overloadDeclaration->Id()->Name(), {{}, Allocator()->Adapter()}); + + for (auto *overloadFunction : overloadDeclaration->OverloadedList()) { + Type *functionType = overloadFunction->Check(this); + if (functionType->IsTypeError()) { + overloadDeclaration->SetTsType(GetGlobalTypesHolder()->GlobalTypeError()); + return GetGlobalTypesHolder()->GlobalTypeError(); + } + ES2PANDA_ASSERT(functionType->IsETSFunctionType()); + auto *signature = functionType->AsETSFunctionType()->CallSignatures().front(); + if (std::find(signatures.begin(), signatures.end(), signature) != signatures.end()) { + continue; + } + signatures.emplace_back(signature); + } + + for (auto &s : signatures) { + syntheticFunctionType->AddCallSignature(s); + } + + syntheticFunctionType->SetVariable(var); + var->SetTsType(syntheticFunctionType); + overloadDeclaration->SetTsType(syntheticFunctionType); + return syntheticFunctionType; +} + +SavedCheckerContext ETSChecker::CreateSavedCheckerContext(varbinder::Variable *const var) { // Before computing the given variables type, we have to make a new checker context frame so that the checking is // done in the proper context, and have to enter the scope where the given variable is declared, so reference // resolution works properly - auto *iter = var->Declaration()->Node()->Parent(); - while (iter != nullptr) { + auto constexpr STATUS = CheckerStatus::NO_OPTS; + for (auto *iter = var->Declaration()->Node()->Parent(); iter != nullptr; iter = iter->Parent()) { if (iter->IsMethodDefinition()) { auto *methodDef = iter->AsMethodDefinition(); ES2PANDA_ASSERT(methodDef->TsType()); - Context().SetContainingSignature(methodDef->Function()->Signature()); - } else if (iter->IsClassDefinition()) { + auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); + return SavedCheckerContext(this, STATUS, nullptr, func->Signature()); + } + if (iter->IsClassDefinition()) { auto *classDef = iter->AsClassDefinition(); Type *containingClass {}; - if (classDef->TsType() == nullptr) { - containingClass = BuildBasicClassProperties(classDef); - ResolveDeclaredMembersOfObject(containingClass->AsETSObjectType()); + containingClass = BuildBasicClassProperties(classDef)->MaybeBaseTypeOfGradualType(); + ResolveDeclaredMembersOfObject(containingClass); } else { - containingClass = classDef->TsType()->AsETSObjectType(); + containingClass = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); } - ES2PANDA_ASSERT(classDef->TsType()); if (!containingClass->IsTypeError()) { - Context().SetContainingClass(containingClass->AsETSObjectType()); + return SavedCheckerContext(this, STATUS, containingClass->AsETSObjectType()); } } - - iter = iter->Parent(); } + return SavedCheckerContext(this, STATUS); } static Type *GetTypeFromVarLikeVariableDeclaration(ETSChecker *checker, varbinder::Variable *const var) @@ -490,7 +589,7 @@ static Type *GetTypeFromVarLikeVariableDeclaration(ETSChecker *checker, varbinde var->SetTsType(checker->GlobalTypeError()); return checker->GlobalTypeError(); } - return declNode->Check(checker); + return var->SetTsType(declNode->Check(checker)); } Type *ETSChecker::GetTypeFromVariableDeclaration(varbinder::Variable *const var) @@ -556,17 +655,8 @@ Type *ETSChecker::GetTypeOfVariable(varbinder::Variable *const var) return var->TsType(); } - // NOTE: kbaladurin. forbid usage of imported entities as types without declarations - if (VarBinder()->AsETSBinder()->IsDynamicModuleVariable(var)) { - auto *importData = VarBinder()->AsETSBinder()->DynamicImportDataForVar(var); - if (importData->import->IsPureDynamic()) { - return GlobalBuiltinDynamicType(importData->import->Language()); - } - } - - checker::SavedCheckerContext savedContext(this, CheckerStatus::NO_OPTS); + checker::SavedCheckerContext savedContext = CreateSavedCheckerContext(var); checker::ScopeContext scopeCtx(this, var->GetScope()); - IterateInVariableContext(var); return GetTypeFromVariableDeclaration(var); } @@ -611,7 +701,9 @@ Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable * switch (auto node = prop->Declaration()->Node(); node->Type()) { case ir::AstNodeType::CLASS_PROPERTY: { - auto baseProp = node->AsClassProperty()->Id()->Variable(); + auto *id = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto baseProp = id->Variable(); if (baseProp == prop) { return nullptr; } @@ -621,6 +713,7 @@ Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable * case ir::AstNodeType::METHOD_DEFINITION: case ir::AstNodeType::CLASS_DEFINITION: return GetTypeOfVariable(prop); + case ir::AstNodeType::OVERLOAD_DECLARATION: case ir::AstNodeType::TS_ENUM_DECLARATION: return nullptr; default: @@ -631,6 +724,7 @@ Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable * // Determine if substituted method cast requires cast from erased type Type *ETSChecker::GuaranteedTypeForUncheckedCallReturn(Signature *sig) { + ES2PANDA_ASSERT(sig != nullptr); ES2PANDA_ASSERT(sig->HasFunction()); if (sig->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { return sig->ReturnType(); @@ -649,9 +743,9 @@ Type *ETSChecker::ResolveUnionUncheckedType(ArenaVector &&appar return nullptr; } auto *unionType = CreateETSUnionType(std::move(apparentTypes)); + ES2PANDA_ASSERT(unionType != nullptr); if (unionType->IsETSUnionType()) { - checker::Type *typeLUB = unionType->AsETSUnionType()->GetAssemblerLUB(); - return typeLUB; + return unionType->AsETSUnionType(); } // Is case of single apparent type, just return itself return unionType; @@ -660,8 +754,17 @@ Type *ETSChecker::ResolveUnionUncheckedType(ArenaVector &&appar Type *ETSChecker::GuaranteedTypeForUnionFieldAccess(ir::MemberExpression *memberExpression, ETSUnionType *etsUnionType) { const auto &types = etsUnionType->ConstituentTypes(); - ArenaVector apparentTypes {Allocator()->Adapter()}; - const auto &propertyName = memberExpression->Property()->AsIdentifier()->Name(); + ArenaVector apparentTypes {ProgramAllocator()->Adapter()}; + const auto *prop = memberExpression->Property(); + util::StringView propertyName; + if (prop->IsIdentifier()) { + propertyName = prop->AsIdentifier()->Name(); + } else if (prop->IsStringLiteral()) { + propertyName = prop->AsStringLiteral()->Str(); + } else { + return GlobalTypeError(); + } + for (auto *type : types) { auto searchFlags = PropertySearchFlags::SEARCH_FIELD | PropertySearchFlags::SEARCH_METHOD | PropertySearchFlags::SEARCH_IN_BASE; @@ -752,6 +855,7 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(varbinder::Variable *var) typeAliasType = CreateETSTypeAliasType(aliasTypeNode->Id()->Name(), aliasTypeNode); if (aliasTypeNode->TypeParams() != nullptr) { auto [typeParamTypes, ok] = CreateUnconstrainedTypeParameters(aliasTypeNode->TypeParams()); + ES2PANDA_ASSERT(typeAliasType != nullptr); typeAliasType->AsETSTypeAliasType()->SetTypeArguments(std::move(typeParamTypes)); if (ok) { AssignTypeParameterConstraints(aliasTypeNode->TypeParams()); @@ -762,7 +866,6 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(varbinder::Variable *var) aliasTypeNode->Check(this); Type *targetType = aliasTypeNode->TypeAnnotation()->GetType(this); typeAliasType->AsETSTypeAliasType()->SetTargetType(targetType); - typeAliasType->AsETSTypeAliasType()->ApplySubstitution(Relation()); var->SetTsType(targetType); return targetType; @@ -774,8 +877,14 @@ Type *ETSChecker::GetTypeFromInterfaceReference(varbinder::Variable *var) return var->TsType(); } + CheckerStatus status = CheckerStatus::IN_STATIC_CONTEXT; + status &= this->Context().Status(); + this->Context().Status() &= ~CheckerStatus::IN_STATIC_CONTEXT; + auto *interfaceType = BuildBasicInterfaceProperties(var->Declaration()->Node()->AsTSInterfaceDeclaration()); var->SetTsType(interfaceType); + + this->Context().Status() |= status; return interfaceType; } @@ -787,8 +896,13 @@ Type *ETSChecker::GetTypeFromClassReference(varbinder::Variable *var) auto classDef = var->Declaration()->Node()->AsClassDefinition(); + CheckerStatus status = CheckerStatus::IN_STATIC_CONTEXT; + status &= this->Context().Status(); + this->Context().Status() &= ~CheckerStatus::IN_STATIC_CONTEXT; + auto *classType = BuildBasicClassProperties(classDef); var->SetTsType(classType); + this->Context().Status() |= status; return classType; } @@ -891,12 +1005,15 @@ void ETSChecker::CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir: for (auto *prop : annoDecl->Properties()) { auto *field = prop->AsClassProperty(); + ES2PANDA_ASSERT(field->Id() != nullptr); fieldMap[field->Id()->Name()] = field; } for (auto *prop : annoImpl->Properties()) { auto *field = prop->AsClassProperty(); - auto fieldName = field->Id()->Name(); + auto *id = field->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto fieldName = id->Name(); auto fieldDeclIter = fieldMap.find(fieldName); if (fieldDeclIter == fieldMap.end()) { LogError(diagnostic::AMBIENT_ANNOT_IMPL_OF_UNDEFINED_FIELD, {fieldName, annoDecl->GetBaseName()->Name()}, @@ -933,22 +1050,22 @@ void ETSChecker::CheckFunctionSignatureAnnotations(const ArenaVectorIsETSParameterExpression()) { - CheckAnnotations(param->AsETSParameterExpression()->Annotations()); + CheckAnnotations(param->AsETSParameterExpression()); if (param->AsETSParameterExpression()->TypeAnnotation() != nullptr) { - param->AsETSParameterExpression()->TypeAnnotation()->Check(this); + CheckAnnotations(param->AsETSParameterExpression()->TypeAnnotation()); } } } if (typeParams != nullptr) { for (auto *typeParam : typeParams->Params()) { - CheckAnnotations(typeParam->Annotations()); + CheckAnnotations(typeParam); } } if (returnTypeAnnotation != nullptr) { ValidateThisUsage(returnTypeAnnotation); - CheckAnnotations(returnTypeAnnotation->Annotations()); + CheckAnnotations(returnTypeAnnotation); } } @@ -961,6 +1078,12 @@ bool ETSChecker::CheckAndLogInvalidThisUsage(const ir::TypeNode *type, const dia 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()) { @@ -983,21 +1106,23 @@ void ETSChecker::ValidateThisUsage(const ir::TypeNode *returnTypeAnnotation) } return; } - if (returnTypeAnnotation->IsTSArrayType()) { - auto elementType = returnTypeAnnotation->AsTSArrayType()->ElementType(); - if (CheckAndLogInvalidThisUsage(elementType, diagnostic::NOT_ALLOWED_THIS_IN_ARRAY_TYPE)) { - return; + if (returnTypeAnnotation->IsETSTypeReference() && + IsFixedArray(returnTypeAnnotation->AsETSTypeReference()->Part())) { + if (returnTypeAnnotation->AsETSTypeReference()->Part()->TypeParams() != nullptr) { + auto elementType = returnTypeAnnotation->AsETSTypeReference()->Part()->TypeParams()->Params()[0]; + if (CheckAndLogInvalidThisUsage(elementType, diagnostic::NOT_ALLOWED_THIS_IN_ARRAY_TYPE)) { + return; + } + ValidateThisUsage(elementType); } - ValidateThisUsage(elementType); return; } } void ETSChecker::CheckAnnotations(const ArenaVector &annotations) { - if (annotations.empty()) { - return; - } + ES2PANDA_ASSERT(!annotations.empty()); + std::unordered_set seenAnnotations; for (const auto &anno : annotations) { anno->Check(this); @@ -1045,21 +1170,28 @@ 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) { - if (anno->GetBaseName()->Variable() == nullptr) { + if (anno->GetBaseName()->Variable() == nullptr || IsTypeError(anno->GetBaseName()->TsType())) { return; } ES2PANDA_ASSERT(anno->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration() != nullptr); @@ -1073,21 +1205,75 @@ void ETSChecker::CheckStandardAnnotation(ir::AnnotationUsage *anno) } } +static auto IsNonArrayLiteral(ir::Expression *init) +{ + if ((init == nullptr) || init->IsLiteral()) { + return true; + } + + if (init->TsType() != nullptr && init->TsType()->IsETSEnumType() && + init->TsType()->AsETSEnumType()->NodeIsEnumLiteral(init)) { + return true; + } + return false; +} + +static auto IsValidAnnotationPropInitializer(ir::Expression *init) +{ + if (IsNonArrayLiteral(init)) { + return true; + } + + if (init->IsArrayExpression()) { + for (auto elem : init->AsArrayExpression()->Elements()) { + if (!IsValidAnnotationPropInitializer(elem)) { + return false; + } + } + return true; + } + return false; +} + +static bool ValidateAnnotationPropertyType(checker::Type *type, ETSChecker *checker) +{ + if (type == nullptr || type->IsTypeError()) { + ES2PANDA_ASSERT(checker->IsAnyError()); + return false; + } + + if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { + return ValidateAnnotationPropertyType(checker->GetElementTypeOfArray(type), checker); + } + auto relation = checker->Relation(); + return type->IsETSEnumType() || type->IsETSStringType() || + (type->IsETSObjectType() && (relation->IsSupertypeOf(checker->GlobalETSBooleanBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalByteBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalShortBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalIntBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalLongBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalFloatBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), type))); +} + void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) { // typeAnnotation check - if (!ValidateAnnotationPropertyType(property->TsType())) { + if (!ValidateAnnotationPropertyType(property->TsType(), this)) { LogError(diagnostic::ANNOT_FIELD_INVALID_TYPE, {}, property->Start()); } - // The type of the Initializer has been check in the parser, - // except for the enumeration type, because it is a member expression, - // so here is an additional check to the enumeration type. - if (property->Value() != nullptr && - ((property->Value()->IsMemberExpression() && !property->TsType()->IsETSEnumType()) || - property->Value()->IsIdentifier())) { - LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); + if (IsValidAnnotationPropInitializer(property->Value())) { + return; } + + // Avoid outputting the same syntax and type errors. + if (property->Value()->IsBrokenExpression()) { + ES2PANDA_ASSERT(IsAnyError()); + return; + } + + LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); } void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::AnnotationDeclaration *annoDecl) @@ -1096,43 +1282,25 @@ void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::Anno if (annoDecl->Properties().size() > 1) { LogError(diagnostic::ANNOT_MULTIPLE_FIELD, {st->GetBaseName()->Name()}, st->Start()); } - auto singleField = annoDecl->Properties().at(0)->AsClassProperty(); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto clone = singleField->TypeAnnotation()->Clone(Allocator(), param); - param->SetTypeAnnotation(clone); + ScopeContext scopeCtx(this, st->Scope()); param->Check(this); CheckAnnotationPropertyType(param); } -void ETSChecker::ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const -{ - for (const auto &entry : fieldMap) { - if (entry.second->Value() == nullptr) { - checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); - continue; - } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *clone = entry.second->Clone(checker->Allocator(), st); - st->AddProperty(clone); - } -} - void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util::StringView const &baseName, ArenaUnorderedMap &fieldMap) { for (auto *it : st->Properties()) { auto *param = it->AsClassProperty(); - auto result = fieldMap.find(param->Id()->Name()); + auto *id = param->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto result = fieldMap.find(id->Name()); if (result == fieldMap.end()) { - LogError(diagnostic::ANNOT_PROP_UNDEFINED, {param->Id()->Name(), baseName}, param->Start()); + LogError(diagnostic::ANNOT_PROP_UNDEFINED, {id->Name(), baseName}, param->Start()); continue; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto clone = result->second->TypeAnnotation()->Clone(Allocator(), param); - param->SetTypeAnnotation(clone); ScopeContext scopeCtx(this, st->Scope()); param->Check(this); CheckAnnotationPropertyType(param); @@ -1168,7 +1336,7 @@ Type *ETSChecker::MaybeUnboxConditionalInRelation(Type *const objectType) return objectType; } - if ((objectType == nullptr) || !objectType->IsConditionalExprType()) { + if (objectType == nullptr) { return nullptr; } @@ -1204,11 +1372,13 @@ Type *ETSChecker::MaybeBoxInRelation(Type *objectType) Type *ETSChecker::MaybeBoxType(Type *type) const { + ES2PANDA_ASSERT(type != nullptr); return type->IsETSPrimitiveType() ? BoxingConverter::Convert(this, type) : type; } Type *ETSChecker::MaybeUnboxType(Type *type) const { + ES2PANDA_ASSERT(type != nullptr); return type->IsETSUnboxableObject() ? UnboxingConverter::Convert(this, type->AsETSObjectType()) : type; } @@ -1222,85 +1392,15 @@ Type const *ETSChecker::MaybeUnboxType(Type const *type) const return MaybeUnboxType(const_cast(type)); } -ir::BoxingUnboxingFlags ETSChecker::GetBoxingFlag(Type *const boxingType) -{ - auto typeKind = TypeKind(MaybeUnboxInRelation(boxingType)); - switch (typeKind) { - case TypeFlag::ETS_BOOLEAN: - return ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN; - case TypeFlag::BYTE: - return ir::BoxingUnboxingFlags::BOX_TO_BYTE; - case TypeFlag::CHAR: - return ir::BoxingUnboxingFlags::BOX_TO_CHAR; - case TypeFlag::SHORT: - return ir::BoxingUnboxingFlags::BOX_TO_SHORT; - case TypeFlag::INT: - return ir::BoxingUnboxingFlags::BOX_TO_INT; - case TypeFlag::LONG: - return ir::BoxingUnboxingFlags::BOX_TO_LONG; - case TypeFlag::FLOAT: - return ir::BoxingUnboxingFlags::BOX_TO_FLOAT; - case TypeFlag::DOUBLE: - return ir::BoxingUnboxingFlags::BOX_TO_DOUBLE; - default: - ES2PANDA_UNREACHABLE(); - } -} - -ir::BoxingUnboxingFlags ETSChecker::GetUnboxingFlag(Type const *const unboxingType) const -{ - auto typeKind = TypeKind(unboxingType); - switch (typeKind) { - case TypeFlag::ETS_BOOLEAN: - return ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN; - case TypeFlag::BYTE: - return ir::BoxingUnboxingFlags::UNBOX_TO_BYTE; - case TypeFlag::CHAR: - return ir::BoxingUnboxingFlags::UNBOX_TO_CHAR; - case TypeFlag::SHORT: - return ir::BoxingUnboxingFlags::UNBOX_TO_SHORT; - case TypeFlag::INT: - return ir::BoxingUnboxingFlags::UNBOX_TO_INT; - case TypeFlag::LONG: - return ir::BoxingUnboxingFlags::UNBOX_TO_LONG; - case TypeFlag::FLOAT: - return ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT; - case TypeFlag::DOUBLE: - return ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE; - default: - ES2PANDA_UNREACHABLE(); - } -} - -void ETSChecker::MaybeAddBoxingFlagInRelation(TypeRelation *relation, Type *target) -{ - auto boxingResult = MaybeBoxInRelation(target); - if ((boxingResult != nullptr) && !relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOXING_FLAG); - relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxingResult)); - relation->Result(true); - } -} - -void ETSChecker::MaybeAddUnboxingFlagInRelation(TypeRelation *relation, Type *source, Type *self) -{ - auto unboxingResult = UnboxingConverter(this, relation, source, self).Result(); - if ((unboxingResult != nullptr) && relation->IsTrue() && !relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxingResult)); - } -} - void ETSChecker::CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self) { - checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx( - relation, TypeRelationFlag::ONLY_CHECK_WIDENING | - (relation->ApplyNarrowing() ? TypeRelationFlag::NARROWING : TypeRelationFlag::NONE)); + checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(relation, TypeRelationFlag::ONLY_CHECK_WIDENING); // NOTE: vpukhov. handle union type auto unboxedType = MaybeUnboxInRelation(target); if (unboxedType == nullptr) { return; } - NarrowingWideningConverter(this, relation, unboxedType, self); + WideningConverter(this, relation, unboxedType, self); if (!relation->IsTrue()) { relation->Result(relation->IsAssignableTo(self, unboxedType)); } @@ -1314,10 +1414,6 @@ void ETSChecker::CheckUnboxedTypesAssignable(TypeRelation *relation, Type *sourc return; } relation->IsAssignableTo(unboxedSourceType, unboxedTargetType); - if (relation->IsTrue()) { - relation->GetNode()->AddBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxedSourceType)); - } } void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target) @@ -1325,7 +1421,6 @@ void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *so ES2PANDA_ASSERT(relation != nullptr); checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx( relation, (relation->ApplyWidening() ? TypeRelationFlag::WIDENING : TypeRelationFlag::NONE) | - (relation->ApplyNarrowing() ? TypeRelationFlag::NARROWING : TypeRelationFlag::NONE) | (relation->OnlyCheckBoxingUnboxing() ? TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING : TypeRelationFlag::NONE)); @@ -1334,22 +1429,13 @@ void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *so return; } ES2PANDA_ASSERT(target != nullptr); - // Do not box primitive in case of cast to dynamic types - if (target->IsETSDynamicType()) { - return; - } relation->IsAssignableTo(boxedSourceType, target); - if (relation->IsTrue()) { - MaybeAddBoxingFlagInRelation(relation, boxedSourceType); - } else { + if (!relation->IsTrue()) { auto unboxedTargetType = MaybeUnboxInRelation(target); if (unboxedTargetType == nullptr) { return; } - NarrowingWideningConverter(this, relation, unboxedTargetType, source); - if (relation->IsTrue()) { - MaybeAddBoxingFlagInRelation(relation, target); - } + WideningConverter(this, relation, unboxedTargetType, source); } } @@ -1363,28 +1449,6 @@ void ETSChecker::CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *rela if (!relation->IsTrue() && relation->ApplyWidening()) { relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, unboxedSourceType); } - if (!relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->AddBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxedSourceType)); - } -} - -static ir::AstNode *DerefETSTypeReference(ir::AstNode *node) -{ - ES2PANDA_ASSERT(node->IsETSTypeReference()); - do { - auto *name = node->AsETSTypeReference()->Part()->GetIdent(); - - ES2PANDA_ASSERT(name->IsIdentifier()); - auto *var = name->AsIdentifier()->Variable(); - ES2PANDA_ASSERT(var != nullptr); - auto *declNode = var->Declaration()->Node(); - if (!declNode->IsTSTypeAliasDeclaration()) { - return declNode; - } - node = declNode->AsTSTypeAliasDeclaration()->TypeAnnotation(); - } while (node->IsETSTypeReference()); - return node; } // #22952: optional arrow leftovers @@ -1395,20 +1459,21 @@ bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction if (typeAnn == nullptr) { return false; } - if (typeAnn->IsETSTypeReference()) { - typeAnn = DerefETSTypeReference(typeAnn); + if (typeAnn->IsETSTypeReference() && !typeAnn->AsETSTypeReference()->TsType()->IsETSArrayType()) { + typeAnn = util::Helpers::DerefETSTypeReference(typeAnn); + } + if (typeAnn->IsTSTypeParameter()) { + return true; } - 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 if (typeAnn->IsETSUnionType()) { - lambda->Parent()->Check(this); return CheckLambdaAssignableUnion(typeAnn, lambda); } Type *paramType = param->AsETSParameterExpression()->Ident()->TsType(); - if (paramType->IsETSObjectType() && Relation()->IsSupertypeOf(paramType, GlobalBuiltinFunctionType())) { + if (Relation()->IsSupertypeOf(paramType, GlobalBuiltinFunctionType())) { lambda->Parent()->Check(this); return true; } @@ -1423,7 +1488,11 @@ bool ETSChecker::CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunction Type *const subParameterType) { if (typeAnnotation->IsETSTypeReference()) { - typeAnnotation = DerefETSTypeReference(typeAnnotation); + typeAnnotation = util::Helpers::DerefETSTypeReference(typeAnnotation); + } + + if (typeAnnotation->IsTSTypeParameter()) { + return true; } if (!typeAnnotation->IsETSFunctionType()) { @@ -1438,10 +1507,14 @@ bool ETSChecker::CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunction return true; } -bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, +bool ETSChecker::CheckLambdaTypeAnnotation(ir::ETSParameterExpression *param, ir::ArrowFunctionExpression *const arrowFuncExpr, Type *const parameterType, TypeRelationFlag flags) { + ir::AstNode *typeAnnotation = param->Ident()->TypeAnnotation(); + if (typeAnnotation->IsETSTypeReference()) { + typeAnnotation = util::Helpers::DerefETSTypeReference(typeAnnotation); + } auto checkInvocable = [&arrowFuncExpr, ¶meterType, this](TypeRelationFlag functionFlags) { Type *const argumentType = arrowFuncExpr->Check(this); functionFlags |= TypeRelationFlag::NO_THROW; @@ -1453,10 +1526,11 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, // process `single` type as usual. if (!typeAnnotation->IsETSUnionType()) { - auto param = typeAnnotation->Parent()->Parent()->AsETSParameterExpression(); // #22952: infer optional parameter heuristics auto nonNullishParam = param->IsOptional() ? GetNonNullishType(parameterType) : parameterType; + ES2PANDA_ASSERT(nonNullishParam != nullptr); if (!nonNullishParam->IsETSFunctionType()) { + arrowFuncExpr->Check(this); return true; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -1465,19 +1539,18 @@ 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()); } auto *const lambdaReturnTypeAnnotation = lambda->ReturnTypeAnnotation(); - Type *const argumentType = arrowFuncExpr->Check(this); - if (Relation()->IsSupertypeOf(parameterType, argumentType)) { - return true; + if (!parameterType->IsETSUnionType() || parameterType->AsETSUnionType()->ConstituentTypes().size() != + typeAnnotation->AsETSUnionType()->Types().size()) { + Type *const argumentType = arrowFuncExpr->Check(this); + return Relation()->IsSupertypeOf(parameterType, argumentType); } - ES2PANDA_ASSERT(parameterType->AsETSUnionType()->ConstituentTypes().size() == - typeAnnotation->AsETSUnionType()->Types().size()); const auto typeAnnsOfUnion = typeAnnotation->AsETSUnionType()->Types(); const auto typeParamOfUnion = parameterType->AsETSUnionType()->ConstituentTypes(); for (size_t ix = 0; ix < typeAnnsOfUnion.size(); ++ix) { @@ -1502,61 +1575,85 @@ 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(); + // Note: (Issue27688) if lambda is trailing lambda transferred, it must be in recheck. + // its type was cleared before the check, so here we need recheck it. + if (!NeedTypeInference(lambda) && !lambda->IsTrailingLambda()) { + return typeValid; + } - // Note: If the signatures are from lambdas, then they have no `Function`. - auto const *const param = - signature->GetSignatureInfo()->params[index]->Declaration()->Node()->AsETSParameterExpression(); - ir::AstNode *typeAnn = param->Ident()->TypeAnnotation(); - Type *const parameterType = signature->Params()[index]->TsType(); + arrowFuncExpr->SetTsType(nullptr); + auto *const param = + signature->GetSignatureInfo()->params[paramPosition]->Declaration()->Node()->AsETSParameterExpression(); + 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(param, arrowFuncExpr, parameterType, resolutionFlags); + if (!rc) { + if ((resolutionFlags & TypeRelationFlag::NO_THROW) == 0) { Type *const argumentType = arrowFuncExpr->Check(this); - LogError(diagnostic::TYPE_MISMATCH_AT_IDX, {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(), 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; - } } + } + + typeValid &= rc; + + return typeValid; +} + +bool ETSChecker::TrailingLambdaTypeInference(Signature *signature, const ArenaVector &arguments) +{ + if (arguments.empty() || signature->GetSignatureInfo()->params.empty()) { + return false; + } + 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]; - invocable &= rc; + 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 @@ -1601,4 +1698,202 @@ void ETSChecker::CheckExceptionClauseType(const std::vectorLogError(diagnostic::OVERLOAD_SAME_ACCESS_MODIFIERS_STATIC_ASYNC, {}, pos); + return false; + } + + if (((overLoadAliasFlags ^ overloadedMethodFlags) & (ir::ModifierFlags::CONSTRUCTOR)) != 0) { + checker->LogError(diagnostic::OVERLOAD_MUST_BOTH_CONSTRUCT, {}, pos); + return false; + } + + return true; +} + +static bool CheckOverloadedName(ETSChecker *checker, ir::OverloadDeclaration *node, ir::Expression *overloadedName) +{ + if (overloadedName->Variable()->Declaration() == nullptr) { + checker->LogError(diagnostic::OVERLOADED_NAME_MUST_FUNCTION, {}, overloadedName->Start()); + overloadedName->SetTsType(checker->GlobalTypeError()); + return false; + } + + auto *identDeclNode = overloadedName->Variable()->Declaration()->Node(); + if (!identDeclNode->IsMethodDefinition()) { + checker->LogError(diagnostic::OVERLOADED_NAME_MUST_FUNCTION, {}, overloadedName->Start()); + overloadedName->SetTsType(checker->GlobalTypeError()); + return false; + } + // Constructor will lowering to multiple Constructor if have rest parameters or optional parameters. + // Need to modify RestTupleConstructionPhase. + if (!identDeclNode->AsMethodDefinition()->Overloads().empty() && !identDeclNode->IsConstructor()) { + checker->LogError(diagnostic::OVERLOADED_NAME_REFER_TO_OVERLOAD_FUNCTION, {overloadedName->Variable()->Name()}, + overloadedName->Start()); + overloadedName->SetTsType(checker->GlobalTypeError()); + return false; + } + + return CheckAccessModifierForOverloadDeclaration(checker, node->Modifiers(), identDeclNode->Modifiers(), + overloadedName->Start()); +} + +void ETSChecker::CheckFunctionOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const +{ + for (auto *overloadedName : node->OverloadedList()) { + if (overloadedName->IsMemberExpression()) { + overloadedName->Check(checker); + overloadedName->SetVariable(overloadedName->AsMemberExpression()->Property()->Variable()); + } else if (overloadedName->IsIdentifier()) { + ir::Identifier *ident = overloadedName->AsIdentifier(); + + Type *classType = node->Parent()->AsClassDefinition()->TsType(); + ES2PANDA_ASSERT(classType->IsETSObjectType()); + + PropertySearchFlags searchFlags = PropertySearchFlags::SEARCH_METHOD | PropertySearchFlags::SEARCH_IN_BASE | + PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::IS_GETTER | PropertySearchFlags::IGNORE_OVERLOAD; + auto *variable = + checker->ResolveOverloadReference(ident->AsIdentifier(), classType->AsETSObjectType(), searchFlags); + if (variable == nullptr) { + checker->LogError(diagnostic::OVERLOADED_NAME_MUST_FUNCTION, {}, ident->Start()); + ident->SetTsType(checker->GlobalTypeError()); + continue; + } + + ident->SetTsType(variable->TsType()); + ident->SetVariable(variable); + + if (!CheckOverloadedName(checker, node, overloadedName)) { + continue; + } + } else { + overloadedName->SetTsType(checker->GlobalTypeError()); + continue; + } + } +} + +void ETSChecker::CheckClassMethodOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const +{ + PropertySearchFlags searchFlags = + PropertySearchFlags::SEARCH_IN_BASE | PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::IS_GETTER | PropertySearchFlags::IGNORE_OVERLOAD | + (node->IsStatic() ? PropertySearchFlags::SEARCH_STATIC_METHOD : PropertySearchFlags::SEARCH_INSTANCE_METHOD); + + for (auto *overloadedName : node->OverloadedList()) { + if (!overloadedName->IsIdentifier()) { + overloadedName->SetTsType(checker->GlobalTypeError()); + continue; + } + ir::Identifier *ident = overloadedName->AsIdentifier(); + + Type *classType = node->Parent()->AsClassDefinition()->TsType(); + ES2PANDA_ASSERT(classType->IsETSObjectType()); + + auto *variable = + checker->ResolveOverloadReference(ident->AsIdentifier(), classType->AsETSObjectType(), searchFlags); + + if (variable == nullptr && + checker->ResolveOverloadReference(ident->AsIdentifier(), classType->AsETSObjectType(), + searchFlags | PropertySearchFlags::SEARCH_METHOD) != nullptr) { + checker->LogError(diagnostic::OVERLOAD_SAME_ACCESS_MODIFIERS_STATIC_ASYNC, {}, ident->Start()); + continue; + } + if (variable == nullptr) { + checker->LogError(diagnostic::OVERLOADED_NAME_MUST_FUNCTION, {}, ident->Start()); + ident->SetTsType(checker->GlobalTypeError()); + continue; + } + + ident->SetTsType(variable->TsType()); + ident->SetVariable(variable); + + if (!CheckOverloadedName(checker, node, overloadedName)) { + continue; + } + } +} + +void ETSChecker::CheckInterfaceMethodOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const +{ + PropertySearchFlags searchFlags = + PropertySearchFlags::SEARCH_IN_BASE | PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::IS_GETTER | PropertySearchFlags::IGNORE_OVERLOAD | + (node->IsStatic() ? PropertySearchFlags::SEARCH_STATIC_METHOD : PropertySearchFlags::SEARCH_INSTANCE_METHOD); + for (auto *overloadedName : node->OverloadedList()) { + if (!overloadedName->IsIdentifier()) { + overloadedName->SetTsType(checker->GlobalTypeError()); + continue; + } + ir::Identifier *ident = overloadedName->AsIdentifier(); + + Type *interfaceType = node->Parent()->Parent()->AsTSInterfaceDeclaration()->TsType(); + ES2PANDA_ASSERT(interfaceType->IsETSObjectType()); + auto *variable = + checker->ResolveOverloadReference(ident->AsIdentifier(), interfaceType->AsETSObjectType(), searchFlags); + + if (variable == nullptr && + checker->ResolveOverloadReference(ident->AsIdentifier(), interfaceType->AsETSObjectType(), + searchFlags | PropertySearchFlags::SEARCH_METHOD) != nullptr) { + checker->LogError(diagnostic::OVERLOAD_SAME_ACCESS_MODIFIERS_STATIC_ASYNC, {}, ident->Start()); + continue; + } + if (variable == nullptr) { + checker->LogError(diagnostic::OVERLOADED_NAME_MUST_FUNCTION, {}, ident->Start()); + ident->SetTsType(checker->GlobalTypeError()); + continue; + } + + ident->SetTsType(variable->TsType()); + ident->SetVariable(variable); + + if (!CheckOverloadedName(checker, node, overloadedName)) { + continue; + } + } +} + +void ETSChecker::CheckConstructorOverloadDeclaration(ETSChecker *checker, ir::OverloadDeclaration *node) const +{ + for (auto *overloadedName : node->OverloadedList()) { + if (!overloadedName->IsIdentifier()) { + overloadedName->SetTsType(checker->GlobalTypeError()); + continue; + } + ir::Identifier *ident = overloadedName->AsIdentifier(); + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + Type *identType = checker->ResolveIdentifier(ident->AsIdentifier()); + ident->SetTsType(identType); + if (identType->IsTypeError()) { + continue; + } + + ES2PANDA_ASSERT(identType->IsETSFunctionType()); + const size_t singleSignatureSize = 1; + if (identType->AsETSFunctionType()->CallSignatures().size() > singleSignatureSize) { + size_t userDefinedConstructorSize = + std::count_if(identType->AsETSFunctionType()->CallSignatures().begin(), + identType->AsETSFunctionType()->CallSignatures().end(), + [](Signature *sig) { return !sig->Function()->IsSynthetic(); }); + if (userDefinedConstructorSize > singleSignatureSize) { + checker->LogError(diagnostic::OVERLOADED_NAME_REFER_TO_OVERLOAD_FUNCTION, {ident->Name()}, + node->Start()); + continue; + } + } + + if (!CheckOverloadedName(checker, node, overloadedName)) { + continue; + } + } +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/typeConverter.h b/ets2panda/checker/ets/typeConverter.h index 2d0bd3db6ce4eecd8838166e27c22b1fb93d0ca7..46635fdc5d66f58cfaa086f6b093a378a749bac2 100644 --- a/ets2panda/checker/ets/typeConverter.h +++ b/ets2panda/checker/ets/typeConverter.h @@ -62,7 +62,7 @@ public: template static Type *ConvertConstantType(Type *source, ArenaAllocator *allocator) { - switch (static_cast(source->TypeFlags() & TypeFlag::ETS_TYPE)) { + switch (static_cast(source->TypeFlags() & (TypeFlag::ETS_NUMERIC | TypeFlag::CHAR))) { case TypeFlag::INT: return ConvertConstant(source->AsIntType(), allocator); @@ -95,7 +95,7 @@ public: { ES2PANDA_ASSERT(source->IsETSPrimitiveType() && target->IsETSPrimitiveType() && source->IsConstantType()); - switch (static_cast(target->TypeFlags() & TypeFlag::ETS_TYPE)) { + switch (static_cast(target->TypeFlags() & (TypeFlag::ETS_NUMERIC | TypeFlag::CHAR))) { case TypeFlag::INT: return ConvertConstantType(source, allocator); diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 86de973cb93954755354e0a09a3bf814945a6cf2..c6396ad6435a2aa5eb7b8cc4107e733429543483 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -17,85 +17,95 @@ #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/gradualType.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); -} - -IntType *ETSChecker::CreateIntTypeFromType(Type *type) -{ - if (!type->HasTypeFlag(TypeFlag::CONSTANT)) { - return GlobalIntType()->AsIntType(); - } - - if (type->IsIntType()) { - return type->AsIntType(); - } - - switch (ETSType(type)) { - case TypeFlag::CHAR: { - return CreateIntType(static_cast(type->AsCharType()->GetValue())); - } - case TypeFlag::BYTE: { - return CreateIntType(static_cast(type->AsByteType()->GetValue())); - } - case TypeFlag::SHORT: { - return CreateIntType(static_cast(type->AsShortType()->GetValue())); - } - default: { - return nullptr; - } - } + return ProgramAllocator()->New(value); } 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) +{ + ETSObjectType *type = GlobalBuiltinETSResizableArrayType(); + ES2PANDA_ASSERT(type != nullptr); + ETSResizableArrayType *const arrayType = type->AsETSResizableArrayType(); + ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); + + Type *baseArrayType = element; + + for (size_t dim = 0; dim < dimSize; ++dim) { + auto tmpSubstitution = Substitution {}; + EmplaceSubstituted(&tmpSubstitution, arrayType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), + MaybeBoxType(baseArrayType)); + baseArrayType = arrayType->Substitute(Relation(), &tmpSubstitution); + } + return baseArrayType->AsETSResizableArrayType(); +} + +ETSResizableArrayType *ETSChecker::CreateETSResizableArrayType(Type *element) +{ + ETSObjectType *type = GlobalBuiltinETSResizableArrayType(); + ES2PANDA_ASSERT(type != nullptr); + ETSResizableArrayType *arrayType = type->AsETSResizableArrayType(); + ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); + + auto substitution = Substitution {}; + EmplaceSubstituted(&substitution, arrayType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), + MaybeBoxType(element)); + return arrayType->Substitute(Relation(), &substitution); } ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePolluting) @@ -105,11 +115,12 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePoll return res->second; } - auto *arrayType = Allocator()->New(elementType); + auto *arrayType = ProgramAllocator()->New(elementType); + ES2PANDA_ASSERT(arrayType != nullptr); 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())) { @@ -119,48 +130,62 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePoll return arrayType; } +Type *ETSChecker::CreateGradualType(Type *type, Language const lang) +{ + if (type == nullptr) { + return type; + } + if (type->IsGradualType()) { + return type; + } + if (type->IsETSAnyType()) { + return type; + } + if (type->IsETSUnionType()) { + ArenaVector copied(ProgramAllocator()->Adapter()); + for (auto const &t : type->AsETSUnionType()->ConstituentTypes()) { + copied.push_back(CreateGradualType(t, lang)); + } + return CreateETSUnionType(std::move(copied)); + } + return ProgramAllocator()->New(type); +} + Type *ETSChecker::CreateETSUnionType(Span constituentTypes) { if (constituentTypes.empty()) { return nullptr; } - ArenaVector newConstituentTypes(Allocator()->Adapter()); + ArenaVector newConstituentTypes(ProgramAllocator()->Adapter()); newConstituentTypes.assign(constituentTypes.begin(), constituentTypes.end()); ETSUnionType::NormalizeTypes(Relation(), newConstituentTypes); if (newConstituentTypes.size() == 1) { return newConstituentTypes[0]; } - - return Allocator()->New(this, std::move(newConstituentTypes)); + auto *un = ProgramAllocator()->New(this, std::move(newConstituentTypes)); + auto ut = un->GetAssemblerType().Mutf8(); + if (std::count_if(ut.begin(), ut.end(), [](char c) { return c == ','; }) > 0) { + unionAssemblerTypes_.insert(un->GetAssemblerType()); + } + return un; } ETSTypeAliasType *ETSChecker::CreateETSTypeAliasType(util::StringView name, const ir::AstNode *declNode, 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)); -} - -ETSFunctionType *ETSChecker::CreateETSDynamicArrowType(Signature *signature, Language lang) -{ - return Allocator()->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)); } static SignatureFlags ConvertToSignatureFlags(ir::ModifierFlags inModifiers, ir::ScriptFunctionFlags inFunctionFlags) @@ -178,9 +203,6 @@ static SignatureFlags ConvertToSignatureFlags(ir::ModifierFlags inModifiers, ir: } }; - convertFlag(ir::ScriptFunctionFlags::THROWS, SignatureFlags::THROWS); - convertFlag(ir::ScriptFunctionFlags::RETHROWS, SignatureFlags::RETHROWS); - convertFlag(ir::ScriptFunctionFlags::CONSTRUCTOR, SignatureFlags::CONSTRUCTOR); convertFlag(ir::ScriptFunctionFlags::SETTER, SignatureFlags::SETTER); convertFlag(ir::ScriptFunctionFlags::GETTER, SignatureFlags::GETTER); @@ -192,6 +214,7 @@ static SignatureFlags ConvertToSignatureFlags(ir::ModifierFlags inModifiers, ir: convertModifier(ir::ModifierFlags::PUBLIC, SignatureFlags::PUBLIC); convertModifier(ir::ModifierFlags::PRIVATE, SignatureFlags::PRIVATE); convertModifier(ir::ModifierFlags::INTERNAL, SignatureFlags::INTERNAL); + convertModifier(ir::ModifierFlags::DEFAULT, SignatureFlags::DEFAULT); return outFlags; } @@ -202,8 +225,9 @@ 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()); + ES2PANDA_ASSERT(signature != nullptr); func->HasReceiver() ? signature->AddSignatureFlag(SignatureFlags::EXTENSION_FUNCTION | convertedFlag) : signature->AddSignatureFlag(convertedFlag); return signature; @@ -216,7 +240,8 @@ 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); + ES2PANDA_ASSERT(signature != nullptr); signature->AddSignatureFlag(ConvertToSignatureFlags(ir::ModifierFlags::NONE, sff)); // synthetic arrow type signature flags auto extraFlags = SignatureFlags::ABSTRACT | SignatureFlags::CALL | SignatureFlags::PUBLIC; @@ -227,18 +252,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,30 +293,46 @@ 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: { auto *objType = setType(GlobalTypeId::ETS_OBJECT_BUILTIN, create())->AsETSObjectType(); auto null = checker->GlobalETSNullType(); auto undef = checker->GlobalETSUndefinedType(); - setType(GlobalTypeId::ETS_NULLISH_OBJECT, checker->CreateETSUnionType({objType, null, undef})); - setType(GlobalTypeId::ETS_NULLISH_TYPE, checker->CreateETSUnionType({null, undef})); + setType(GlobalTypeId::ETS_UNION_UNDEFINED_NULL_OBJECT, checker->CreateETSUnionType({objType, null, undef})); + setType(GlobalTypeId::ETS_UNION_UNDEFINED_NULL, checker->CreateETSUnionType({null, undef})); return objType; } case GlobalTypeId::ETS_STRING_BUILTIN: { 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() != compiler::Signatures::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_READONLY_ARRAY: + if (declNode->IsClassDefinition() || declNode->AsTSInterfaceDeclaration()->InternalName().Utf8() != + compiler::Signatures::ESCOMPAT_READONLYARRAY) { + return checker->CreateETSObjectType(declNode, flags); + } + return setType(globalId, create(ETSObjectFlags::BUILTIN_READONLY_ARRAY))->AsETSObjectType(); case GlobalTypeId::ETS_BOOLEAN_BUILTIN: return create(ETSObjectFlags::BUILTIN_BOOLEAN); case GlobalTypeId::ETS_BYTE_BUILTIN: @@ -318,6 +359,7 @@ ETSObjectType *ETSChecker::CreateETSObjectTypeOrBuiltin(ir::AstNode *declNode, E if (LIKELY(HasStatus(CheckerStatus::BUILTINS_INITIALIZED))) { return CreateETSObjectType(declNode, flags); } + // Note (zengran): should be determined whether is a builtin type through InternalName instead of DeclName. auto const globalId = GetGlobalTypesHolder()->NameToId(GetObjectTypeDeclNames(declNode).first); if (!globalId.has_value()) { return CreateETSObjectType(declNode, flags); @@ -325,50 +367,27 @@ ETSObjectType *ETSChecker::CreateETSObjectTypeOrBuiltin(ir::AstNode *declNode, E return InitializeGlobalBuiltinObjectType(this, globalId.value(), declNode, flags); } -std::tuple ETSChecker::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 *ETSChecker::CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags) { auto const [name, internalName] = GetObjectTypeDeclNames(declNode); - + ETSObjectType *objectType = nullptr; if (declNode->IsClassDefinition() && (declNode->AsClassDefinition()->IsEnumTransformed())) { if (declNode->AsClassDefinition()->IsIntEnumTransformed()) { - return Allocator()->New(Allocator(), name, internalName, declNode, Relation()); + objectType = + ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, Relation()); + } else { + ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); + objectType = ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, + Relation()); } - ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); - return Allocator()->New(Allocator(), name, internalName, declNode, Relation()); + } else if (internalName == compiler::Signatures::BUILTIN_ARRAY) { + objectType = ProgramAllocator()->New(ProgramAllocator(), name, + std::make_tuple(declNode, flags, Relation())); + } else { + objectType = ProgramAllocator()->New(ProgramAllocator(), name, internalName, + 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 Allocator()->New(Allocator(), name, internalName, - std::make_tuple(declNode, flags, Relation())); + return objectType; } std::tuple ETSChecker::CreateBuiltinArraySignatureInfo(const ETSArrayType *arrayType, @@ -380,12 +399,14 @@ std::tuple ETSChecker::CreateBuiltinArraySign arrayType->ToAssemblerTypeWithRank(ss); auto *info = CreateSignatureInfo(); + ES2PANDA_ASSERT(info != nullptr); info->minArgCount = dim; for (size_t i = 0; i < dim; i++) { - 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); + ES2PANDA_ASSERT(paramVar != nullptr); paramVar->SetTsType(GlobalIntType()); info->params.push_back(paramVar); @@ -395,22 +416,26 @@ 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); + ES2PANDA_ASSERT(signature != nullptr); signature->SetInternalName(internalName); - globalArraySignatures_.insert({arrayType, signature}); + globalArraySignatures.insert({arrayType, signature}); return signature; } @@ -420,10 +445,11 @@ ETSObjectType *ETSChecker::CreatePromiseOf(Type *type) ETSObjectType *const promiseType = GlobalBuiltinPromiseType(); ES2PANDA_ASSERT(promiseType->TypeArguments().size() == 1U); - Substitution *substitution = NewSubstitution(); - EmplaceSubstituted(substitution, promiseType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), type); + auto substitution = Substitution {}; + ES2PANDA_ASSERT(promiseType != nullptr); + EmplaceSubstituted(&substitution, promiseType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), type); - return promiseType->Substitute(Relation(), substitution); + return promiseType->Substitute(Relation(), &substitution); } static bool IsInValidKeyofTypeNode(ir::AstNode *node) @@ -461,7 +487,7 @@ void ETSChecker::ProcessTypeMembers(ETSObjectType *type, ArenaVector &li Type *ETSChecker::CreateUnionFromKeyofType(ETSObjectType *const type) { - ArenaVector stringLiterals(Allocator()->Adapter()); + ArenaVector stringLiterals(ProgramAllocator()->Adapter()); std::deque superTypes; superTypes.push_back(type); auto enqueueSupers = [&](ETSObjectType *currentType) { @@ -486,13 +512,13 @@ Type *ETSChecker::CreateUnionFromKeyofType(ETSObjectType *const type) 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 039b1ce024f0c488a8b6cd9453a88ec82250a60f..d2835dec80367d14eb1aa29ef1050222f0848e85 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -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; @@ -74,30 +73,18 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame if (typeArgs != nullptr) { for (auto *const it : typeArgs->Params()) { auto *paramType = it->GetType(checker_); + ES2PANDA_ASSERT(paramType != nullptr); if (paramType->IsTypeError()) { result_ = paramType; return; } - - if (paramType->IsETSPrimitiveType()) { - checker_->Relation()->SetNode(it); - - auto *const boxedTypeArg = checker_->MaybeBoxInRelation(paramType); - if (boxedTypeArg != nullptr) { - paramType = boxedTypeArg->Instantiate(checker_->Allocator(), checker_->Relation(), - checker_->GetGlobalTypesHolder()); - } else { - ES2PANDA_UNREACHABLE(); - } - } - + ES2PANDA_ASSERT(!paramType->IsETSPrimitiveType()); typeArgTypes.push_back(paramType); } } while (typeArgTypes.size() < type->TypeArguments().size()) { Type *defaultType = nullptr; - if (type->TypeArguments().at(typeArgTypes.size())->IsETSTypeParameter()) { defaultType = type->TypeArguments().at(typeArgTypes.size())->AsETSTypeParameter()->GetDefaultType(); } else { @@ -112,7 +99,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame } } - auto pos = (typeArgs == nullptr) ? lexer::SourcePosition() : typeArgs->Range().start; + auto pos = (typeArgs == nullptr) ? type->Variable()->Declaration()->Node()->Range().start : typeArgs->Range().start; InstantiateType(type, std::move(typeArgTypes), pos); ES2PANDA_ASSERT(result_->IsETSObjectType()); result_->AsETSObjectType()->AddObjectFlag(ETSObjectFlags::NO_OPTS); @@ -124,6 +111,7 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorRelation(); for (auto type : typeParams) { + type = type->MaybeBaseTypeOfGradualType(); if (!type->IsETSTypeParameter()) { continue; } @@ -137,10 +125,10 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorIsETSReferenceType() || typeArg->IsETSVoidType()); + auto maybeIrrelevantTypeArg = typeArg->IsETSVoidType() ? checker->GlobalETSUndefinedType() : typeArg; auto constraint = typeParam->GetConstraintType()->Substitute(relation, substitution); - if (!relation->IsAssignableTo(typeArg, constraint)) { - // NOTE(vpukhov): refine message - checker->LogError(diagnostic::INIT_NOT_ASSIGNABLE, {typeArg, constraint}, pos); + if (!relation->IsSupertypeOf(constraint, maybeIrrelevantTypeArg)) { + checker->LogError(diagnostic::TYPEARG_TYPEPARAM_SUBTYPING, {typeArg, constraint}, pos); } } } @@ -150,7 +138,7 @@ void ConstraintCheckScope::TryCheckConstraints() if (Unlock()) { auto &records = checker_->PendingConstraintCheckRecords(); for (auto const &[typeParams, substitution, pos] : records) { - CheckInstantiationConstraints(checker_, *typeParams, substitution, pos); + CheckInstantiationConstraints(checker_, *typeParams, &substitution, pos); } records.clear(); } @@ -166,21 +154,21 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorNewSubstitution(); + auto substitution = Substitution {}; for (size_t idx = 0; idx < typeParams.size(); idx++) { if (!typeParams[idx]->IsETSTypeParameter()) { continue; } - checker_->EmplaceSubstituted(substitution, typeParams[idx]->AsETSTypeParameter(), typeArgTypes[idx]); + checker_->EmplaceSubstituted(&substitution, typeParams[idx]->AsETSTypeParameter(), typeArgTypes[idx]); } ConstraintCheckScope ctScope(checker_); + result_ = type->Substitute(checker_->Relation(), &substitution)->AsETSObjectType(); if (!checker_->Relation()->NoThrowGenericTypeAlias()) { - checker_->PendingConstraintCheckRecords().push_back({&typeParams, substitution, pos}); + checker_->PendingConstraintCheckRecords().emplace_back(&typeParams, std::move(substitution), pos); } - result_ = type->Substitute(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 ef6c5017f9cb026520b83ba5f7166d0b5855baeb..7ba41f94c85585a2607a67f9da63bea20b07c3ff 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -34,6 +34,9 @@ public: auto *const etsChecker = relation->GetChecker()->AsETSChecker(); + ES2PANDA_ASSERT(target != nullptr); + ES2PANDA_ASSERT(node != nullptr); + ES2PANDA_ASSERT(source != nullptr); if (target->IsETSArrayType() && node->IsArrayExpression()) { assignable_ = ValidateArrayTypeInitializerByElement(relation, node->AsArrayExpression(), target->AsETSArrayType()); @@ -45,19 +48,11 @@ public: flags_ |= flags; relation->SetNode(node); - // NOTE (oeotvos) The narrowing flag will be applied here. It means, that the result of "let tmp: int = 1.5" - // will be 1, which could cause problems. - if (source->HasTypeFlag(TypeFlag::CONSTANT)) { - flags_ |= TypeRelationFlag::NARROWING; - } - relation->SetFlags(flags_); if (!relation->IsAssignableTo(source, target)) { if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { - Type *sourceUnboxedType = etsChecker->MaybeUnboxType(source); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetBoxingFlag(target)); + relation->Result(true); } if (((flags_ & TypeRelationFlag::UNBOXING) != 0) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { @@ -107,6 +102,9 @@ public: relation->SetFlags(flags_ | initialFlags); if (!relation->IsAssignableTo(source, target)) { + if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { + relation->Result(true); + } if (((flags_ & TypeRelationFlag::UNBOXING) != 0U) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { etsChecker->CheckUnboxedSourceTypeWithWideningAssignable(relation, source, target); diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 138fe7d21e3f6aae71973d47c1b3ba43b7cc3b9a..b47ff09f704ff798f08c2f74b964a72b4f48ba63 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -22,6 +22,11 @@ #include "ir/expressions/literals/undefinedLiteral.h" #include "varbinder/ETSBinder.h" #include "checker/types/ets/etsPartialTypeParameter.h" +#include "checker/types/ets/etsAwaitedType.h" +#include "compiler/lowering/util.h" +#include "util/nameMangler.h" + +#include namespace ark::es2panda::checker { @@ -35,6 +40,13 @@ std::optional ETSChecker::GetUtilityTypeTypeParamNode( return typeParams->Params().front(); } +static bool ValidBaseTypeOfRequiredAndPartial(Type *baseType) +{ + Type *type = baseType->MaybeBaseTypeOfGradualType(); + return type->IsETSObjectType() && (type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE) || + type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)); +} + Type *ETSChecker::HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstantiation *const typeParams, const ir::Identifier *const ident) { @@ -59,6 +71,17 @@ Type *ETSChecker::HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstan return GlobalTypeError(); } + if (baseType->IsETSAnyType()) { + return baseType; + } + + if ((utilityType == compiler::Signatures::PARTIAL_TYPE_NAME || + utilityType == compiler::Signatures::REQUIRED_TYPE_NAME) && + !ValidBaseTypeOfRequiredAndPartial(baseType)) { + LogError(diagnostic::MUST_BE_CLASS_INTERFACE_TYPE, {utilityType}, typeParams->Start()); + return GlobalTypeError(); + } + if (utilityType == compiler::Signatures::PARTIAL_TYPE_NAME) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return CreatePartialType(baseType); @@ -72,10 +95,98 @@ Type *ETSChecker::HandleUtilityTypeParameterNode(const ir::TSTypeParameterInstan return HandleRequiredType(baseType); } + if (utilityType == compiler::Signatures::AWAITED_TYPE_NAME) { + return HandleAwaitedUtilityType(baseType); + } + LogError(diagnostic::UTILITY_TYPE_UNIMPLEMENTED, {}, typeParams->Start()); return baseType; } +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// Awaited utility type +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +bool ETSChecker::IsPromiseType(Type *type) +{ + if (type->IsETSUnionType()) { + for (Type *constituentType : type->AsETSUnionType()->ConstituentTypes()) { + if (!IsPromiseType(constituentType)) { + return false; + } + } + return true; + } + return type->IsETSObjectType() && type->AsETSObjectType()->GetOriginalBaseType() == GlobalBuiltinPromiseType(); +} + +Type *ETSChecker::UnwrapPromiseType(checker::Type *type) +{ + Type *promiseType = GlobalBuiltinPromiseType(); + while (type->IsETSObjectType() && type->AsETSObjectType()->GetOriginalBaseType() == promiseType) { + type = type->AsETSObjectType()->TypeArguments().at(0); + } + if (!type->IsETSUnionType()) { + return type; + } + const auto &ctypes = type->AsETSUnionType()->ConstituentTypes(); + auto it = std::find_if(ctypes.begin(), ctypes.end(), [promiseType](checker::Type *t) { + return t == promiseType || (t->IsETSObjectType() && t->AsETSObjectType()->GetBaseType() == promiseType); + }); + if (it == ctypes.end()) { + return type; + } + ArenaVector newCTypes(ctypes); + do { + size_t index = it - ctypes.begin(); + newCTypes[index] = UnwrapPromiseType(ctypes[index]); + ++it; + it = std::find_if(it, ctypes.end(), [promiseType](checker::Type *t) { + return t == promiseType || t->AsETSObjectType()->GetBaseType() == promiseType; + }); + } while (it != ctypes.end()); + return CreateETSUnionType(std::move(newCTypes)); +} + +Type *ETSChecker::HandleAwaitedUtilityType(Type *typeToBeAwaited) +{ + if (typeToBeAwaited->IsETSTypeParameter()) { + return ProgramAllocator()->New(typeToBeAwaited->AsETSTypeParameter()); + } + + if (typeToBeAwaited->IsETSUnionType()) { + ArenaVector awaitedTypes(ProgramAllocator()->Adapter()); + for (Type *type : typeToBeAwaited->AsETSUnionType()->ConstituentTypes()) { + Type *unwrapped = IsPromiseType(type) ? type->AsETSObjectType()->TypeArguments().at(0) : type; + if (unwrapped->IsETSTypeParameter()) { + unwrapped = HandleAwaitedUtilityType(unwrapped); + } + awaitedTypes.push_back(UnwrapPromiseType(unwrapped)); + } + return CreateETSUnionType(std::move(awaitedTypes)); + } + + if (IsPromiseType(typeToBeAwaited)) { + Type *typeArg = typeToBeAwaited->AsETSObjectType()->TypeArguments().at(0); + auto unwrappedType = UnwrapPromiseType(typeArg); + return unwrappedType->IsETSTypeParameter() ? HandleAwaitedUtilityType(unwrappedType) : unwrappedType; + } + + return typeToBeAwaited; +} + +Type *ETSChecker::HandleAwaitExpression(Type *typeToBeAwaited, ir::AwaitExpression *expr) +{ + Relation()->SetFlags(TypeRelationFlag::IGNORE_TYPE_PARAMETERS); + if (!typeToBeAwaited->IsETSTypeParameter() && + !Relation()->IsSupertypeOf(GlobalBuiltinPromiseType(), typeToBeAwaited)) { + LogError(diagnostic::AWAITED_TYPE_NOT_PROMISE, {typeToBeAwaited}, expr->Start()); + return typeToBeAwaited; + } + Relation()->RemoveFlags(TypeRelationFlag::IGNORE_TYPE_PARAMETERS); + + return HandleAwaitedUtilityType(typeToBeAwaited); +} + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // Partial utility type // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -84,7 +195,9 @@ 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(); + std::string newName = + util::NameMangler::GetInstance()->CreateMangledNameByTypeAndName(util::NameMangler::PARTIAL, name); + return util::UString(newName, checker->ProgramAllocator()).View(); }; auto declIdent = typeNode->IsClassDefinition() ? typeNode->AsClassDefinition()->Ident() @@ -98,7 +211,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)}; @@ -114,6 +227,14 @@ static T *CloneNodeIfNotNullptr(T *node, ArenaAllocator *allocator) Type *ETSChecker::CreatePartialType(Type *const typeToBePartial) { ES2PANDA_ASSERT(typeToBePartial->IsETSReferenceType()); + if (typeToBePartial->IsTypeError() || typeToBePartial->IsETSNeverType() || typeToBePartial->IsETSAnyType()) { + return typeToBePartial; + } + + if (typeToBePartial->IsGradualType()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return CreatePartialType(typeToBePartial->AsGradualType()->GetBaseType()); + } if (typeToBePartial->IsETSTypeParameter()) { return CreatePartialTypeParameter(typeToBePartial->AsETSTypeParameter()); @@ -131,7 +252,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) @@ -141,7 +262,9 @@ Type *ETSChecker::CreatePartialTypeClass(ETSObjectType *typeToBePartial, ir::Ast // Check if we've already generated the partial class, then don't do it again const auto classNameToFind = - partialProgram == VarBinder()->Program() || VarBinder()->IsGenStdLib() ? partialName : partialQualifiedName; + partialProgram == VarBinder()->Program() || VarBinder()->IsGenStdLib() || partialProgram->IsGenAbcForExternal() + ? partialName + : partialQualifiedName; if (auto *var = SearchNamesInMultiplePrograms({partialProgram, VarBinder()->Program()}, {classNameToFind, partialName}); var != nullptr) { @@ -204,8 +327,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); @@ -215,17 +341,22 @@ Type *ETSChecker::HandlePartialInterface(ir::TSInterfaceDeclaration *interfaceDe ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefinition *const accessor, ir::ClassDefinition *const newClassDefinition) { + auto *id = accessor->Id(); + ES2PANDA_ASSERT(id != nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *ident = accessor->Id()->Clone(Allocator(), nullptr); + auto *ident = id->Clone(ProgramAllocator(), nullptr); + ES2PANDA_ASSERT(accessor->Function() != nullptr); auto modifierFlag = accessor->Function()->IsGetter() && accessor->Overloads().empty() ? ir::ModifierFlags::READONLY : ir::ModifierFlags::NONE; - // 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); + ES2PANDA_ASSERT(prop != nullptr); prop->SetParent(newClassDefinition); ident->SetParent(prop); + ES2PANDA_ASSERT(accessor->Function() != nullptr); prop->SetTypeAnnotation(accessor->Function()->IsGetter() ? accessor->Function()->ReturnTypeAnnotation() : accessor->Function()->Params()[0]->AsETSParameterExpression()->TypeAnnotation()); @@ -235,16 +366,14 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin return CreateNullishProperty(prop, newClassDefinition); } - if (accessor->TsType() == nullptr) { - accessor->Parent()->Check(this); - } - + ES2PANDA_ASSERT(accessor->TsType()->IsETSFunctionType()); auto callSign = accessor->TsType()->AsETSFunctionType()->CallSignatures()[0]; + ES2PANDA_ASSERT(accessor->Function() != nullptr); 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 +388,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 +428,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(), newClassDefinition)->AsClassProperty(); + auto *const propClone = prop->Clone(ProgramAllocator(), newClassDefinition)->AsClassProperty(); + propClone->CleanCheckInformation(); // 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,22 +465,24 @@ 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()); + ES2PANDA_ASSERT(newTypeParam != nullptr); newTypeParams->AddParam(newTypeParam); newTypeParam->SetParent(newTypeParams); + ES2PANDA_ASSERT(likeSubstitution != nullptr); (*likeSubstitution)[classOrInterfaceDefTypeParam] = newTypeParam; } return newTypeParams; @@ -365,8 +497,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(); @@ -375,15 +508,18 @@ ir::TSTypeParameterInstantiation *ETSChecker::CreateNewSuperPartialRefTypeParams !originRefParams[ix]->AsETSTypeReference()->Part()->TsType()->IsETSTypeParameter()) { continue; } - auto it = likeSubstitution->find( - originRefParams[ix]->AsETSTypeReference()->Part()->TsType()->AsETSTypeParameter()->GetDeclNode()); + auto type = originRefParams[ix]->AsETSTypeReference()->Part()->TsType(); + auto it = likeSubstitution->find(type->AsETSTypeParameter()->GetDeclNode()); 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()); + ES2PANDA_ASSERT(typeParamRefPart != nullptr); typeParamRefPart->Name()->SetParent(typeParamRefPart); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *typeParamRef = AllocNode(typeParamRefPart, Allocator()); + auto *typeParamRef = ProgramAllocNode(typeParamRefPart, ProgramAllocator()); + ES2PANDA_ASSERT(typeParamRef != nullptr); typeParamRefPart->SetParent(typeParamRef); typeParamRef->SetParent(superPartialRefTypeParams); @@ -399,47 +535,52 @@ 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()); + ES2PANDA_ASSERT(superPartialRefPart != nullptr); 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; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newClassDefinition, 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()); + ES2PANDA_ASSERT(newTypeParams != nullptr); newClassDefinition->SetTypeParams(newTypeParams); newTypeParams->SetParent(newClassDefinition); } @@ -451,7 +592,8 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla // Only handle class properties (members) // Method calls on partial classes will make the class not type safe, so we don't copy any methods if (prop->IsClassProperty()) { - if (prop->AsClassProperty()->Id()->Name().Mutf8().find(compiler::Signatures::PROPERTY, 0) == 0) { + if (prop->AsClassProperty()->Id() == nullptr || + prop->AsClassProperty()->Id()->Name().Mutf8().find(compiler::Signatures::PROPERTY, 0) == 0) { continue; } @@ -459,18 +601,30 @@ 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() || - prop->AsMethodDefinition()->Function()->IsSetter())) { + if (prop->IsMethodDefinition() && prop->AsMethodDefinition()->Function() != nullptr && + (prop->AsMethodDefinition()->Function()->IsGetter() || + prop->AsMethodDefinition()->Function()->IsSetter())) { auto *method = prop->AsMethodDefinition(); + ES2PANDA_ASSERT(method->Id() != nullptr); + auto isBrokenSetter = method->Function()->IsSetter() && method->Function()->Params().size() != 1; + auto isBrokenGetter = method->Function()->IsGetter() && !method->Function()->Params().empty(); if (newClassDefinition->Scope()->FindLocal(method->Id()->Name(), - varbinder::ResolveBindingOptions::VARIABLES) != nullptr) { + varbinder::ResolveBindingOptions::VARIABLES) != nullptr || + isBrokenSetter || isBrokenGetter) { + ES2PANDA_ASSERT(IsAnyError()); continue; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - newClassDefinition->Body().emplace_back(CreateNullishPropertyFromAccessor(method, newClassDefinition)); + + if (method->TsType() == nullptr) { + method->Parent()->Check(this); + } + + if (method->TsType() != nullptr && !method->TsType()->IsTypeError()) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + newClassDefinition->EmplaceBody(CreateNullishPropertyFromAccessor(method, newClassDefinition)); + } } } if (classDef->IsDeclare()) { @@ -484,12 +638,44 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla newClassDefinition->Variable()->SetTsType(nullptr); } +static void SetupFunctionParams(ir::ScriptFunction *function, varbinder::FunctionParamScope *paramScope, + checker::ETSChecker *checker) +{ + for (auto *params : function->Params()) { + auto *paramExpr = params->AsETSParameterExpression(); + if (paramExpr->Ident()->TypeAnnotation() == nullptr) { + paramExpr->Ident()->SetTsTypeAnnotation(nullptr); + } else { + auto *unionType = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + checker->ProgramAllocNode( + ArenaVector( + {paramExpr->Ident()->TypeAnnotation(), + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + checker->ProgramAllocNode(checker->ProgramAllocator())}, + checker->ProgramAllocator()->Adapter()), + checker->ProgramAllocator()); + ES2PANDA_ASSERT(unionType != nullptr); + paramExpr->Ident()->SetTsTypeAnnotation(unionType); + unionType->SetParent(paramExpr->Ident()); + } + auto [paramVar, node] = paramScope->AddParamDecl(checker->ProgramAllocator(), checker->VarBinder(), paramExpr); + if (node != nullptr) { + checker->VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name(), paramVar->Declaration()->Type()); + } + + paramExpr->SetVariable(paramVar); + } +} + +// 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); + ES2PANDA_ASSERT(functionScope != nullptr); functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); @@ -499,10 +685,13 @@ 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()); + nullishAccessor->SetRange(accessor->Range()); + nullishAccessor->Function()->SetRange(accessor->Function()->Range()); - 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 +702,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 +711,17 @@ 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( - ArenaVector({paramExpr->Ident()->TypeAnnotation(), - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(Allocator())}, - Allocator()->Adapter()), - Allocator()); - paramExpr->Ident()->SetTsTypeAnnotation(unionType); - unionType->SetParent(paramExpr->Ident()); - - auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), VarBinder(), paramExpr); - if (node != nullptr) { - VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); - } - - paramExpr->SetVariable(paramVar); - } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + SetupFunctionParams(function, paramScope, this); } - nullishAccessor->SetOverloads(ArenaVector(Allocator()->Adapter())); + nullishAccessor->SetOverloads(ArenaVector(ProgramAllocator()->Adapter())); return nullishAccessor; } @@ -564,26 +734,28 @@ 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()); + ES2PANDA_ASSERT(interfaceId != nullptr); 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)}); const auto classCtx = varbinder::LexicalScope(VarBinder()); + ES2PANDA_ASSERT(partialInterface != nullptr); partialInterface->TypeParams()->SetParent(partialInterface); partialInterface->SetScope(classCtx.GetScope()); partialInterface->SetVariable(var); @@ -591,10 +763,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; } @@ -634,14 +808,17 @@ void ETSChecker::CreatePartialTypeInterfaceMethods(ir::TSInterfaceDeclaration *c } auto *const method = prop->AsMethodDefinition(); - ES2PANDA_ASSERT((method->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); + ES2PANDA_ASSERT((func->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); - if (method->Function()->IsGetter() || method->Function()->IsSetter()) { + if (func->IsGetter() || func->IsSetter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) addNullishAccessor(CreateNullishAccessor(method, partialInterface)); } for (auto *overload : method->Overloads()) { + ES2PANDA_ASSERT(overload->Function() != nullptr); if (overload->Function()->IsGetter() || overload->Function()->IsSetter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) addNullishAccessor(CreateNullishAccessor(overload, partialInterface)); @@ -659,7 +836,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) @@ -672,10 +849,12 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con auto methodscope = partialInterface->Scope()->AsClassScope()->InstanceMethodScope(); // Add getter methods to instancemethodscope. for (auto *const prop : partialInterface->Body()->Body()) { - if (prop->IsMethodDefinition() && prop->AsMethodDefinition()->Function()->IsGetter()) { - auto *decl = Allocator()->New( - Allocator(), prop->AsMethodDefinition()->Key()->AsIdentifier()->Name(), prop); - methodscope->AddDecl(Allocator(), decl, ScriptExtension::ETS); + auto *func = prop->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + if (prop->IsMethodDefinition() && func->IsGetter()) { + auto *decl = ProgramAllocator()->New( + ProgramAllocator(), prop->AsMethodDefinition()->Key()->AsIdentifier()->Name(), prop); + methodscope->AddDecl(ProgramAllocator(), decl, ScriptExtension::ETS); } } @@ -693,7 +872,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 +905,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 +920,8 @@ 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()); + ES2PANDA_ASSERT(classId != nullptr); const auto [decl, var] = VarBinder()->NewVarDecl(classId->Start(), classId->Name()); classId->SetVariable(var); @@ -749,14 +929,16 @@ 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)); + ES2PANDA_ASSERT(classDef != nullptr); 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()); + ES2PANDA_ASSERT(classDecl != nullptr); classDecl->SetParent(classDeclProgram->Ast()); // Class definition is scope bearer, not class declaration @@ -764,7 +946,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 +978,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)) { @@ -837,6 +1019,13 @@ Type *ETSChecker::CreatePartialTypeClassDef(ir::ClassDefinition *const partialCl ? GlobalETSObjectType() : classDef->Super()->TsType()); + if (partialSuper == partialType) { + LogError(diagnostic::CYCLIC_CLASS_SUPER_TYPE, {}, classDef->Start()); + return partialType; + } + if (partialSuper->IsTypeError()) { + return partialType; + } partialType->SetSuperType(partialSuper->AsETSObjectType()); } @@ -846,25 +1035,27 @@ 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)); + ES2PANDA_ASSERT(body != nullptr); 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}); + ES2PANDA_ASSERT(func != nullptr); func->SetScope(scope); scope->BindNode(func); func->SetIdent(id); @@ -878,8 +1069,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 +1091,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; @@ -919,10 +1111,16 @@ Type *ETSChecker::GetReadonlyType(Type *type) return *found; } - NamedTypeStackElement ntse(this, type); + if (type->IsGradualType()) { + return GetReadonlyType(type->AsGradualType()->GetBaseType()); + } + NamedTypeStackElement ntse(this, type); + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSArrayType()) { - ETSArrayType *const clonedArrayType = Allocator()->New(type->AsETSArrayType()->ElementType()); + ETSArrayType *const clonedArrayType = + ProgramAllocator()->New(type->AsETSArrayType()->ElementType()); + ES2PANDA_ASSERT(clonedArrayType != nullptr); clonedArrayType->AddTypeFlag(TypeFlag::READONLY); return clonedArrayType; } @@ -939,10 +1137,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 +1151,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,10 +1179,11 @@ 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); + ES2PANDA_ASSERT(type != nullptr); MakePropertiesNonNullish(type->AsETSObjectType()); } @@ -1003,7 +1203,7 @@ Type *ETSChecker::HandleRequiredType(Type *typeToBeRequired) typeToBeRequired = typeToBeRequired->Clone(this); - MakePropertiesNonNullish(typeToBeRequired->AsETSObjectType()); + MakePropertiesNonNullish(typeToBeRequired->MaybeBaseTypeOfGradualType()->AsETSObjectType()); return typeToBeRequired; } @@ -1034,8 +1234,8 @@ 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()); + ES2PANDA_ASSERT(propCopy != nullptr); propCopy->SetTsType(nonNullishPropType); classType->RemoveProperty(prop); classType->AddProperty(propCopy); @@ -1065,7 +1265,12 @@ void ETSChecker::ValidateObjectLiteralForRequiredType(const ETSObjectType *const if (requiredType->HasObjectFlag(ETSObjectFlags::INTERFACE)) { for (const auto *method : requiredType->GetDeclNode()->AsTSInterfaceDeclaration()->Body()->Body()) { - if (!method->IsMethodDefinition() || !method->AsMethodDefinition()->Function()->IsGetter()) { + if (!method->IsMethodDefinition()) { + continue; + } + auto *func = method->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + if (!func->IsGetter()) { continue; } @@ -1085,4 +1290,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 ed71d79e9525a88cf44e20873d0dc89cfffaa9aa..ead157339ea626fbba740c0fda764617e5ce8ff7 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -51,24 +51,63 @@ void ETSChecker::ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType } } +bool ETSChecker::IsStaticInvoke(ir::MemberExpression *const expr) +{ + ir::Identifier *ident = nullptr; + if (expr->Object()->IsIdentifier()) { + ident = expr->Object()->AsIdentifier(); + } else if (expr->Object()->IsMemberExpression()) { + auto object = expr->Object(); + + while (object->IsMemberExpression()) { + object = object->AsMemberExpression()->Object(); + } + if (object->IsIdentifier()) { + ident = object->AsIdentifier(); + } + } + + return (ident != nullptr && + (ident->Variable()->Declaration()->IsClassDecl() || ident->Variable()->Declaration()->IsImportDecl())); +} + void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, Type *const type) { - if (ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && - ident->Parent()->AsCallExpression()->Callee() != ident) { + ir::CallExpression *callExpr = nullptr; + if (ident->Parent()->IsMemberExpression() && IsStaticInvoke(ident->Parent()->AsMemberExpression())) { + callExpr = ident->Parent()->Parent()->AsCallExpression(); + } else if (ident->Parent()->IsCallExpression()) { + callExpr = ident->Parent()->AsCallExpression(); + } else { + return; + } + + if (ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)) { + if (callExpr->Callee()->Variable() != nullptr && callExpr->Callee()->Variable()->Name().Is("with")) { + LogError(diagnostic::ERROR_ARKTS_NO_WITH, callExpr->Start()); + } + } + + if (ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && callExpr->Callee() != ident && + callExpr->Callee() != ident->Parent()) { std::ignore = TypeError(ident->Variable(), diagnostic::CLASS_OR_IFACE_AS_OBJ, {ident->ToString()}, ident->Start()); } - if (ident->Parent()->AsCallExpression()->Callee() != ident) { + if (callExpr->Callee() != ident && callExpr->Callee() != ident->Parent()) { return; } ES2PANDA_ASSERT(ident->Variable() != nullptr); + if (ident->Variable()->Declaration()->Node() != nullptr && + ident->Variable()->Declaration()->Node()->IsOverloadDeclaration()) { + return; + } if (ident->Variable()->Declaration()->Node() != nullptr && ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier()) { std::ignore = TypeError(ident->Variable(), diagnostic::NAMESPACE_CALL, {ident->ToString()}, ident->Start()); } - if (type->IsETSFunctionType() || type->IsETSDynamicType()) { + if (type->IsETSFunctionType() || type->IsETSRelaxedAnyType()) { return; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -129,7 +168,8 @@ bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, const auto *const binaryExpr = ident->Parent()->AsBinaryExpression(); bool isFinished = false; - if (binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF && binaryExpr->Left() == ident) { + bool isInstanceOfKeyword = binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF; + if (isInstanceOfKeyword && binaryExpr->Left() == ident) { if (!IsReferenceType(type)) { std::ignore = TypeError(ident->Variable(), diagnostic::INSTANCEOF_NONOBJECT, {ident->Name()}, ident->Start()); @@ -145,6 +185,10 @@ bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, } isFinished = true; } + if (isInstanceOfKeyword && ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE | + varbinder::VariableFlags::TYPE_ALIAS)) { + LogError(diagnostic::WRONG_LEFT_OF_INSTANCEOF, {}, ident->Start()); + } return isFinished; } @@ -158,7 +202,9 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) auto *smartType = Context().GetSmartCast(resolved); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const resolvedType = GetApparentType(smartType != nullptr ? smartType : GetTypeOfVariable(resolved)); - + bool isValidResolved = + resolved != nullptr && !resolved->Declaration()->PossibleTDZ() && + !(resolvedType->IsETSFunctionType() && !resolved->Declaration()->Node()->IsTSTypeAliasDeclaration()); switch (ident->Parent()->Type()) { case ir::AstNodeType::CALL_EXPRESSION: // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -174,7 +220,10 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) if (ValidateBinaryExpressionIdentifier(ident, resolvedType)) { return; } - [[fallthrough]]; + if (isValidResolved) { + WrongContextErrorClassifyByType(ident); + } + break; case ir::AstNodeType::UPDATE_EXPRESSION: case ir::AstNodeType::UNARY_EXPRESSION: if (resolved != nullptr && !resolved->Declaration()->PossibleTDZ()) { @@ -185,28 +234,13 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) ValidateAssignmentIdentifier(ident, resolvedType); break; default: - if (resolved != nullptr && !resolved->Declaration()->PossibleTDZ() && !resolvedType->IsETSFunctionType()) { + if (isValidResolved) { WrongContextErrorClassifyByType(ident); } } } -bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) -{ - if (type == nullptr || type->IsTypeError()) { - ES2PANDA_ASSERT(IsAnyError()); - return false; - } - - if (type->IsETSArrayType()) { - return ValidateAnnotationPropertyType(type->AsETSArrayType()->ElementType()); - } - - return type->HasTypeFlag(TypeFlag::ETS_NUMERIC | TypeFlag::ETS_ENUM | TypeFlag::ETS_BOOLEAN) || - type->IsETSStringType(); -} - -void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) +void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable, ir::Expression *expr) { if (IsVariableGetterSetter(variable)) { return; @@ -214,15 +248,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)) { + 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, diagnostic::FIELD_ASSIGN_TYPE_MISMATCH, {fieldType, variable->Name()}, - variable->Declaration()->Node()->Start()); + const auto &diagKind = variable->Declaration()->IsConstDecl() ? diagnostic::FIELD_ASSIGN_TO_CONST + : diagnostic::FIELD_ASSIGN_TO_READONLY; + std::ignore = TypeError(variable, diagKind, {variable->Name()}, expr->Start()); + } + + if (variable->HasFlag(varbinder::VariableFlags::INIT_IN_STATIC_BLOCK)) { + variable->AddFlag(varbinder::VariableFlags::INITIALIZED); } } } @@ -273,7 +314,7 @@ void ETSChecker::ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaratio ir::TypeNode *typeParamType = nullptr; - if (exactTypeParams->Params().size() > typeParamIdx) { + if (exactTypeParams != nullptr && exactTypeParams->Params().size() > typeParamIdx) { typeParamType = exactTypeParams->Params().at(typeParamIdx); } else { typeParamType = typeAliasNode->TypeParams()->Params().at(typeParamIdx)->DefaultType(); diff --git a/ets2panda/checker/ets/wideningConverter.h b/ets2panda/checker/ets/wideningConverter.h index 794fd9d807924d7330cbe6841d7861b48cc4ad28..6d7f4088f7f7eda2258cf3fb3926d9a32def6ebb 100644 --- a/ets2panda/checker/ets/wideningConverter.h +++ b/ets2panda/checker/ets/wideningConverter.h @@ -30,14 +30,11 @@ public: return; } - if (!Source()->HasTypeFlag(TypeFlag::CONSTANT)) { - ApplyGlobalWidening(); - } else { - ApplyConstWidening(); - } + ApplyGlobalWidening(); } private: + // NOTE(dkofanov): Deprecated operations on 'char' #28006 static constexpr TypeFlag WIDENABLE_TO_SHORT = TypeFlag::BYTE; static constexpr TypeFlag WIDENABLE_TO_CHAR = TypeFlag::BYTE; static constexpr TypeFlag WIDENABLE_TO_INT = TypeFlag::CHAR | TypeFlag::SHORT | WIDENABLE_TO_SHORT; @@ -45,42 +42,10 @@ private: static constexpr TypeFlag WIDENABLE_TO_FLOAT = TypeFlag::LONG | WIDENABLE_TO_LONG; static constexpr TypeFlag WIDENABLE_TO_DOUBLE = TypeFlag::FLOAT | WIDENABLE_TO_FLOAT; - void ApplyConstWidening() - { - switch (ETSChecker::ETSChecker::ETSType(Target())) { - case TypeFlag::SHORT: { - ApplyWidening(WIDENABLE_TO_SHORT); - break; - } - case TypeFlag::CHAR: { - ApplyWidening(WIDENABLE_TO_CHAR); - break; - } - case TypeFlag::INT: { - ApplyWidening(WIDENABLE_TO_INT); - break; - } - case TypeFlag::LONG: { - ApplyWidening(WIDENABLE_TO_LONG); - break; - } - case TypeFlag::FLOAT: { - ApplyWidening(WIDENABLE_TO_FLOAT); - break; - } - case TypeFlag::DOUBLE: { - ApplyWidening(WIDENABLE_TO_DOUBLE); - break; - } - default: { - break; - } - } - } - void ApplyGlobalWidening() { switch (ETSChecker::ETSChecker::ETSType(Target())) { + // NOTE(dkofanov): Deprecated operations on 'char' #28006 case TypeFlag::CHAR: { ApplyGlobalWidening(WIDENABLE_TO_CHAR); break; @@ -121,31 +86,32 @@ private: ES2PANDA_ASSERT(Relation()->GetNode()); switch (ETSChecker::ETSChecker::ETSType(Source())) { case TypeFlag::BYTE: { - Relation()->GetNode()->SetTsType(Checker()->GlobalByteType()); + Relation()->GetNode()->SetTsType(Checker()->GlobalByteBuiltinType()); break; } case TypeFlag::SHORT: { - Relation()->GetNode()->SetTsType(Checker()->GlobalShortType()); + Relation()->GetNode()->SetTsType(Checker()->GlobalShortBuiltinType()); break; } - case TypeFlag::CHAR: { - Relation()->GetNode()->SetTsType(Checker()->GlobalCharType()); + case TypeFlag::INT: { + Relation()->GetNode()->SetTsType(Checker()->GlobalIntBuiltinType()); break; } - case TypeFlag::INT: { - Relation()->GetNode()->SetTsType(Checker()->GlobalIntType()); + // NOTE(dkofanov): Deprecated operations on 'char' #28006 + case TypeFlag::CHAR: { + Relation()->GetNode()->SetTsType(Checker()->GlobalCharBuiltinType()); break; } case TypeFlag::LONG: { - Relation()->GetNode()->SetTsType(Checker()->GlobalLongType()); + Relation()->GetNode()->SetTsType(Checker()->GlobalLongBuiltinType()); break; } case TypeFlag::FLOAT: { - Relation()->GetNode()->SetTsType(Checker()->GlobalFloatType()); + Relation()->GetNode()->SetTsType(Checker()->GlobalFloatBuiltinType()); break; } case TypeFlag::DOUBLE: { - Relation()->GetNode()->SetTsType(Checker()->GlobalDoubleType()); + Relation()->GetNode()->SetTsType(Checker()->GlobalDoubleBuiltinType()); break; } default: { @@ -156,62 +122,6 @@ private: Relation()->Result(true); } - - template - void ApplyWidening(TypeFlag flag) - { - if (!Source()->HasTypeFlag(flag)) { - return; - } - - switch (ETSChecker::ETSChecker::ETSType(Source())) { - case TypeFlag::BYTE: { - ApplyWidening(); - break; - } - case TypeFlag::CHAR: { - ApplyWidening(); - break; - } - case TypeFlag::SHORT: { - ApplyWidening(); - break; - } - case TypeFlag::INT: { - ApplyWidening(); - break; - } - case TypeFlag::LONG: { - ApplyWidening(); - break; - } - case TypeFlag::FLOAT: { - ApplyWidening(); - break; - } - case TypeFlag::DOUBLE: { - ApplyWidening(); - break; - } - default: { - return; - } - } - Relation()->Result(true); - } - - template - void ApplyWidening() - { - using SType = typename SourceType::UType; - using TType = typename TargetType::UType; - SType value = reinterpret_cast(Source())->GetValue(); - - if (!Relation()->OnlyCheckWidening()) { - ES2PANDA_ASSERT(Relation()->GetNode()); - Relation()->GetNode()->SetTsType(Checker()->Allocator()->New(static_cast(value))); - } - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index 95f65a54bb3774b404092e6be1cefd35534e21c7..7fcbc2e9d905ac4dee37558f8e74a2cdf537f4a7 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -154,9 +154,10 @@ void DestructuringContext::HandleAssignmentPattern(ir::AssignmentExpression *ass if (!checker_->HasStatus(CheckerStatus::IN_CONST_CONTEXT)) { defaultType = checker_->GetBaseTypeOfLiteralType(defaultType); } - + ES2PANDA_ASSERT(defaultType != nullptr); if (validateDefault && assignmentPattern->Right()->IsObjectExpression() && assignmentPattern->Left()->IsObjectPattern()) { + ES2PANDA_ASSERT(defaultType != nullptr); ValidateObjectLiteralType(defaultType->AsObjectType(), assignmentPattern->Left()->AsObjectPattern()); } @@ -201,6 +202,7 @@ void DestructuringContext::HandleAssignmentPattern(ir::AssignmentExpression *ass void ArrayDestructuringContext::ValidateInferredType() { + ES2PANDA_ASSERT(inferredType_ != nullptr); if (!inferredType_->IsArrayType() && !inferredType_->IsUnionType() && (!inferredType_->IsObjectType() || !inferredType_->AsObjectType()->IsTupleType())) { checker_->ThrowTypeError( @@ -328,8 +330,10 @@ Type *ArrayDestructuringContext::CreateTupleTypeForRest(TupleType *tuple) util::StringView memberIndex = util::Helpers::ToStringView(checker_->Allocator(), iterIndex); auto *memberVar = varbinder::Scope::CreateVar(checker_->Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY, nullptr); + ES2PANDA_ASSERT(memberVar != nullptr); memberVar->SetTsType(tupleElementType); elementFlags.push_back(memberFlag); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(memberVar); index_++; @@ -528,6 +532,7 @@ void ArrayDestructuringContext::Start() void ObjectDestructuringContext::ValidateInferredType() { + ES2PANDA_ASSERT(inferredType_ != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) if (!inferredType_->IsObjectType()) { return; @@ -557,13 +562,16 @@ Type *ObjectDestructuringContext::CreateObjectTypeForRest(ObjectType *objType) if (!it->HasFlag(varbinder::VariableFlags::INFERRED_IN_PATTERN)) { auto *memberVar = varbinder::Scope::CreateVar(checker_->Allocator(), it->Name(), varbinder::VariableFlags::NONE, nullptr); + ES2PANDA_ASSERT(memberVar != nullptr); memberVar->SetTsType(it->TsType()); memberVar->AddFlag(it->Flags()); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(memberVar); } } Type *returnType = checker_->Allocator()->New(desc); + ES2PANDA_ASSERT(returnType != nullptr); returnType->AsObjectType()->AddObjectFlag(ObjectFlags::RESOLVED_MEMBERS); return returnType; } diff --git a/ets2panda/checker/ts/function.cpp b/ets2panda/checker/ts/function.cpp index e4419c3f8c3e31d2890a36cf00d8249525e94ec9..7b0634260ae6807f7d3a0a5ed3871690ee83a8db 100644 --- a/ets2panda/checker/ts/function.cpp +++ b/ets2panda/checker/ts/function.cpp @@ -54,7 +54,7 @@ Type *TSChecker::HandleFunctionReturn(ir::ScriptFunction *func) if (func->IsArrow() && func->Body()->IsExpression()) { ElaborateElementwise(returnType, func->Body()->AsExpression(), func->Body()->Start()); } - + ES2PANDA_ASSERT(returnType != nullptr); if (returnType->IsNeverType()) { ThrowTypeError("A function returning 'never' cannot have a reachable end point.", func->ReturnTypeAnnotation()->Start()); @@ -149,13 +149,15 @@ Type *TSChecker::CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpressio return inferredType; } - TupleType *newTuple = - inferredTuple->Instantiate(Allocator(), Relation(), GetGlobalTypesHolder())->AsObjectType()->AsTupleType(); + auto initTuple = inferredTuple->Instantiate(Allocator(), Relation(), GetGlobalTypesHolder()); + ES2PANDA_ASSERT(initTuple != nullptr); + TupleType *newTuple = initTuple->AsObjectType()->AsTupleType(); for (uint32_t index = inferredTuple->FixedLength(); index < arrayPattern->Elements().size(); index++) { util::StringView memberIndex = util::Helpers::ToStringView(Allocator(), index); varbinder::LocalVariable *newMember = varbinder::Scope::CreateVar( Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY | varbinder::VariableFlags::OPTIONAL, nullptr); + ES2PANDA_ASSERT(newMember != nullptr); newMember->SetTsType(GlobalAnyType()); newTuple->AddProperty(newMember); } @@ -193,6 +195,7 @@ Type *TSChecker::CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpress varbinder::LocalVariable *newProp = varbinder::Scope::CreateVar( Allocator(), prop->Key()->AsIdentifier()->Name(), varbinder::VariableFlags::PROPERTY | varbinder::VariableFlags::OPTIONAL, nullptr); + ES2PANDA_ASSERT(newProp != nullptr); newProp->SetTsType(GetBaseTypeOfLiteralType(CheckTypeCached(assignmentPattern->Right()))); newObject->AddProperty(newProp); } @@ -246,6 +249,7 @@ ReturnedVariable TSChecker::CheckFunctionAssignmentPatternParameter(ir::Assignme util::UString pn(ss.str(), Allocator()); varbinder::LocalVariable *patternVar = varbinder::Scope::CreateVar(Allocator(), pn.View(), varbinder::VariableFlags::NONE, param); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(paramType); patternVar->AddFlag(varbinder::VariableFlags::OPTIONAL); return {patternVar->AsLocalVariable(), nullptr, true}; @@ -264,6 +268,7 @@ std::tuple TSCheck if (typeAnnotation != nullptr) { typeAnnotation->Check(this); restType = typeAnnotation->GetType(this); + ES2PANDA_ASSERT(restType != nullptr); if (!restType->IsArrayType()) { ThrowTypeError("A rest parameter must be of an array type", param->Start()); } @@ -315,6 +320,7 @@ std::tuple TSCheck auto destructuringContext = ArrayDestructuringContext({this, param->AsArrayPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(destructuringContext.InferredType()); return {patternVar->AsLocalVariable(), nullptr, false}; } @@ -337,6 +343,7 @@ std::tuple TSCheck auto destructuringContext = ObjectDestructuringContext( {this, param->AsObjectPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(destructuringContext.InferredType()); return {patternVar->AsLocalVariable(), nullptr, false}; } @@ -386,6 +393,7 @@ std::tuple TSCheck if (cache) { Type *placeholder = Allocator()->New(GlobalAnyType()); + ES2PANDA_ASSERT(placeholder != nullptr); placeholder->SetVariable(std::get<0>(result)); param->SetTsType(placeholder); } @@ -396,6 +404,7 @@ std::tuple TSCheck void TSChecker::CheckFunctionParameterDeclarations(const ArenaVector ¶ms, SignatureInfo *signatureInfo) { + ES2PANDA_ASSERT(signatureInfo != nullptr); signatureInfo->restVar = nullptr; signatureInfo->minArgCount = 0; @@ -590,6 +599,7 @@ void TSChecker::InferFunctionDeclarationType(const varbinder::FunctionDecl *decl } Signature *overloadSignature = Allocator()->New(overloadSignatureInfo, returnType, func); + ES2PANDA_ASSERT(descWithOverload != nullptr); descWithOverload->callSignatures.push_back(overloadSignature); } @@ -601,14 +611,16 @@ void TSChecker::InferFunctionDeclarationType(const varbinder::FunctionDecl *decl if (descWithOverload->callSignatures.empty()) { Type *funcType = CreateFunctionTypeWithSignature(bodyCallSignature); + ES2PANDA_ASSERT(funcType != nullptr); funcType->SetVariable(funcVar); funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(bodyCallSignature != nullptr); bodyCallSignature->SetReturnType(HandleFunctionReturn(bodyDeclaration)); if (!descWithOverload->callSignatures.empty()) { Type *funcType = Allocator()->New(descWithOverload); + ES2PANDA_ASSERT(funcType != nullptr); funcType->SetVariable(funcVar); funcVar->SetTsType(funcType); diff --git a/ets2panda/checker/ts/helpers.cpp b/ets2panda/checker/ts/helpers.cpp index 9c2455f558c2cf064c93663fee5cd0ffa05bf9b4..9b5abf6d2902b1da9ca71b0877115008f6afa0ac 100644 --- a/ets2panda/checker/ts/helpers.cpp +++ b/ets2panda/checker/ts/helpers.cpp @@ -59,7 +59,7 @@ Type *TSChecker::GetBaseTypeOfLiteralType(Type *type) if (HasStatus(CheckerStatus::KEEP_LITERAL_TYPE)) { return type; } - + ES2PANDA_ASSERT(type != nullptr); if (type->IsStringLiteralType()) { return GlobalStringType(); } @@ -382,6 +382,7 @@ void TSChecker::GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl) { ir::AstNode *declaration = FindAncestorUntilGivenType(decl->Node(), ir::AstNodeType::SCRIPT_FUNCTION); + ES2PANDA_ASSERT(declaration != nullptr); if (declaration->IsIdentifier()) { auto *ident = declaration->AsIdentifier(); if (ident->TypeAnnotation() != nullptr) { @@ -499,6 +500,7 @@ Type *TSChecker::GetTypeFromClassOrInterfaceReference([[maybe_unused]] ir::TSTyp if (resolvedType == nullptr) { ObjectDescriptor *desc = Allocator()->New(Allocator()); resolvedType = Allocator()->New(Allocator(), var->Name(), desc); + ES2PANDA_ASSERT(resolvedType != nullptr); resolvedType->SetVariable(var); var->SetTsType(resolvedType); } diff --git a/ets2panda/checker/ts/object.cpp b/ets2panda/checker/ts/object.cpp index d0b36c61dc21745bb7fb0994b1f9c0f222731dd9..0c9e3c25c32a4186ee55c6746a6e212a05cedbc7 100644 --- a/ets2panda/checker/ts/object.cpp +++ b/ets2panda/checker/ts/object.cpp @@ -139,6 +139,7 @@ void TSChecker::ResolveUnionTypeMembers(UnionType *type) } } + ES2PANDA_ASSERT(desc != nullptr); desc->callSignatures = callSignatures; desc->constructSignatures = constructSignatures; @@ -151,6 +152,7 @@ void TSChecker::ResolveUnionTypeMembers(UnionType *type) } ObjectType *mergedType = Allocator()->New(desc); + ES2PANDA_ASSERT(mergedType != nullptr); mergedType->AddObjectFlag(ObjectFlags::RESOLVED_MEMBERS); type->SetMergedObjectType(mergedType); } @@ -333,6 +335,7 @@ varbinder::Variable *TSChecker::GetPropertyOfUnionType(UnionType *type, const ut } varbinder::Variable *syntheticProp = varbinder::Scope::CreateVar(Allocator(), name, flags, nullptr); + ES2PANDA_ASSERT(syntheticProp != nullptr); syntheticProp->SetTsType(CreateUnionType(std::move(collectedTypes))); type->CachedSyntheticProperties().insert({name, syntheticProp}); return syntheticProp; @@ -386,10 +389,12 @@ IndexInfo *TSChecker::GetApplicableIndexInfo(Type *type, Type *indexType) Type *TSChecker::GetPropertyTypeForIndexType(Type *type, Type *indexType) { + ES2PANDA_ASSERT(type != nullptr); if (type->IsArrayType()) { return type->AsArrayType()->ElementType(); } + ES2PANDA_ASSERT(indexType != nullptr); if (indexType->HasTypeFlag(TypeFlag::STRING_LITERAL | TypeFlag::NUMBER_LITERAL)) { varbinder::Variable *prop = nullptr; @@ -453,6 +458,7 @@ ArenaVector TSChecker::GetBaseTypes(InterfaceType *type) for (auto *extends : declaration->Extends()) { Type *baseType = extends->Expr()->GetType(this); + ES2PANDA_ASSERT(baseType != nullptr); if (!baseType->HasTypeFlag(TypeFlag::OBJECT | TypeFlag::NON_PRIMITIVE | TypeFlag::ANY)) { ThrowTypeError( "An interface can only extend an object type or intersection of object types with statically " diff --git a/ets2panda/checker/ts/typeCreation.cpp b/ets2panda/checker/ts/typeCreation.cpp index c40b8b1ed750ee4e21a47d61006ca2b9620b0bc2..08b9a7ae9bcba3a14be96f43d24ed6c717601b50 100644 --- a/ets2panda/checker/ts/typeCreation.cpp +++ b/ets2panda/checker/ts/typeCreation.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -125,6 +125,7 @@ Type *TSChecker::CreateUnionType(ArenaVector &&constituentTypes) Type *TSChecker::CreateObjectTypeWithCallSignature(Signature *callSignature) { auto *objType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(objType != nullptr); objType->AddCallSignature(callSignature); return objType; } @@ -132,6 +133,7 @@ Type *TSChecker::CreateObjectTypeWithCallSignature(Signature *callSignature) Type *TSChecker::CreateObjectTypeWithConstructSignature(Signature *constructSignature) { auto *objType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(objType != nullptr); objType->AddConstructSignature(constructSignature); return objType; } @@ -139,6 +141,7 @@ Type *TSChecker::CreateObjectTypeWithConstructSignature(Signature *constructSign Type *TSChecker::CreateFunctionTypeWithSignature(Signature *callSignature) { auto *funcObjType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(funcObjType != nullptr); funcObjType->AddCallSignature(callSignature); return funcObjType; } @@ -146,6 +149,7 @@ Type *TSChecker::CreateFunctionTypeWithSignature(Signature *callSignature) Type *TSChecker::CreateConstructorTypeWithSignature(Signature *constructSignature) { auto *constructObjType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(constructObjType != nullptr); constructObjType->AddConstructSignature(constructSignature); return constructObjType; } diff --git a/ets2panda/checker/typeChecker/TypeChecker.cpp b/ets2panda/checker/typeChecker/TypeChecker.cpp index b9977ba38af132168115304b4eba1ef966c98192..aeb0e9e5f51bdbc79f0e6346457e0b3e1810c7ae 100644 --- a/ets2panda/checker/typeChecker/TypeChecker.cpp +++ b/ets2panda/checker/typeChecker/TypeChecker.cpp @@ -18,14 +18,6 @@ namespace ark::es2panda::checker { -void ETSTypeChecker::VisitArrowFunctionExpression(ir::ArrowFunctionExpression *node) -{ - Iterate(node); - if (!node->TsType()->IsETSObjectType()) { - LogError(diagnostic::INFER_FAIL_ON_LAMBDA, {node->TsType()}, node->Start()); - } -} - bool RunTypeChecker(Checker *checker, ScriptExtension ext, ir::AstNode *node) { switch (ext) { diff --git a/ets2panda/checker/typeChecker/TypeChecker.h b/ets2panda/checker/typeChecker/TypeChecker.h index 802f884a5c6a5d19d8dd23ba0a4add9ff72346b7..864753b273ad8713ffc5957a7b5456f8c59b6881 100644 --- a/ets2panda/checker/typeChecker/TypeChecker.h +++ b/ets2panda/checker/typeChecker/TypeChecker.h @@ -50,9 +50,6 @@ private: class ETSTypeChecker : public TypeChecker { public: explicit ETSTypeChecker(Checker *checker) : TypeChecker(checker) {} - -private: - void VisitArrowFunctionExpression(ir::ArrowFunctionExpression *node) override; }; class JSTypeChecker : public TypeChecker { diff --git a/ets2panda/checker/types/ets/byteType.cpp b/ets2panda/checker/types/ets/byteType.cpp index 44537a4f5469bd9f109de7b02dc32816a05cf909..e69f7aff80e99cd986e89b4a4b5dc09b98f17023 100644 --- a/ets2panda/checker/types/ets/byteType.cpp +++ b/ets2panda/checker/types/ets/byteType.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 @@ -15,8 +15,9 @@ #include "byteType.h" +#include "checker/ETSchecker.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingConverter.h" +#include "checker/types/ets/etsObjectType.h" namespace ark::es2panda::checker { void ByteType::Identical(TypeRelation *relation, Type *other) @@ -26,13 +27,7 @@ void ByteType::Identical(TypeRelation *relation, Type *other) } } -void ByteType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) -{ - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); -} +void ByteType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) {} bool ByteType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { @@ -57,38 +52,9 @@ void ByteType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::SHORT | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::CHAR)) { - conversion::WideningNarrowingPrimitive(relation, this, target->AsCharType()); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/byteType.h b/ets2panda/checker/types/ets/byteType.h index a92f1f637d46d3611ba579ca23e7acc4cd63d9ca..a622ebc4e27e1b8bf50171ba47e1b301816d9c7e 100644 --- a/ets2panda/checker/types/ets/byteType.h +++ b/ets2panda/checker/types/ets/byteType.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 @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BYTE; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 044657176938dfc8ba8914c7faeea14277b7dc57..43bbec66cd258fa3b35bd307b86ec6a804ea5725 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 @@ -16,7 +16,7 @@ #include "charType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/ets/wideningConverter.h" namespace ark::es2panda::checker { void CharType::Identical(TypeRelation *relation, Type *other) @@ -28,20 +28,12 @@ void CharType::Identical(TypeRelation *relation, Type *other) void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } 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; @@ -62,43 +54,9 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, 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); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/charType.h b/ets2panda/checker/types/ets/charType.h index 9ddb9054ff1173910324d71e2ccdb1a65e3854e6..793a64ea4ed52a5ed44f86b1a6439623f9e55375 100644 --- a/ets2panda/checker/types/ets/charType.h +++ b/ets2panda/checker/types/ets/charType.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 @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_CHAR; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != '\0'}; - } - private: UType value_ {'\0'}; }; diff --git a/ets2panda/checker/types/ets/doubleType.cpp b/ets2panda/checker/types/ets/doubleType.cpp index 91477c19e4e6d3e13e3bd32caa00fe15102b22c2..ad58d7bc8c9a5470fb94e12a8b57660b0dd10813 100644 --- a/ets2panda/checker/types/ets/doubleType.cpp +++ b/ets2panda/checker/types/ets/doubleType.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 @@ -28,9 +28,6 @@ void DoubleType::Identical(TypeRelation *relation, Type *other) void DoubleType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } @@ -56,34 +53,9 @@ void DoubleType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | - TypeFlag::FLOAT)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/doubleType.h b/ets2panda/checker/types/ets/doubleType.h index e7e7dde792299f53ba775bea89d0a674dab337d2..fa3d5de326b61b66c9a6eaa2f745f8d82e7044a4 100644 --- a/ets2panda/checker/types/ets/doubleType.h +++ b/ets2panda/checker/types/ets/doubleType.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 @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_DOUBLE; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/etsAnyType.cpp b/ets2panda/checker/types/ets/etsAnyType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1e5307545c902a90b0062e2aa9fa97ff2b5abda --- /dev/null +++ b/ets2panda/checker/types/ets/etsAnyType.cpp @@ -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. + */ + +#include "etsAnyType.h" +#include + +#include "checker/ETSchecker.h" +#include "checker/ets/conversion.h" +#include "etsTypeParameter.h" + +namespace ark::es2panda::checker { +void ETSAnyType::Identical(TypeRelation *relation, Type *other) +{ + relation->Result(other->IsETSAnyType()); +} + +void ETSAnyType::AssignmentTarget(TypeRelation *relation, Type *source) +{ + if (!source->IsETSPrimitiveType()) { + relation->Result(true); + return; + } + + if (relation->ApplyBoxing()) { + relation->Result(true); + } +} + +bool ETSAnyType::AssignmentSource(TypeRelation *relation, Type *target) +{ + Identical(relation, target); + return relation->IsTrue(); +} + +void ETSAnyType::Compare([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *other) +{ + ES2PANDA_UNREACHABLE(); +} + +void ETSAnyType::Cast(TypeRelation *relation, Type *target) +{ + if (!relation->InCastingContext()) { + Identical(relation, target); + return; + } + + if (!target->IsETSPrimitiveType()) { + relation->Result(true); + return; + } + + if (relation->ApplyUnboxing()) { + auto *const boxedTarget = relation->GetChecker()->AsETSChecker()->MaybeBoxInRelation(target); + ES2PANDA_ASSERT(boxedTarget != nullptr); + conversion::Unboxing(relation, boxedTarget->AsETSObjectType()); + relation->Result(true); + } +} + +void ETSAnyType::CastTarget(TypeRelation *relation, [[maybe_unused]] Type *source) +{ + AssignmentTarget(relation, source); +} + +void ETSAnyType::IsSubtypeOf(TypeRelation *relation, Type *target) +{ + Identical(relation, target); +} + +void ETSAnyType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + relation->Result(!source->IsETSPrimitiveType()); +} + +void ETSAnyType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const +{ + ss << (IsRelaxed() ? compiler::Signatures::ANY : compiler::Signatures::ANY_TYPE_NAME); +} + +void ETSAnyType::ToAssemblerType(std::stringstream &ss) const +{ + ss << compiler::Signatures::BUILTIN_OBJECT; +} + +TypeFacts ETSAnyType::GetTypeFacts() const +{ + return TypeFacts::NONE; +} + +void ETSAnyType::ToDebugInfoType(std::stringstream &ss) const +{ + ss << ETSObjectType::NameToDescriptor(compiler::Signatures::BUILTIN_OBJECT); +} + +Type *ETSAnyType::Instantiate(ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, + [[maybe_unused]] GlobalTypesHolder *globalTypes) +{ + return allocator->New(isRelaxed_); +} +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/dynamic/dynamicCall.h b/ets2panda/checker/types/ets/etsAnyType.h similarity index 33% rename from ets2panda/checker/ets/dynamic/dynamicCall.h rename to ets2panda/checker/types/ets/etsAnyType.h index b4de6cfd0a0b7bcab4e9cdace2a8997c5eff1db9..8e111f75ed5379e3b2af66cc71c9b420ba06bcd3 100644 --- a/ets2panda/checker/ets/dynamic/dynamicCall.h +++ b/ets2panda/checker/types/ets/etsAnyType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 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 @@ -12,49 +12,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_ANY_TYPE_H +#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_ANY_TYPE_H -#ifndef ARK_DYNAMICCALLINFO_H -#define ARK_DYNAMICCALLINFO_H - -#include - -#include "varbinder/ETSBinder.h" -#include "ir/expression.h" +#include "checker/types/type.h" +#include "ir/astNode.h" namespace ark::es2panda::checker { - -class DynamicCall { - using NameHolder = ArenaVector; - +class ETSAnyType : public Type { public: - struct Result { - const ir::AstNode *obj; - const NameHolder name; // NOLINT(readability-identifier-naming) - }; - - /** - * Resolve callee - * @param varbinder - * @param callee expression used to call method - * @return callee and name from which should be used to produce call - */ - static Result ResolveCall(const varbinder::ETSBinder *varbinder, const ir::Expression *callee); - static bool IsByValue(const varbinder::ETSBinder *varbinder, const ir::Expression *callee) + explicit ETSAnyType(bool isRelaxed) : Type(TypeFlag::ETS_ANY), isRelaxed_(isRelaxed) {} + + bool IsRelaxed() const { - return ResolveCall(varbinder, callee).name.empty(); + return isRelaxed_; } - /** - * Example: A[0].C.D => return: A[0], name: ".C.D" - * @param expr member expression - * @param name to store result - * @return object with remaining member expression - */ - static Result SqueezeExpr(ArenaAllocator *allocator, const ir::MemberExpression *expr); + void Identical(TypeRelation *relation, Type *other) override; + void AssignmentTarget(TypeRelation *relation, Type *source) override; + bool AssignmentSource(TypeRelation *relation, Type *target) override; + void Compare(TypeRelation *relation, Type *other) override; + void Cast(TypeRelation *relation, Type *target) override; + void CastTarget(TypeRelation *relation, Type *source) override; + void IsSubtypeOf(TypeRelation *relation, Type *target) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; + void ToString(std::stringstream &ss, bool precise) const override; + void ToAssemblerType(std::stringstream &ss) const override; + void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; + + TypeFacts GetTypeFacts() const override; + + Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; private: - static const ir::Expression *SqueezeExpr(const ir::MemberExpression *expr, NameHolder &name); + bool isRelaxed_; }; - } // namespace ark::es2panda::checker -#endif // ARK_DYNAMICCALLINFO_H + +#endif diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 9325edf156836da28d580ec9811d7ab1d8555015..79d9cc398389767328cfa2ccc2d9a51868e91f81 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 @@ -82,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)) { @@ -93,7 +111,7 @@ void ETSArrayType::AssignmentTarget(TypeRelation *relation, Type *source) source->AsETSArrayType()->ElementType()->IsETSPrimitiveOrEnumType()) { return; } - relation->IsAssignableTo(source->AsETSArrayType()->ElementType(), element_); + relation->IsSupertypeOf(element_, source->AsETSArrayType()->ElementType()); } } diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index 78cceccd5e2018c57754eaacb687047a0b3b06ea..c9dd00904fffa7d09046075fde8e94a49ff87db8 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -38,11 +38,6 @@ public: element_ = element; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; @@ -51,6 +46,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.cpp b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp index 46308e495d546fec72639801ef3c8588619a8f9a..bc2a83fca736a1b978110d1655b64d2fa954bab3 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp @@ -39,6 +39,15 @@ void ETSAsyncFuncReturnType::Identical(TypeRelation *relation, Type *other) relation->Result(false); } +void ETSAsyncFuncReturnType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + GetPromiseTypeArg()->IsSupertypeOf(relation, source); + if (relation->IsTrue()) { + return; + } + promiseType_->IsSupertypeOf(relation, source); +} + bool ETSAsyncFuncReturnType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { return false; @@ -47,9 +56,6 @@ bool ETSAsyncFuncReturnType::AssignmentSource([[maybe_unused]] TypeRelation *rel void ETSAsyncFuncReturnType::AssignmentTarget(TypeRelation *relation, Type *source) { relation->IsAssignableTo(source, promiseType_) || relation->IsAssignableTo(source, GetPromiseTypeArg()); - if (relation->IsTrue() && !source->IsETSObjectType() && relation->ApplyBoxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddBoxingFlagInRelation(relation, source); - } } void ETSAsyncFuncReturnType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index e1ede4842b6fe35b3dc6ac4d712bf8e26ed064f2..d6b4d58b22b090e2bb0e2202a5d51510d5ead510 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) @@ -33,6 +33,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; diff --git a/ets2panda/checker/types/ets/etsAwaitedType.cpp b/ets2panda/checker/types/ets/etsAwaitedType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0adb9a37cd64d0da09e1571d1921f14a54700993 --- /dev/null +++ b/ets2panda/checker/types/ets/etsAwaitedType.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "etsAwaitedType.h" + +namespace ark::es2panda::checker { +void ETSAwaitedType::ToString(std::stringstream &ss, bool precise) const +{ + ss << "Awaited<"; + GetUnderlying()->ToString(ss, precise); + ss << ">"; +} + +void ETSAwaitedType::Identical(TypeRelation *relation, Type *other) +{ + if (other->IsETSAwaitedType()) { + relation->IsIdenticalTo(GetUnderlying(), other->AsETSAwaitedType()->GetUnderlying()); + } +} + +bool ETSAwaitedType::AssignmentSource(TypeRelation *relation, Type *target) +{ + return relation->IsSupertypeOf(target, this); +} + +void ETSAwaitedType::AssignmentTarget(TypeRelation *relation, Type *source) +{ + relation->IsSupertypeOf(this, source); +} + +void ETSAwaitedType::Cast(TypeRelation *relation, Type *target) +{ + if (relation->IsSupertypeOf(target, this)) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + return; + } + relation->Result(relation->InCastingContext()); +} + +void ETSAwaitedType::CastTarget(TypeRelation *relation, Type *source) +{ + if (relation->IsSupertypeOf(this, source)) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + return; + } + relation->Result(relation->InCastingContext()); +} + +void ETSAwaitedType::IsSupertypeOf(TypeRelation *relation, [[maybe_unused]] Type *source) +{ + relation->Result(false); +} + +void ETSAwaitedType::IsSubtypeOf(TypeRelation *relation, Type *target) +{ + relation->Result(false); + if (target->IsETSAwaitedType()) { + relation->IsSupertypeOf(target->AsETSAwaitedType()->GetUnderlying(), GetUnderlying()); + } +} +ETSAwaitedType *ETSAwaitedType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, + [[maybe_unused]] TypeRelation *relation, + [[maybe_unused]] GlobalTypesHolder *globalTypes) +{ + return allocator->New( + GetUnderlying()->Instantiate(allocator, relation, globalTypes)->AsETSTypeParameter()); +} + +Type *ETSAwaitedType::Substitute([[maybe_unused]] TypeRelation *relation, const Substitution *substitution) +{ + auto *substituted = GetUnderlying()->Substitute(relation, substitution); + auto *checker = relation->GetChecker()->AsETSChecker(); + if (substituted == GetUnderlying()) { + return this; + } + + return checker->HandleAwaitedUtilityType(substituted); +} + +void ETSAwaitedType::ToAssemblerType(std::stringstream &ss) const +{ + GetUnderlying()->ToAssemblerTypeWithRank(ss); +} + +void ETSAwaitedType::ToDebugInfoType(std::stringstream &ss) const +{ + GetUnderlying()->ToDebugInfoType(ss); +} + +void ETSAwaitedType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) +{ + relation->CheckVarianceRecursively(GetUnderlying(), + relation->TransferVariant(varianceFlag, VarianceFlag::COVARIANT)); +} +} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/ets/etsDynamicType.h b/ets2panda/checker/types/ets/etsAwaitedType.h similarity index 38% rename from ets2panda/checker/types/ets/etsDynamicType.h rename to ets2panda/checker/types/ets/etsAwaitedType.h index eea79b4fb92a6ea1b1275bdfc17aa8c1a845ad9c..e5415da37cd6a822fb7a0ca5732d460faf0b394d 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.h +++ b/ets2panda/checker/types/ets/etsAwaitedType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-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,60 +13,51 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_DYNAMIC_TYPE_H -#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_DYNAMIC_TYPE_H +#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_AWAITED_TYPE_H +#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_AWAITED_TYPE_H -#include "checker/types/ets/etsObjectType.h" +#include "checker/types/ets/etsTypeParameter.h" +#include "checker/types/type.h" namespace ark::es2panda::checker { -class ETSDynamicType : public ETSObjectType { - static constexpr auto NAME = 0; - static constexpr auto ASSEMBLER_NAME = 1; - static constexpr auto LANGUAGE = 2; - static constexpr auto DECL_NODE = 0; - static constexpr auto FLAGS = 1; - static constexpr auto RELATION = 2; - +class ETSAwaitedType : public Type { public: - explicit ETSDynamicType(ArenaAllocator *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, - std::get(info))), - propertiesCache_ {allocator->Adapter()}, - lang_(std::get(label)), - hasDecl_(hasDecl) + ETSAwaitedType() = delete; + ~ETSAwaitedType() override = default; + + NO_COPY_SEMANTIC(ETSAwaitedType); + NO_MOVE_SEMANTIC(ETSAwaitedType); + + explicit ETSAwaitedType(ETSTypeParameter *tparam) : Type(TypeFlag::ETS_AWAITED), tparam_(tparam) {} + + ETSTypeParameter *GetUnderlying() const { - AddTypeFlag(TypeFlag::ETS_DYNAMIC_TYPE); + return tparam_; } - varbinder::LocalVariable *GetPropertyDynamic(const util::StringView &name, const ETSChecker *checker) const; + Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + + ETSAwaitedType *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, + GlobalTypesHolder *globalTypes) override; + + void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; + void IsSubtypeOf(TypeRelation *relation, Type *target) override; - es2panda::Language Language() const - { - return lang_; - } - - bool HasDecl() const - { - return hasDecl_; - } - - ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const override; + void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; + void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; - - static bool IsConvertible(Type const *target); + void ToDebugInfoType(std::stringstream &ss) const override; private: - mutable PropertyMap propertiesCache_; - es2panda::Language lang_; - bool hasDecl_; + ETSTypeParameter *const tparam_; }; + } // namespace ark::es2panda::checker #endif 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/etsBooleanType.cpp b/ets2panda/checker/types/ets/etsBooleanType.cpp index e3d661ea8d4435fc18891f6373dceb2ebff8bdcd..f19823daa2f3ab0f1dc703ee184a7708609884c5 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.cpp +++ b/ets2panda/checker/types/ets/etsBooleanType.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 @@ -26,14 +26,9 @@ void ETSBooleanType::Identical(TypeRelation *relation, Type *other) } } -void ETSBooleanType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) -{ - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } -} +void ETSBooleanType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) {} -bool ETSBooleanType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) +bool ETSBooleanType::AssignmentSource(TypeRelation *relation, Type *target) { if (relation->ApplyBoxing() && target->IsETSObjectType()) { relation->GetChecker()->AsETSChecker()->CheckBoxedSourceTypeAssignable(relation, this, target); diff --git a/ets2panda/checker/types/ets/etsBooleanType.h b/ets2panda/checker/types/ets/etsBooleanType.h index 421ae63e3b29b5ff3b070f1b25c482a73f8343ef..2bc7ccaddca17d8268de62ba33e7fbaa7a3aa371 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.h +++ b/ets2panda/checker/types/ets/etsBooleanType.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 @@ -51,11 +51,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BOOLEAN; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_}; - } - private: UType value_ {false}; }; diff --git a/ets2panda/checker/types/ets/etsDynamicFunctionType.h b/ets2panda/checker/types/ets/etsDynamicFunctionType.h deleted file mode 100644 index 77a3c5731b2a49305766413eb1db370c0a9635e2..0000000000000000000000000000000000000000 --- a/ets2panda/checker/types/ets/etsDynamicFunctionType.h +++ /dev/null @@ -1,54 +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. - */ - -#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_DYNAMIC_FUNCTION_TYPE_H -#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_DYNAMIC_FUNCTION_TYPE_H - -#include "checker/types/ets/etsFunctionType.h" -#include "checker/ETSchecker.h" - -namespace ark::es2panda::checker { - -class ETSDynamicFunctionType : public ETSFunctionType { -public: - explicit ETSDynamicFunctionType(ETSChecker *checker, util::StringView name, ArenaVector &&signatures, - Language lang) - : ETSFunctionType(checker, name, std::move(signatures)), lang_(lang) - { - AddTypeFlag(TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE); - } - - explicit ETSDynamicFunctionType(ETSChecker *checker, Signature *signature, Language lang) - : ETSFunctionType(checker, signature), lang_(lang) - { - AddTypeFlag(TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE); - } - - ETSDynamicFunctionType() = delete; - ~ETSDynamicFunctionType() override = default; - NO_COPY_SEMANTIC(ETSDynamicFunctionType); - NO_MOVE_SEMANTIC(ETSDynamicFunctionType); - - es2panda::Language Language() const - { - return lang_; - } - -private: - es2panda::Language lang_; -}; -} // namespace ark::es2panda::checker - -#endif /* ES2PANDA_COMPILER_CHECKER_TYPES_ETS_DYNAMIC_FUNCTION_TYPE_H */ diff --git a/ets2panda/checker/types/ets/etsDynamicType.cpp b/ets2panda/checker/types/ets/etsDynamicType.cpp deleted file mode 100644 index 3fb4c1392d36f4ec568982963c0b2cc247d00960..0000000000000000000000000000000000000000 --- a/ets2panda/checker/types/ets/etsDynamicType.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2021-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "etsDynamicType.h" -#include "checker/ETSchecker.h" -#include "checker/ets/conversion.h" -#include "checker/types/ets/etsDynamicFunctionType.h" - -namespace ark::es2panda::checker { - -varbinder::LocalVariable *ETSDynamicType::GetPropertyDynamic(const util::StringView &name, - const ETSChecker *checker) const -{ - auto it = propertiesCache_.find(name); - if (it != propertiesCache_.end()) { - return it->second; - } - - varbinder::LocalVariable *var = varbinder::Scope::CreateVar( - Allocator(), name, varbinder::VariableFlags::BUILTIN_TYPE, nullptr); - var->SetTsType(checker->GlobalBuiltinDynamicType(lang_)); - propertiesCache_.emplace(name, var); - - return var; -} - -void ETSDynamicType::AssignmentTarget(TypeRelation *relation, Type *source) -{ - if (hasDecl_) { - return ETSObjectType::AssignmentTarget(relation, source); - } - - if (relation->ApplyBoxing() && !relation->IsTrue() && IsConvertible(source)) { - relation->Result(true); - return; - } - - if (source->IsETSDynamicType()) { - relation->Result(true); - } -} - -bool ETSDynamicType::AssignmentSource(TypeRelation *relation, Type *target) -{ - if (hasDecl_) { - return ETSObjectType::AssignmentSource(relation, target); - } - - if (relation->ApplyUnboxing() && IsConvertible(target)) { - relation->Result(true); - return true; - } - - if (target->IsETSDynamicType()) { - relation->Result(true); - } - return relation->IsTrue(); -} - -void ETSDynamicType::Cast(TypeRelation *relation, Type *target) -{ - if (hasDecl_) { - return ETSObjectType::Cast(relation, target); - } - - if (relation->InCastingContext() || IsConvertible(target)) { - relation->Result(true); - return; - } - - conversion::Forbidden(relation); -} - -void ETSDynamicType::CastTarget(TypeRelation *relation, Type *source) -{ - if (hasDecl_) { - ETSObjectType::CastTarget(relation, source); - return; - } - - if (relation->InCastingContext() || IsConvertible(source)) { - relation->Result(true); - return; - } - - conversion::Forbidden(relation); -} - -bool ETSDynamicType::IsConvertible(Type const *target) -{ - return target->IsETSDynamicType() || target->IsETSObjectType() || target->IsETSArrayType() || - target->IsETSTupleType() || target->IsETSFunctionType() || - target->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC | checker::TypeFlag::ETS_BOOLEAN); -} - -ETSFunctionType *ETSDynamicType::CreateMethodTypeForProp(const util::StringView &name) const -{ - auto checker = GetRelation()->GetChecker()->AsETSChecker(); - return checker->CreateETSDynamicMethodType(name, {{}, Allocator()->Adapter()}, lang_); -} - -void ETSDynamicType::ToAssemblerType(std::stringstream &ss) const -{ - ss << compiler::Signatures::Dynamic::Type(lang_); -} - -} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 61d23b7cbf94ef87d12a88cce69cb24207f4cb97..233a403e0501e8a662fba2b7bd2ad9c056b0df62 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -15,11 +15,17 @@ #include "etsEnumType.h" +#include "checker/ETSchecker.h" #include "checker/ets/conversion.h" #include "checker/types/ets/etsUnionType.h" namespace ark::es2panda::checker { +Type *ETSEnumType::GetBaseEnumElementType(ETSChecker *checker) +{ + return checker->MaybeUnboxType(SuperType()->TypeArguments()[0]); +} + bool ETSStringEnumType::AssignmentSource(TypeRelation *relation, Type *target) { bool result = false; @@ -55,6 +61,7 @@ void ETSStringEnumType::Cast(TypeRelation *const relation, Type *const target) return; } if (target->IsETSStringType()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {this, target}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -64,6 +71,7 @@ void ETSStringEnumType::Cast(TypeRelation *const relation, Type *const target) void ETSStringEnumType::CastTarget(TypeRelation *relation, Type *source) { if (source->IsETSStringType()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {source, this}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -77,7 +85,7 @@ bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) if (target->AsETSObjectType()->IsGlobalETSObjectType() || target->AsETSObjectType()->Name() == compiler::Signatures::NUMERIC) { result = true; - } else if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { + } else if (target->IsBuiltinNumeric()) { result = true; relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } @@ -108,8 +116,8 @@ void ETSIntEnumType::Cast(TypeRelation *const relation, Type *const target) relation->Result(true); return; } - if (target->HasTypeFlag(TypeFlag::ETS_NUMERIC) || - (target->IsETSObjectType() && target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC))) { + if (target->HasTypeFlag(TypeFlag::ETS_NUMERIC) || target->IsBuiltinNumeric()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {this, target}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -118,15 +126,12 @@ void ETSIntEnumType::Cast(TypeRelation *const relation, Type *const target) void ETSIntEnumType::CastTarget(TypeRelation *relation, Type *source) { - if (source->IsIntType()) { - relation->Result(true); - return; - } - if (source->IsETSObjectType() && source->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { + if (source->IsIntType() || source->IsBuiltinNumeric()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {source, this}, relation->GetNode()->Start()); relation->Result(true); return; } conversion::Forbidden(relation); } -} // namespace ark::es2panda::checker \ No newline at end of file +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index a5c6bdf33d7a3e767413365b6105f75f9114285b..3005b78053a406f8ef707e2410d7d7cc090593a4 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -19,16 +19,24 @@ #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsObjectTypeConstants.h" #include "checker/types/typeFlag.h" +#include "ir/base/classProperty.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/expressions/memberExpression.h" namespace ark::es2panda::checker { class ETSEnumType : public ETSObjectType { public: - explicit ETSEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, - ir::AstNode *declNode, TypeRelation *relation) + // CC-OFFNXT(G.FUN.01-CPP) solid logic + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) + explicit ETSEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, + ir::AstNode *declNode, TypeRelation *relation, ETSObjectFlags const flag) : ETSObjectType(allocator, name, internalName, - std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)) + std::make_tuple(declNode, ETSObjectFlags::CLASS | flag, relation)), + memberNameToOrdinal_(allocator->Adapter()) { + InitElementsShortcuts(declNode->AsClassDefinition()); } NO_COPY_SEMANTIC(ETSEnumType); @@ -37,21 +45,86 @@ public: ETSEnumType() = delete; ~ETSEnumType() override = default; - static constexpr std::string_view const TO_STRING_METHOD_NAME {"toString"}; - static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; - static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; - static constexpr std::string_view const GET_VALUE_OF_METHOD_NAME {"getValueOf"}; - static constexpr std::string_view const FROM_VALUE_METHOD_NAME {"fromValue"}; - static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; - static constexpr std::string_view const GET_ORDINAL_METHOD_NAME {"getOrdinal"}; - static constexpr std::string_view const DOLLAR_GET_METHOD_NAME {"$_get"}; + static constexpr std::string_view TO_STRING_METHOD_NAME {"toString"}; + static constexpr std::string_view VALUE_OF_METHOD_NAME {"valueOf"}; + static constexpr std::string_view GET_NAME_METHOD_NAME {"getName"}; + static constexpr std::string_view GET_VALUE_OF_METHOD_NAME {"getValueOf"}; + static constexpr std::string_view FROM_VALUE_METHOD_NAME {"fromValue"}; + static constexpr std::string_view VALUES_METHOD_NAME {"values"}; + static constexpr std::string_view GET_ORDINAL_METHOD_NAME {"getOrdinal"}; + static constexpr std::string_view DOLLAR_GET_METHOD_NAME {"$_get"}; + + static constexpr std::string_view STRING_VALUES_ARRAY_NAME {"#StringValuesArray"}; + static constexpr std::string_view VALUES_ARRAY_NAME {"#ValuesArray"}; + static constexpr std::string_view NAMES_ARRAY_NAME {"#NamesArray"}; + + auto *Underlying() + { + ES2PANDA_ASSERT(membersValues_->TsType() != nullptr); + return membersValues_->TsType()->AsETSArrayType()->ElementType(); + } + + auto GetOrdinalFromMemberName(std::string_view name) const + { + return memberNameToOrdinal_.at(name); + } + + auto GetValueLiteralFromOrdinal(size_t ord) const + { + ES2PANDA_ASSERT(ord < membersValues_->Elements().size()); + return membersValues_->Elements()[ord]; + } + + bool NodeIsEnumLiteral(ir::Expression *node) const + { + ES2PANDA_ASSERT(node->TsType() == this); + if (!node->IsMemberExpression()) { + return false; + } + + auto mobj = node->AsMemberExpression()->Object(); + if (mobj->TsType() == this) { + // No need to search properties since enum-literals are the only enum-type properties + // NOTE(dkofanov): For some reason, 'enumLowering' changes 'CLASS' to 'ENUM_LITERAL', instead of 'ENUM'. + ES2PANDA_ASSERT(GetDeclNode()->AsClassDefinition()->IsEnumTransformed()); + return true; + } + return false; + } + Type *GetBaseEnumElementType(ETSChecker *checker); + +private: + void InitElementsShortcuts(ir::ClassDefinition *declNode) + { + Span membersNames {}; + for (auto elem : declNode->Body()) { + auto elemName = elem->AsClassElement()->Key()->AsIdentifier()->Name(); + if (elemName == NAMES_ARRAY_NAME) { + membersNames = Span(elem->AsClassProperty()->Value()->AsArrayExpression()->Elements()); + } else if (elemName == VALUES_ARRAY_NAME) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // int-enum + } else if ((elemName == STRING_VALUES_ARRAY_NAME) && (membersValues_ == nullptr)) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // string-enum + } + } + auto membersValues = Span {membersValues_->Elements()}; + ES2PANDA_ASSERT(membersValues.size() == membersNames.size()); + for (size_t i = 0; i < membersNames.size(); i++) { + memberNameToOrdinal_.insert({membersNames[i]->AsStringLiteral()->Str(), i}); + ES2PANDA_ASSERT(membersValues[i]->IsStringLiteral() || membersValues[i]->IsNumberLiteral()); + } + } + +private: + ArenaMap memberNameToOrdinal_; + ir::ArrayExpression *membersValues_; }; 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) + : ETSEnumType(allocator, name, internalName, declNode, relation, ETSObjectFlags::INT_ENUM_OBJECT) { AddTypeFlag(checker::TypeFlag::ETS_INT_ENUM); } @@ -70,9 +143,9 @@ public: class ETSStringEnumType : public ETSEnumType { public: - explicit ETSStringEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, - ir::AstNode *declNode, TypeRelation *relation) - : ETSEnumType(allocator, name, internalName, declNode, relation) + explicit ETSStringEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, + util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) + : ETSEnumType(allocator, name, internalName, declNode, relation, ETSObjectFlags::STRING_ENUM_OBJECT) { AddTypeFlag(checker::TypeFlag::ETS_STRING_ENUM); } @@ -91,4 +164,4 @@ public: } // namespace ark::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index a5a07c1729a7b6eb50f05440fe61b102ff04daef..669ab5d1ed0a67aaf076429635f2f8b91605e10d 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -15,6 +15,8 @@ #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" +#include "checker/types/typeError.h" +#include "compiler/lowering/phase.h" namespace ark::es2panda::checker { @@ -22,8 +24,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,25 +43,28 @@ 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() - ->AssemblerName()) + assemblerName_(checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) != + nullptr + ? checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) + ->AsETSObjectType() + ->AssemblerName() + : "") { } // #22951: proper this type implementation -static void HackThisParameterInExtensionFunctionInvoke(ETSObjectType *interface, size_t arity) +static void HackThisParameterInExtensionFunctionInvoke(ETSObjectType *interface, std::string &invokeName) { - auto invokeName = FunctionalInterfaceInvokeName(arity, false); - auto &callSigsOfInvoke0 = interface->AsETSObjectType() - ->GetOwnProperty(util::StringView(invokeName)) - ->TsType() - ->AsETSFunctionType() - ->CallSignatures(); + auto *property = interface->AsETSObjectType()->GetOwnProperty( + util::StringView(invokeName)); + ES2PANDA_ASSERT(property != nullptr); + auto *tsType = property->TsType(); + ES2PANDA_ASSERT(tsType != nullptr); + auto &callSigsOfInvoke0 = tsType->AsETSFunctionType()->CallSignatures(); for (auto sig : callSigsOfInvoke0) { sig->AddSignatureFlag(SignatureFlags::THIS_RETURN_TYPE); } @@ -71,44 +76,69 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, bool isExtensionHack = signature->HasSignatureFlag(SignatureFlags::EXTENSION_FUNCTION); 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())); - return functionN->Substitute(checker->Relation(), substitution, true, isExtensionHack); + auto sigParamsSize = signature->Params().size(); + auto nPosParams = arity < sigParamsSize ? arity : sigParamsSize; + auto *functionN = checker->GlobalBuiltinFunctionType(nPosParams, true); + + if (nPosParams >= checker->GetGlobalTypesHolder()->VariadicFunctionTypeThreshold()) { + return functionN; + } + + auto substitution = Substitution {}; + ES2PANDA_ASSERT(functionN != nullptr && nPosParams <= functionN->TypeArguments().size()); + for (size_t i = 0; i < nPosParams; i++) { + substitution.emplace(functionN->TypeArguments()[i]->AsETSTypeParameter(), + checker->MaybeBoxType(signature->Params()[i]->TsType())); + } + auto *elementType = !signature->RestVar()->TsType()->IsETSTupleType() + ? checker->GetElementTypeOfArray(signature->RestVar()->TsType()) + : checker->GlobalETSAnyType(); + substitution.emplace(functionN->TypeArguments()[nPosParams]->AsETSTypeParameter(), + checker->MaybeBoxType(elementType)); + substitution.emplace(functionN->TypeArguments()[nPosParams + 1]->AsETSTypeParameter(), + checker->MaybeBoxType(signature->ReturnType())); + auto result = functionN->Substitute(checker->Relation(), &substitution, true, isExtensionHack); + result->AddObjectFlag(checker::ETSObjectFlags::FUNCTIONAL); + return result; } ES2PANDA_ASSERT(arity >= signature->MinArgCount() && arity <= signature->ArgCount()); - // Note: FunctionN is not supported yet + auto *funcIface = checker->GlobalBuiltinFunctionType(arity, false); if (arity >= checker->GetGlobalTypesHolder()->VariadicFunctionTypeThreshold()) { - return nullptr; + return funcIface; } - auto *funcIface = checker->GlobalBuiltinFunctionType(arity, false)->AsETSObjectType(); - auto *substitution = checker->NewSubstitution(); - + auto substitution = Substitution {}; for (size_t i = 0; i < arity; i++) { - substitution->emplace(funcIface->TypeArguments()[i]->AsETSTypeParameter(), - checker->MaybeBoxType(signature->Params()[i]->TsType())); + substitution.emplace(funcIface->TypeArguments()[i]->AsETSTypeParameter(), + checker->MaybeBoxType(signature->Params()[i]->TsType())); } - substitution->emplace(funcIface->TypeArguments()[arity]->AsETSTypeParameter(), - checker->MaybeBoxType(signature->ReturnType())); - auto result = funcIface->Substitute(checker->Relation(), substitution, true, isExtensionHack); + substitution.emplace(funcIface->TypeArguments()[arity]->AsETSTypeParameter(), + checker->MaybeBoxType(signature->ReturnType())); + auto result = funcIface->Substitute(checker->Relation(), &substitution, true, isExtensionHack); if (signature->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { - HackThisParameterInExtensionFunctionInvoke(result, arity); + auto invokeName = checker->FunctionalInterfaceInvokeName(arity, false); + HackThisParameterInExtensionFunctionInvoke(result, invokeName); } + + result->AddObjectFlag(checker::ETSObjectFlags::FUNCTIONAL); return result; } 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 +151,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]); + ERROR_SANITY_CHECK(checker, !IsETSArrowType() && CallSignatures().size() == 1, return nullptr); + return cached.emplace(this, checker->CreateETSArrowType(CallSignatures()[0])).first->second; } void ETSFunctionType::AddCallSignature(Signature *signature) @@ -157,29 +189,28 @@ static inline void AssertNoMethodsInFunctionRelation([[maybe_unused]] Type *left static Signature *EnhanceSignatureSubstitution(TypeRelation *relation, Signature *super, Signature *sub) { auto checker = relation->GetChecker()->AsETSChecker(); - auto *substitution = checker->NewSubstitution(); + auto substitution = Substitution {}; - auto const enhance = [checker, sub, substitution](Type *param, Type *arg) { - return checker->EnhanceSubstitutionForType(sub->GetSignatureInfo()->typeParams, param, arg, substitution); + auto const enhance = [checker, sub, &substitution](Type *param, Type *arg) { + return checker->EnhanceSubstitutionForType(sub->GetSignatureInfo()->typeParams, param, arg, &substitution); }; - for (size_t ix = 0; ix < super->MinArgCount(); ix++) { + for (size_t ix = 0; ix < sub->ArgCount(); ix++) { if (!enhance(sub->GetSignatureInfo()->params[ix]->TsType(), super->GetSignatureInfo()->params[ix]->TsType())) { return nullptr; } } + + if (!enhance(sub->ReturnType(), super->ReturnType())) { + return nullptr; + } + if (super->RestVar() != nullptr) { if (!enhance(sub->RestVar()->TsType(), super->RestVar()->TsType())) { return nullptr; } } - return sub->Substitute(relation, substitution); -} -static uint8_t SignatureThrowKindToOrder(Signature *sig) -{ - return sig->HasSignatureFlag(SignatureFlags::THROWS) ? 0U - : sig->HasSignatureFlag(SignatureFlags::RETHROWS) ? 1U - : 2U; + return sub->Substitute(relation, &substitution); } static bool SignatureIsSupertypeOf(TypeRelation *relation, Signature *super, Signature *sub) @@ -208,7 +239,7 @@ static bool SignatureIsSupertypeOf(TypeRelation *relation, Signature *super, Sig if (!relation->IsSupertypeOf(super->ReturnType(), sub->ReturnType())) { return false; } - return SignatureThrowKindToOrder(super) <= SignatureThrowKindToOrder(sub); + return true; } static ETSFunctionType *CoerceToArrowType(TypeRelation *relation, Type *type) @@ -241,16 +272,6 @@ bool ETSFunctionType::AssignmentSource(TypeRelation *relation, Type *target) { AssertNoMethodsInFunctionRelation(this, target); - // this should be defined by the dynamic type itself - if (target->IsETSDynamicType()) { - ES2PANDA_ASSERT(relation->GetNode() != nullptr); - if (relation->GetNode()->IsArrowFunctionExpression()) { - ES2PANDA_ASSERT(callSignatures_.size() == 1 && ArrowSignature()->HasSignatureFlag(SignatureFlags::CALL)); - return relation->Result(true); - } - return relation->Result(false); - } - return relation->IsSupertypeOf(target, this); } @@ -292,7 +313,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 +353,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..ffc9e8ea5987fe634c900543de8f21a8e019eb4c 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -134,11 +134,6 @@ public: void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetHelperSignature(Signature *signature) noexcept { helperSignature_ = signature; @@ -165,8 +160,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.h b/ets2panda/checker/types/ets/etsNeverType.h index 06904ce0581c2dcf74cc495f1c17e960a04cbbf0..7e998eb6b619f7962aea4e1d931ca1b2edff1889 100644 --- a/ets2panda/checker/types/ets/etsNeverType.h +++ b/ets2panda/checker/types/ets/etsNeverType.h @@ -1,5 +1,5 @@ /* - * 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 @@ -38,11 +38,6 @@ public: TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsNullishTypes.cpp b/ets2panda/checker/types/ets/etsNullishTypes.cpp index 6e102e16751ae3c4b039af93f2d5a8278a34a2de..e9abc5839f4d6d494453c5aa8d7ad9fab029c3b0 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.cpp +++ b/ets2panda/checker/types/ets/etsNullishTypes.cpp @@ -59,12 +59,12 @@ void ETSNullType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) void ETSNullType::ToAssemblerType(std::stringstream &ss) const { - ss << compiler::Signatures::BUILTIN_OBJECT; + ss << compiler::Signatures::NULL_ASSEMBLY_TYPE; } void ETSNullType::ToDebugInfoType(std::stringstream &ss) const { - ss << ETSObjectType::NameToDescriptor(compiler::Signatures::BUILTIN_OBJECT); + ss << ETSObjectType::NameToDescriptor(compiler::Signatures::NULL_ASSEMBLY_TYPE); } Type *ETSNullType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, diff --git a/ets2panda/checker/types/ets/etsNullishTypes.h b/ets2panda/checker/types/ets/etsNullishTypes.h index 195332ffd27cb4541ca6d7ee6bdd31beb21f0027..ff11033e5d4d7c2a2af967e67bd0cc3fea8ce87a 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.h +++ b/ets2panda/checker/types/ets/etsNullishTypes.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 @@ -37,11 +37,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; class ETSUndefinedType : public Type { @@ -60,11 +55,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 5d54c7235bfa01c6cc5825a3c67e5ef2436ad080..3fd970b6bb9f95aa2d575299e3c2acd3ffbf2a89 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -18,26 +18,50 @@ #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 "compiler/lowering/phase.h" +#include "util/nameMangler.h" +#include "ir/statements/annotationDeclaration.h" namespace ark::es2panda::checker { void ETSObjectType::Iterate(const PropertyTraverser &cb) const { - for (const auto *prop : GetAllProperties()) { - cb(prop); + ForEachAllOwnProperties(cb); + ForEachAllNonOwnProperties(cb); +} + +void ETSObjectType::AddInterface(ETSObjectType *interfaceType) +{ + if (std::find(interfaces_.begin(), interfaces_.end(), interfaceType) == interfaces_.end()) { + interfaces_.push_back(interfaceType); + CacheSupertypeTransitive(interfaceType); } +} - if (superType_ != nullptr) { - superType_->Iterate(cb); +void ETSObjectType::SetSuperType(ETSObjectType *super) +{ + superType_ = super; + if (super == nullptr) { + return; } + CacheSupertypeTransitive(super); +} - for (const auto *interface : interfaces_) { - interface->Iterate(cb); +void ETSObjectType::CacheSupertypeTransitive(ETSObjectType *type) +{ + auto const insertType = [this](ETSObjectType *t) { + return transitiveSupertypes_.insert(t->GetOriginalBaseType()).second; + }; + if (insertType(type)) { + for (auto &t : type->transitiveSupertypes_) { + insertType(t); + } } } -varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(const util::StringView &name, - PropertySearchFlags flags) const +varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(util::StringView name, PropertySearchFlags flags) const { varbinder::LocalVariable *res {}; if ((flags & PropertySearchFlags::SEARCH_INSTANCE_FIELD) != 0) { @@ -58,37 +82,53 @@ varbinder::LocalVariable *ETSObjectType::SearchFieldsDecls(const util::StringVie return res; } -varbinder::LocalVariable *ETSObjectType::GetProperty(const util::StringView &name, PropertySearchFlags flags) const +varbinder::LocalVariable *ETSObjectType::GetProperty(util::StringView name, PropertySearchFlags flags) const { - varbinder::LocalVariable *res = SearchFieldsDecls(name, flags); - if (res == nullptr && (flags & PropertySearchFlags::SEARCH_METHOD) != 0) { - if ((flags & PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION) != 0) { - if ((flags & PropertySearchFlags::SEARCH_INSTANCE_METHOD) != 0) { - res = GetOwnProperty(name); + // CC-OFFNXT(G.FMT.14-CPP) project code style + auto const searchOwnMethod = [this, flags, name]() -> varbinder::LocalVariable * { + if ((flags & PropertySearchFlags::SEARCH_INSTANCE_METHOD) != 0) { + if (auto res = GetOwnProperty(name); res != nullptr) { + return res; + } + } + if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { + if (auto res = GetOwnProperty(name); res != nullptr) { + return res; } + } + return nullptr; + }; + + if (auto res = SearchFieldsDecls(name, flags); res != nullptr) { + return res; + } - if (res == nullptr && ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0)) { - res = GetOwnProperty(name); + if ((flags & PropertySearchFlags::SEARCH_METHOD) != 0) { + if ((flags & PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION) != 0) { + if (auto res = searchOwnMethod(); res != nullptr) { + return res; } } else { - res = CreateSyntheticVarFromEverySignature(name, flags); + if (auto res = CreateSyntheticVarFromEverySignature(name, flags)) { + return res; + } } } - if (res == nullptr && (flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { + if (((flags & PropertySearchFlags::SEARCH_INSTANCE) != 0 || (flags & PropertySearchFlags::SEARCH_STATIC) == 0) && + (flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { for (auto *interface : interfaces_) { - res = interface->GetProperty(name, flags); - if (res != nullptr) { + if (auto res = interface->GetProperty(name, flags); res != nullptr) { return res; } } } - if (res == nullptr && superType_ != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { - res = superType_->GetProperty(name, flags); + if ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0 && superType_ != nullptr) { + return superType_->GetProperty(name, flags); } - return res; + return nullptr; } bool ETSObjectType::IsPropertyInherited(const varbinder::Variable *var) @@ -160,7 +200,11 @@ static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, cons if (!HasAccessor(flags, funcType) || res->Declaration() != nullptr) { return; } - auto var = funcType->CallSignatures().front()->OwnerVar(); + + auto frontGetter = std::find_if(funcType->CallSignatures().begin(), funcType->CallSignatures().end(), + [](Signature *sig) { return sig->Function()->IsGetter(); }); + auto var = frontGetter == funcType->CallSignatures().end() ? funcType->CallSignatures().front()->OwnerVar() + : (*frontGetter)->OwnerVar(); auto decl = var->Declaration(); if (decl == nullptr || decl->Node() == nullptr) { return; @@ -168,11 +212,52 @@ static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, cons res->Reset(decl, var->Flags()); } +static PropertySearchFlags UpdateOverloadDeclarationSearchFlags(const PropertySearchFlags &flags) +{ + if ((flags & PropertySearchFlags::IGNORE_OVERLOAD) != 0) { + return flags; + } + PropertySearchFlags syntheticFlags = flags; + if ((flags & PropertySearchFlags::SEARCH_INSTANCE_METHOD) != 0) { + syntheticFlags &= ~PropertySearchFlags::SEARCH_INSTANCE_METHOD; + syntheticFlags |= PropertySearchFlags::SEARCH_INSTANCE_DECL; + } + if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { + syntheticFlags &= ~PropertySearchFlags::SEARCH_STATIC_METHOD; + syntheticFlags |= PropertySearchFlags::SEARCH_STATIC_DECL; + } + return syntheticFlags; +} + +static PropertySearchFlags UpdateMethodSearchFlags(const PropertySearchFlags &flags) +{ + if ((flags & PropertySearchFlags::IGNORE_OVERLOAD) != 0) { + return flags; + } + PropertySearchFlags syntheticFlags = flags; + if ((flags & PropertySearchFlags::SEARCH_INSTANCE_DECL) != 0) { + syntheticFlags &= ~PropertySearchFlags::SEARCH_INSTANCE_DECL; + syntheticFlags |= PropertySearchFlags::SEARCH_INSTANCE_METHOD; + } + if ((flags & PropertySearchFlags::SEARCH_STATIC_DECL) != 0) { + syntheticFlags &= ~PropertySearchFlags::SEARCH_STATIC_DECL; + syntheticFlags |= PropertySearchFlags::SEARCH_STATIC_METHOD; + } + return syntheticFlags; +} + varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(const util::StringView &name, PropertySearchFlags flags) const { std::vector signatures; - varbinder::LocalVariable *functionalInterface = CollectSignaturesForSyntheticType(signatures, name, flags); + // Since both "first match" and "best match" exist at present, overloadDeclarationCall is temporarily used. After + // "best match" removed, this marking needs to be removed. + auto *overloadDeclaration = SearchFieldsDecls(name, UpdateOverloadDeclarationSearchFlags(flags)); + SignatureCollectContext sigCtx {GetRelation()->GetChecker()->AsETSChecker(), overloadDeclaration, true}; + PropertySearchFlags syntheticFlags = + sigCtx.IsOverloadDeclarationCall() ? UpdateOverloadDeclarationSearchFlags(flags) : flags; + + varbinder::LocalVariable *functionalInterface = CollectSignaturesForSyntheticType(signatures, name, syntheticFlags); // #22952: the called function *always* returns nullptr ES2PANDA_ASSERT(functionalInterface == nullptr); (void)functionalInterface; @@ -181,14 +266,14 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co return nullptr; } - varbinder::LocalVariable *res = allocator_->New(varbinder::VariableFlags::SYNTHETIC | - varbinder::VariableFlags::METHOD); + varbinder::LocalVariable *res = sigCtx.CreateSyntheticVar(allocator_); ETSFunctionType *funcType = CreateMethodTypeForProp(name); + ES2PANDA_ASSERT(funcType != nullptr); for (auto &s : signatures) { funcType->AddCallSignature(s); } - + ES2PANDA_ASSERT(res != nullptr); res->SetTsType(funcType); funcType->SetVariable(res); @@ -197,15 +282,41 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co return res; } -ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView &name) const +ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(util::StringView name) const { ES2PANDA_ASSERT(GetRelation() != nullptr); return GetRelation()->GetChecker()->AsETSChecker()->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } -static void AddSignature(std::vector &signatures, PropertySearchFlags flags, ETSChecker *checker, - varbinder::LocalVariable *found) +bool ETSObjectType::ReplaceArgumentInSignature(std::vector &signatures, Signature *sigToInsert, + TypeRelation *relation) const +{ + for (auto *&sigToReplace : signatures) { + if (sigToReplace->ArgCount() != sigToInsert->ArgCount()) { + continue; + } + if (relation->IsSupertypeOf(sigToInsert->Owner(), sigToReplace->Owner()) && + relation->SignatureIsSupertypeOf(sigToInsert, sigToReplace)) { + // Already overridden by a subtype's signature + return true; + } + if (relation->IsSupertypeOf(sigToReplace->Owner(), sigToInsert->Owner()) && + relation->SignatureIsSupertypeOf(sigToReplace, sigToInsert)) { + sigToReplace = sigToInsert; + return true; + } + } + + return false; +} + +void ETSObjectType::AddSignatureFromFunction(std::vector &signatures, PropertySearchFlags flags, + ETSChecker *checker, varbinder::LocalVariable *found) const { + if (found == nullptr || !found->TsType()->IsETSFunctionType()) { + return; + } + for (auto *it : found->TsType()->AsETSFunctionType()->CallSignatures()) { if (std::find(signatures.begin(), signatures.end(), it) != signatures.end()) { continue; @@ -213,20 +324,65 @@ static void AddSignature(std::vector &signatures, PropertySearchFla 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)); - })) { + if (ReplaceArgumentInSignature(signatures, it, checker->Relation())) { continue; } - // Issue: #18720 - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) signatures.emplace_back(it); } } +void ETSObjectType::AddSignatureFromOverload(std::vector &signatures, PropertySearchFlags flags, + varbinder::LocalVariable *found) const +{ + if (found == nullptr || !found->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + return; + } + + ES2PANDA_ASSERT(found->Declaration()->Node()->IsOverloadDeclaration()); + auto *overloadDeclaration = found->Declaration()->Node()->AsOverloadDeclaration(); + std::vector methodSignature; + if (overloadDeclaration->Id()->IsErrorPlaceHolder()) { + return; + } + + SignatureCollectContext sigCtx {GetRelation()->GetChecker()->AsETSChecker(), found}; + + if (overloadDeclaration->IsConstructorOverloadDeclaration()) { + return AddSignatureFromConstructor(signatures, found); + } + + for (auto *method : overloadDeclaration->OverloadedList()) { + // Identical type cannot be obtained directly, because typeparamter has not been substitute. + methodSignature.clear(); + util::StringView methodName = + method->IsIdentifier() ? method->AsIdentifier()->Name() : method->AsTSQualifiedName()->Right()->Name(); + CollectSignaturesForSyntheticType(methodSignature, methodName, UpdateMethodSearchFlags(flags)); + if (!methodSignature.empty()) { + signatures.emplace_back(methodSignature.front()); + } + } +} + +void ETSObjectType::AddSignatureFromConstructor(std::vector &signatures, + varbinder::LocalVariable *found) const +{ + auto *overloadDeclaration = found->Declaration()->Node()->AsOverloadDeclaration(); + for (auto *method : overloadDeclaration->OverloadedList()) { + util::StringView orderConstructorName = method->AsIdentifier()->Name(); + + // Constructor will lowering to multiple Constructor if have rest parameters or optional parameters. + // Need to modify RestTupleConstructionPhase. + std::vector matches; + std::copy_if( + constructSignatures_.begin(), constructSignatures_.end(), std::back_inserter(matches), + [orderConstructorName](Signature *sig) { return sig->Function()->Id()->Name() == orderConstructorName; }); + + if (!matches.empty()) { + std::copy(matches.begin(), matches.end(), std::back_inserter(signatures)); + } + } +} + varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std::vector &signatures, const util::StringView &name, PropertySearchFlags flags) const @@ -234,42 +390,65 @@ varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std:: 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(signatures, flags, checker, found); - } + auto *found = GetOwnProperty(name); + AddSignatureFromFunction(signatures, flags, checker, found); } if ((flags & PropertySearchFlags::SEARCH_INSTANCE_METHOD) != 0) { - if (auto *found = GetOwnProperty(name); - found != nullptr && !found->TsType()->IsTypeError()) { - ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - AddSignature(signatures, flags, checker, found); - } + auto *found = GetOwnProperty(name); + AddSignatureFromFunction(signatures, flags, checker, found); + } + + if ((flags & PropertySearchFlags::SEARCH_STATIC_DECL) != 0) { + auto *found = GetOwnProperty(name); + AddSignatureFromOverload(signatures, flags, found); + } + + if ((flags & PropertySearchFlags::SEARCH_INSTANCE_DECL) != 0) { + auto *found = GetOwnProperty(name); + AddSignatureFromOverload(signatures, flags, found); + } + + if ((flags & PropertySearchFlags::SEARCH_METHOD) == 0 && (flags & PropertySearchFlags::SEARCH_DECL) == 0) { + return nullptr; } if (superType_ != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { 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); - } + if ((flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) { + for (auto *interface : Interfaces()) { + interface->CollectSignaturesForSyntheticType(signatures, name, flags); } } + return nullptr; } +void ETSObjectType::ForEachAllOwnProperties(const PropertyTraverser &cb) const +{ + EnsurePropertiesInstantiated(); + for (size_t i = 0; i < static_cast(PropertyType::COUNT); ++i) { + PropertyMap &map = properties_[i]; + for (const auto &[_, prop] : map) { + (void)_; + cb(prop); + } + } +} + +void ETSObjectType::ForEachAllNonOwnProperties(const PropertyTraverser &cb) const +{ + if (superType_ != nullptr) { + superType_->Iterate(cb); + } + + for (const auto *interface : interfaces_) { + interface->Iterate(cb); + } +} + std::vector ETSObjectType::GetAllProperties() const { std::vector allProperties; @@ -306,16 +485,42 @@ std::vector ETSObjectType::GetAllProperties() const return allProperties; } +std::vector ETSObjectType::Overloads() const +{ + std::vector methods; + for (const auto &[_, prop] : InstanceMethods()) { + (void)_; + if (prop->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + methods.push_back(prop); + } + } + + for (const auto &[_, prop] : StaticMethods()) { + (void)_; + if (prop->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + methods.push_back(prop); + } + } + + return methods; +} + std::vector ETSObjectType::Methods() const { std::vector methods; for (const auto &[_, prop] : InstanceMethods()) { (void)_; + if (prop->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + continue; + } methods.push_back(prop); } for (const auto &[_, prop] : StaticMethods()) { (void)_; + if (prop->HasFlag(varbinder::VariableFlags::OVERLOAD)) { + continue; + } methods.push_back(prop); } @@ -350,35 +555,25 @@ std::vector ETSObjectType::ForeignProperties() ownInstanceProps.reserve(properties_.size()); ownStaticProps.reserve(properties_.size()); - for (const auto *prop : GetAllProperties()) { + ForEachAllOwnProperties([&](const varbinder::LocalVariable *prop) { if (prop->HasFlag(varbinder::VariableFlags::STATIC)) { ownStaticProps.insert(prop->Name()); } else { ownInstanceProps.insert(prop->Name()); } - } - - std::map allInstanceProps {}; - std::map allStaticProps {}; - Iterate([&allInstanceProps, &allStaticProps](const varbinder::LocalVariable *var) { + }); + ForEachAllNonOwnProperties([&](const varbinder::LocalVariable *var) { if (var->HasFlag(varbinder::VariableFlags::STATIC)) { - allStaticProps.emplace(var->Name(), var); + if (ownStaticProps.find(var->Name()) == ownStaticProps.end()) { + foreignProps.push_back(var); + } } else { - allInstanceProps.emplace(var->Name(), var); + if (ownInstanceProps.find(var->Name()) == ownInstanceProps.end()) { + foreignProps.push_back(var); + } } }); - 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); - } - } - return foreignProps; } @@ -386,7 +581,7 @@ void ETSObjectType::ToString(std::stringstream &ss, bool precise) const { if (IsPartial()) { ss << "Partial" << compiler::Signatures::GENERIC_BEGIN; - baseType_->ToString(ss, precise); + ss << util::NameMangler::GetInstance()->GetOriginalClassNameFromPartial(name_.Mutf8()); ss << compiler::Signatures::GENERIC_END; return; } @@ -425,7 +620,8 @@ void ETSObjectType::SubstitutePartialTypes(TypeRelation *relation, Type *other) ES2PANDA_ASSERT(IsPartial()); if ((baseType_->IsGeneric() || baseType_->IsETSTypeParameter()) && effectiveSubstitution_ != nullptr) { - if (auto *newBaseType = baseType_->Substitute(relation, effectiveSubstitution_); + auto subst = ETSChecker::ArenaSubstitutionToSubstitution(effectiveSubstitution_); + if (auto *newBaseType = baseType_->Substitute(relation, &subst); newBaseType->IsETSObjectType() && !relation->IsIdenticalTo(newBaseType, baseType_)) { baseType_ = newBaseType->AsETSObjectType(); } @@ -435,7 +631,8 @@ void ETSObjectType::SubstitutePartialTypes(TypeRelation *relation, Type *other) auto *otherPartial = other->AsETSObjectType(); if ((otherPartial->baseType_->IsGeneric() || otherPartial->baseType_->IsETSTypeParameter()) && otherPartial->effectiveSubstitution_ != nullptr) { - if (auto *newBaseType = otherPartial->baseType_->Substitute(relation, otherPartial->effectiveSubstitution_); + auto subst = ETSChecker::ArenaSubstitutionToSubstitution(otherPartial->effectiveSubstitution_); + if (auto *newBaseType = otherPartial->baseType_->Substitute(relation, &subst); newBaseType->IsETSObjectType() && !relation->IsIdenticalTo(newBaseType, otherPartial->baseType_)) { otherPartial->baseType_ = newBaseType->AsETSObjectType(); } @@ -447,15 +644,14 @@ void ETSObjectType::SubstitutePartialTypes(TypeRelation *relation, Type *other) void ETSObjectType::IdenticalUptoTypeArguments(TypeRelation *relation, Type *other) { relation->Result(false); + if (!other->IsETSObjectType() || !CheckIdenticalFlags(other->AsETSObjectType())) { + return; + } if (IsPartial()) { SubstitutePartialTypes(relation, other); } - if (!other->IsETSObjectType() || !CheckIdenticalFlags(other->AsETSObjectType())) { - return; - } - // NOTE: (DZ) only both Partial types can be compatible. if (static_cast(static_cast(IsPartial()) ^ static_cast(other->AsETSObjectType()->IsPartial()))) { @@ -464,7 +660,7 @@ void ETSObjectType::IdenticalUptoTypeArguments(TypeRelation *relation, Type *oth auto *thisBase = GetOriginalBaseType(); auto *otherBase = other->AsETSObjectType()->GetOriginalBaseType(); - if (thisBase->Variable() != otherBase->Variable()) { + if (thisBase->Variable()->Declaration()->Node() != otherBase->Variable()->Declaration()->Node()) { return; } @@ -517,7 +713,6 @@ void ETSObjectType::Identical(TypeRelation *relation, Type *other) bool ETSObjectType::CheckIdenticalFlags(ETSObjectType *other) const { constexpr auto FLAGS_TO_REMOVE = ETSObjectFlags::INCOMPLETE_INSTANTIATION | - ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY | ETSObjectFlags::EXTENSION_FUNCTION; auto cleanedTargetFlags = other->ObjectFlags(); @@ -537,7 +732,7 @@ bool ETSObjectType::AssignmentSource(TypeRelation *const relation, [[maybe_unuse bool ETSObjectType::IsBoxedPrimitive() const { - if (this->IsETSDynamicType()) { + if (this->IsETSEnumType()) { return false; } @@ -553,12 +748,12 @@ void ETSObjectType::AssignmentTarget(TypeRelation *const relation, Type *source) ETSFunctionType *ETSObjectType::GetFunctionalInterfaceInvokeType() const { ES2PANDA_ASSERT(HasObjectFlag(ETSObjectFlags::FUNCTIONAL)); + auto checker = GetRelation()->GetChecker()->AsETSChecker(); // NOTE(vpukhov): this is still better than to retain any "functional" state in ETSObjectType - auto [foundArity, hasRest] = [this]() { - auto checker = GetRelation()->GetChecker()->AsETSChecker(); + auto [foundArity, hasRest] = [this, checker]() { auto baseType = GetConstOriginalBaseType(); - for (size_t arity = 0; arity < checker->GetGlobalTypesHolder()->VariadicFunctionTypeThreshold(); ++arity) { + for (size_t arity = 0; arity <= checker->GlobalBuiltinFunctionTypeVariadicThreshold(); ++arity) { if (auto itf = checker->GlobalBuiltinFunctionType(arity, false); itf == baseType) { return std::make_pair(arity, false); } @@ -569,14 +764,15 @@ ETSFunctionType *ETSObjectType::GetFunctionalInterfaceInvokeType() const ES2PANDA_UNREACHABLE(); }(); - std::string invokeName = FunctionalInterfaceInvokeName(foundArity, hasRest); - auto *invoke = GetOwnProperty(util::StringView(invokeName)); + std::string invokeName = checker->FunctionalInterfaceInvokeName(foundArity, hasRest); + auto *invoke = GetProperty(util::StringView(invokeName), + PropertySearchFlags::SEARCH_INSTANCE_METHOD | PropertySearchFlags::SEARCH_IN_INTERFACES); ES2PANDA_ASSERT(invoke != nullptr && invoke->TsType() != nullptr && invoke->TsType()->IsETSFunctionType()); return invoke->TsType()->AsETSFunctionType(); } -bool ETSObjectType::CastWideningNarrowing(TypeRelation *const relation, Type *const target, TypeFlag unboxFlags, - TypeFlag wideningFlags, TypeFlag narrowingFlags) +bool ETSObjectType::CastWidening(TypeRelation *const relation, Type *const target, TypeFlag unboxFlags, + TypeFlag wideningFlags) { if (target->HasTypeFlag(unboxFlags)) { conversion::Unboxing(relation, this); @@ -586,10 +782,6 @@ bool ETSObjectType::CastWideningNarrowing(TypeRelation *const relation, Type *co conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (target->HasTypeFlag(narrowingFlags)) { - conversion::UnboxingNarrowingPrimitive(relation, this, target); - return true; - } return false; } @@ -604,7 +796,7 @@ bool ETSObjectType::TryCastByte(TypeRelation *const relation, Type *const target return true; } if (target->HasTypeFlag(TypeFlag::CHAR)) { - conversion::UnboxingWideningNarrowingPrimitive(relation, this, target); + conversion::UnboxingWideningPrimitive(relation, this, target); return true; } return false; @@ -616,25 +808,21 @@ bool ETSObjectType::TryCastIntegral(TypeRelation *const relation, Type *const ta return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT) && - CastWideningNarrowing(relation, target, TypeFlag::SHORT, - TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, - TypeFlag::BYTE | TypeFlag::CHAR)) { + CastWidening(relation, target, TypeFlag::SHORT, + TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR) && - CastWideningNarrowing(relation, target, TypeFlag::CHAR, - TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, - TypeFlag::BYTE | TypeFlag::SHORT)) { + CastWidening(relation, target, TypeFlag::CHAR, + TypeFlag::SHORT | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_INT) && - CastWideningNarrowing(relation, target, TypeFlag::INT, TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE, - TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR)) { + CastWidening(relation, target, TypeFlag::INT, TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && - CastWideningNarrowing(relation, target, TypeFlag::LONG, TypeFlag::FLOAT | TypeFlag::DOUBLE, - TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT)) { + CastWidening(relation, target, TypeFlag::LONG, TypeFlag::FLOAT | TypeFlag::DOUBLE)) { return true; } return false; @@ -643,14 +831,11 @@ bool ETSObjectType::TryCastIntegral(TypeRelation *const relation, Type *const ta bool ETSObjectType::TryCastFloating(TypeRelation *const relation, Type *const target) { if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT) && - CastWideningNarrowing(relation, target, TypeFlag::FLOAT, TypeFlag::DOUBLE, - TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG)) { + CastWidening(relation, target, TypeFlag::FLOAT, TypeFlag::DOUBLE)) { return true; } - if (auto narrowingFlags = - TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT; - this->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE) && - CastWideningNarrowing(relation, target, TypeFlag::DOUBLE, TypeFlag::NONE, narrowingFlags)) { + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE) && + CastWidening(relation, target, TypeFlag::DOUBLE, TypeFlag::NONE)) { return true; } return false; @@ -672,6 +857,12 @@ bool ETSObjectType::TryCastUnboxable(TypeRelation *const relation, Type *const t conversion::WideningReference(relation, this, target->AsETSObjectType()); return true; } + + if (target->IsETSEnumType()) { + auto unboxedThis = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(this); + return relation->IsCastableTo(unboxedThis, target); + } + conversion::Forbidden(relation); return true; } @@ -697,10 +888,6 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const if (this->IsETSUnboxableObject()) { return TryCastUnboxable(relation, target); } - if (target->IsETSPrimitiveType()) { - conversion::NarrowingReferenceUnboxing(relation, this, target); - return true; - } return false; } @@ -711,6 +898,11 @@ void ETSObjectType::Cast(TypeRelation *const relation, Type *const target) return; } + if (target->IsGradualType()) { + relation->Result(true); + return; + } + if (CastNumericObject(relation, target)) { return; } @@ -754,7 +946,7 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) relation->Result(false); auto const checker = relation->GetChecker()->AsETSChecker(); - if (source->HasTypeFlag(TypeFlag::READONLY)) { + if (source->HasTypeFlag(TypeFlag::READONLY) && !IsGlobalETSObjectType()) { relation->Result(false); return; } @@ -793,6 +985,14 @@ void ETSObjectType::IsSupertypeOf(TypeRelation *relation, Type *source) void ETSObjectType::IsSubtypeOf(TypeRelation *relation, Type *target) { + if (target->IsETSObjectType()) { + auto &transitives = transitiveSupertypes_; + if (transitives.find(target->AsETSObjectType()->GetOriginalBaseType()) == transitives.end()) { + relation->Result(false); + return; + } + } + if (auto super = SuperType(); super != nullptr) { if (relation->IsSupertypeOf(target, super)) { return; @@ -855,6 +1055,7 @@ void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType * Type *ETSObjectType::AsSuper(Checker *checker, varbinder::Variable *sourceVar) { + checker = GetETSChecker(); if (sourceVar == nullptr) { return nullptr; } @@ -914,13 +1115,15 @@ varbinder::LocalVariable *ETSObjectType::CopyProperty(varbinder::LocalVariable * if (copiedPropType->Variable() == prop) { copiedPropType->SetVariable(copiedProp); } + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(copiedPropType); 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(); @@ -933,9 +1136,9 @@ Type *ETSObjectType::Instantiate(ArenaAllocator *const allocator, TypeRelation * auto *const copiedType = checker->CreateETSObjectType(declNode_, flags_); ES2PANDA_ASSERT(copiedType->internalName_ == internalName_); ES2PANDA_ASSERT(copiedType->name_ == name_); + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->typeFlags_ = typeFlags_; - copiedType->RemoveObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | - ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); + copiedType->RemoveObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); copiedType->SetVariable(variable_); copiedType->SetSuperType(superType_); @@ -981,6 +1184,7 @@ static varbinder::LocalVariable *CopyPropertyWithTypeArguments(varbinder::LocalV if (copiedPropType->Variable() == prop || copiedPropType->Variable() == nullptr) { copiedPropType->SetVariable(copiedProp); } + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(copiedPropType); return copiedProp; } @@ -1013,13 +1217,13 @@ bool ETSObjectType::SubstituteTypeArgs(TypeRelation *const relation, ArenaVector return anyChange; } -static Substitution *ComputeEffectiveSubstitution(TypeRelation *const relation, - const ArenaVector &baseTypeParams, - ArenaVector &newTypeArgs) +static ArenaSubstitution *ComputeEffectiveSubstitution(TypeRelation *const relation, + const ArenaVector &baseTypeParams, + ArenaVector &newTypeArgs) { ES2PANDA_ASSERT(baseTypeParams.size() == newTypeArgs.size()); auto *const checker = relation->GetChecker()->AsETSChecker(); - auto *effectiveSubstitution = checker->NewSubstitution(); + auto *effectiveSubstitution = checker->NewArenaSubstitution(); for (size_t ix = 0; ix < baseTypeParams.size(); ix++) { checker->EmplaceSubstituted(effectiveSubstitution, baseTypeParams[ix]->AsETSTypeParameter(), newTypeArgs[ix]); @@ -1031,23 +1235,30 @@ static Substitution *ComputeEffectiveSubstitution(TypeRelation *const relation, void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObjectType *const copiedType, ArenaVector &&newTypeArgs, ETSObjectType *base) { + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->typeFlags_ = typeFlags_; - copiedType->RemoveObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | - ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); + copiedType->RemoveObjectFlag(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) { @@ -1059,36 +1270,97 @@ 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()}; +} + +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 (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. @@ -1097,7 +1369,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; @@ -1109,14 +1381,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) { @@ -1144,16 +1417,41 @@ ETSObjectType *ETSObjectType::SubstituteArguments(TypeRelation *relation, ArenaV } auto *checker = relation->GetChecker()->AsETSChecker(); - auto *substitution = checker->NewSubstitution(); + auto substitution = Substitution {}; ES2PANDA_ASSERT(baseType_ == nullptr); ES2PANDA_ASSERT(typeArguments_.size() == arguments.size()); for (size_t ix = 0; ix < typeArguments_.size(); ix++) { - substitution->emplace(typeArguments_[ix]->AsETSTypeParameter(), checker->MaybeBoxType(arguments[ix])); + substitution.emplace(typeArguments_[ix]->AsETSTypeParameter(), + checker->MaybeBoxType(arguments[ix]->MaybeBaseTypeOfGradualType())); } - return Substitute(relation, substitution); + return Substitute(relation, &substitution); +} + +ETSChecker *ETSObjectType::GetETSChecker() +{ + return relation_->GetChecker()->AsETSChecker(); +} + +void ETSObjectType::CheckAndInstantiateProperties() const +{ + auto *checker = relation_->GetChecker()->AsETSChecker(); + auto *declNode = GetDeclNode(); + if (HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) && declNode == nullptr) { + declNode = SuperType()->GetDeclNode(); + } + if (declNode == nullptr) { + ES2PANDA_ASSERT(checker->IsAnyError()); + return; + } + + TypeStackElement tse {checker, this, {{diagnostic::CIRCULAR_DEPENDENCY, {this->Name()}}}, declNode->Start()}; + if (tse.HasTypeError()) { + return; + } + InstantiateProperties(); } void ETSObjectType::InstantiateProperties() const @@ -1169,44 +1467,48 @@ void ETSObjectType::InstantiateProperties() const ES2PANDA_ASSERT(!propertiesInstantiated_); declNode_->Check(checker); + auto subst = effectiveSubstitution_ == nullptr + ? Substitution {} + : ETSChecker::ArenaSubstitutionToSubstitution(effectiveSubstitution_); + for (auto *const it : baseType_->ConstructSignatures()) { - auto *newSig = it->Substitute(relation_, effectiveSubstitution_); + auto *newSig = it->Substitute(relation_, &subst); constructSignatures_.push_back(newSig); } for (auto const &[_, prop] : baseType_->InstanceFields()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::INSTANCE_FIELD)].emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticFields()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::STATIC_FIELD)].emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->InstanceMethods()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::INSTANCE_METHOD)].emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticMethods()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::STATIC_METHOD)].emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->InstanceDecls()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::INSTANCE_DECL)].emplace(prop->Name(), copiedProp); } for (auto const &[_, prop] : baseType_->StaticDecls()) { (void)_; - auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, effectiveSubstitution_); + auto *copiedProp = CopyPropertyWithTypeArguments(prop, relation_, &subst); properties_[static_cast(PropertyType::STATIC_DECL)].emplace(prop->Name(), copiedProp); } } @@ -1335,8 +1637,29 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla return; } - auto *params = GetDeclNode()->IsClassDefinition() ? GetDeclNode()->AsClassDefinition()->TypeParams() - : GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + // according to the spec(GENERICS chapter), only class/interface/function/ + // method/lambda and type alias can have type parameters. since + // 1. the type of function and method is ETSFunctionType + // 2. lambda has been checked above + // here we just need check + // 1. class + // 2. interface + // 3. type alias(which will be redirected to its real type) + // And all of them should have declarations + if (declNode_ == nullptr) { + // If the type is not declared, then we do not need to check variance. + return; + } + ir::TSTypeParameterDeclaration *params; + if (GetDeclNode()->IsClassDefinition()) { + params = GetDeclNode()->AsClassDefinition()->TypeParams(); + } else if (GetDeclNode()->IsTSInterfaceDeclaration()) { + params = GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + } else { + // If the type is not a class or interface or type alias, then we do not need to check variance. + return; + } + if (params == nullptr) { return; } @@ -1354,4 +1677,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(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, std::move(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..a86f126b974a89484f4a1ec9f5d7795a66d6a498 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)> {}) @@ -63,17 +67,10 @@ public: propertiesInstantiated_ = true; } - void AddInterface(ETSObjectType *interfaceType) - { - if (std::find(interfaces_.begin(), interfaces_.end(), interfaceType) == interfaces_.end()) { - interfaces_.push_back(interfaceType); - } - } + void AddInterface(ETSObjectType *interfaceType); + void SetSuperType(ETSObjectType *super); - void SetSuperType(ETSObjectType *super) - { - superType_ = super; - } + ETSChecker *GetETSChecker(); void SetTypeArguments(ArenaVector &&typeArgs) { @@ -92,6 +89,7 @@ public: void SetRelation(TypeRelation *relation) { + ES2PANDA_ASSERT(relation); relation_ = relation; } @@ -158,7 +156,7 @@ public: return interfaces_; } - ArenaVector &Interfaces() + const ArenaVector &Interfaces() { return interfaces_; } @@ -234,12 +232,12 @@ public: bool IsDescendantOf(const ETSObjectType *ascendant) const; - const util::StringView &Name() const + util::StringView Name() const { return name_; } - const util::StringView &AssemblerName() const + util::StringView AssemblerName() const { return internalName_; } @@ -264,6 +262,17 @@ public: return (flags_ & flag) != 0; } + bool IsInterface() const + { + return HasObjectFlag(ETSObjectFlags::INTERFACE); + } + + bool IsETSStringLiteralType() const + { + return superType_ != nullptr && superType_->IsETSObjectType() && + superType_->HasObjectFlag(ETSObjectFlags::STRING); + } + ETSFunctionType *GetFunctionalInterfaceInvokeType() const; ETSObjectFlags BuiltInKind() const @@ -276,15 +285,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,13 +296,10 @@ 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 + varbinder::LocalVariable *GetOwnProperty(const util::StringView name) const { EnsurePropertiesInstantiated(); auto found = properties_[static_cast(TYPE)].find(name); @@ -349,19 +347,29 @@ public: } std::vector ForeignProperties() const; - varbinder::LocalVariable *GetProperty(const util::StringView &name, PropertySearchFlags flags) const; + varbinder::LocalVariable *GetProperty(util::StringView name, PropertySearchFlags flags) const; std::vector GetAllProperties() const; + void ForEachAllOwnProperties(const PropertyTraverser &cb) const; + void ForEachAllNonOwnProperties(const PropertyTraverser &cb) const; varbinder::LocalVariable *CopyProperty(varbinder::LocalVariable *prop, ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); std::vector Methods() const; std::vector Fields() const; + std::vector Overloads() const; varbinder::LocalVariable *CreateSyntheticVarFromEverySignature(const util::StringView &name, PropertySearchFlags flags) const; varbinder::LocalVariable *CollectSignaturesForSyntheticType(std::vector &signatures, const util::StringView &name, PropertySearchFlags flags) const; + void AddSignatureFromFunction(std::vector &signatures, PropertySearchFlags flags, ETSChecker *checker, + varbinder::LocalVariable *found) const; + void AddSignatureFromOverload(std::vector &signatures, PropertySearchFlags flags, + varbinder::LocalVariable *found) const; + void AddSignatureFromConstructor(std::vector &signatures, varbinder::LocalVariable *found) const; + bool ReplaceArgumentInSignature(std::vector &signatures, Signature *sigToInsert, + TypeRelation *relation) 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 +377,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,16 +400,11 @@ public: const ArenaVector &ReExports() const; bool IsSameBasedGeneric(TypeRelation *relation, Type const *other) const; - ArenaAllocator *Allocator() const + ThreadSafeArenaAllocator *Allocator() const { return allocator_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] static std::uint32_t GetPrecedence(checker::ETSChecker *checker, ETSObjectType const *type) noexcept; bool IsPropertiesInstantiated() const @@ -410,11 +413,11 @@ public: } protected: - virtual ETSFunctionType *CreateMethodTypeForProp(const util::StringView &name) const; + virtual ETSFunctionType *CreateMethodTypeForProp(util::StringView name) const; 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,8 +429,8 @@ private: reExports_(allocator->Adapter()), reExportAlias_(allocator->Adapter()), flags_(std::get(info)), - instantiationMap_(allocator->Adapter()), typeArguments_(allocator->Adapter()), + transitiveSupertypes_(allocator->Adapter()), relation_(std::get(info)), constructSignatures_(allocator->Adapter()), properties_ {(void(IS), PropertyMap {allocator->Adapter()})...} @@ -436,22 +439,22 @@ private: /* Properties and construct signatures are instantiated lazily. */ void InstantiateProperties() const; + void CheckAndInstantiateProperties() const; void EnsurePropertiesInstantiated() const { if (!propertiesInstantiated_) { - InstantiateProperties(); + CheckAndInstantiateProperties(); propertiesInstantiated_ = true; } } - bool CastWideningNarrowing(TypeRelation *relation, Type *target, TypeFlag unboxFlags, TypeFlag wideningFlags, - TypeFlag narrowingFlags); + bool CastWidening(TypeRelation *relation, Type *target, TypeFlag unboxFlags, TypeFlag wideningFlags); 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; + varbinder::LocalVariable *SearchFieldsDecls(util::StringView name, PropertySearchFlags flags) const; void SetCopiedTypeProperties(TypeRelation *relation, ETSObjectType *copiedType, ArenaVector &&newTypeArgs, ETSObjectType *base); @@ -462,9 +465,11 @@ private: bool TryCastFloating(TypeRelation *const relation, Type *const target); bool TryCastUnboxable(TypeRelation *const relation, Type *const target); + void CacheSupertypeTransitive(ETSObjectType *type); + ir::TSTypeParameterDeclaration *GetTypeParams() const; - ArenaAllocator *const allocator_; + ThreadSafeArenaAllocator *const allocator_; util::StringView const name_; util::StringView const internalName_; ir::AstNode *const declNode_; @@ -472,15 +477,17 @@ private: ArenaVector reExports_; ArenaMap reExportAlias_; ETSObjectFlags flags_; - InstantiationMap instantiationMap_; ArenaVector typeArguments_; ETSObjectType *superType_ {}; ETSObjectType *enclosingType_ {}; ETSObjectType *baseType_ {}; + // optimized subtyping + ArenaSet transitiveSupertypes_; + // for lazy properties instantiation TypeRelation *relation_ = nullptr; - const Substitution *effectiveSubstitution_ = nullptr; + const ArenaSubstitution *effectiveSubstitution_ = nullptr; mutable bool propertiesInstantiated_ = false; mutable ArenaVector constructSignatures_; mutable PropertyHolder properties_; diff --git a/ets2panda/checker/types/ets/etsObjectTypeConstants.h b/ets2panda/checker/types/ets/etsObjectTypeConstants.h index a0582dd23555b9b1c3485716724ea03c0557a966..b3a4e93f35c0672ccd9053edd73c7b07650a9c12 100644 --- a/ets2panda/checker/types/ets/etsObjectTypeConstants.h +++ b/ets2panda/checker/types/ets/etsObjectTypeConstants.h @@ -34,15 +34,14 @@ enum class ETSObjectFlags : std::uint64_t { RESOLVED_INTERFACES = 1U << 7U, RESOLVED_SUPER = 1U << 8U, RESOLVED_TYPE_PARAMS = 1U << 9U, - CHECKED_COMPATIBLE_ABSTRACTS = 1U << 10U, - STRING = 1U << 11U, - INCOMPLETE_INSTANTIATION = 1U << 12U, - INNER = 1U << 13U, - DYNAMIC = 1U << 14U, - ASYNC_FUNC_RETURN_TYPE = 1U << 15U, - CHECKED_INVOKE_LEGITIMACY = 1U << 16U, - REQUIRED = 1U << 17U, - READONLY = 1U << 18U, + STRING = 1U << 10U, + INCOMPLETE_INSTANTIATION = 1U << 11U, + INNER = 1U << 12U, + DYNAMIC = 1U << 13U, + ASYNC_FUNC_RETURN_TYPE = 1U << 14U, + CHECKED_INVOKE_LEGITIMACY = 1U << 15U, + REQUIRED = 1U << 16U, + READONLY = 1U << 17U, BUILTIN_BIGINT = 1U << 22U, BUILTIN_STRING = 1U << 23U, @@ -54,15 +53,30 @@ enum class ETSObjectFlags : std::uint64_t { BUILTIN_LONG = 1U << 29U, BUILTIN_FLOAT = 1U << 30U, BUILTIN_DOUBLE = 1U << 31U, + BUILTIN_ARRAY = 1ULL << 32U, + BUILTIN_READONLY_ARRAY = 1ULL << 33U, - ENUM_OBJECT = 1ULL << 32U, - EXTENSION_FUNCTION = 1ULL << 33U, + INT_ENUM_OBJECT = 1ULL << 34U, + STRING_ENUM_OBJECT = 1ULL << 35U, - BUILTIN_NUMERIC = BUILTIN_BYTE | BUILTIN_SHORT | BUILTIN_INT | BUILTIN_LONG | BUILTIN_FLOAT | BUILTIN_DOUBLE, + EXTENSION_FUNCTION = 1ULL << 36U, + FUNCTIONAL_REFERENCE = 1ULL << 37U, + LAZY_IMPORT_OBJECT = 1ULL << 38U, + + ENUM_OBJECT = INT_ENUM_OBJECT | STRING_ENUM_OBJECT, + + BUILTIN_FLOATING_POINT = BUILTIN_DOUBLE | BUILTIN_FLOAT, + BUILTIN_INTEGRAL = BUILTIN_BYTE | BUILTIN_SHORT | BUILTIN_INT | BUILTIN_LONG, + + BUILTIN_ARRAY_INDEX = BUILTIN_BYTE | BUILTIN_SHORT | BUILTIN_INT, + BUILTIN_ARRAY_NUMERIC = BUILTIN_ARRAY_INDEX | BUILTIN_FLOATING_POINT, + + BUILTIN_NUMERIC = BUILTIN_INTEGRAL | BUILTIN_FLOATING_POINT, // Complete set includes null|undefined|Object VALUE_TYPED = BUILTIN_BOOLEAN | BUILTIN_CHAR | BUILTIN_NUMERIC | BUILTIN_BIGINT | STRING, UNBOXABLE_TYPE = BUILTIN_BOOLEAN | BUILTIN_CHAR | BUILTIN_NUMERIC, BUILTIN_TYPE = BUILTIN_STRING | BUILTIN_BIGINT | UNBOXABLE_TYPE, + CONVERTIBLE_TO_NUMERIC = BUILTIN_NUMERIC | BUILTIN_CHAR | INT_ENUM_OBJECT, GLOBAL_CLASS = CLASS | GLOBAL, FUNCTIONAL_INTERFACE = INTERFACE | ABSTRACT | FUNCTIONAL, @@ -87,6 +101,7 @@ enum class PropertySearchFlags : std::uint32_t { DISALLOW_SYNTHETIC_METHOD_CREATION = 1U << 10U, IS_SETTER = 1U << 11U, IS_GETTER = 1U << 12U, + IGNORE_OVERLOAD = 1U << 13U, SEARCH_INSTANCE = SEARCH_INSTANCE_FIELD | SEARCH_INSTANCE_METHOD | SEARCH_INSTANCE_DECL, SEARCH_STATIC = SEARCH_STATIC_FIELD | SEARCH_STATIC_METHOD | SEARCH_STATIC_DECL, @@ -107,12 +122,6 @@ enum class PropertyType { COUNT, }; -/* Invoke method name in functional interfaces */ -inline std::string FunctionalInterfaceInvokeName(size_t arity, bool hasRest) -{ - return (hasRest ? "invokeR" : "invoke") + std::to_string(arity); -} - } // namespace ark::es2panda::checker namespace enumbitops { diff --git a/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp b/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp index 14b55779761ae1d6d2230315da9696e72eaf0d35..9333d54633a9c357e64dde7d9bbdc270b617ec4d 100644 --- a/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp @@ -76,14 +76,21 @@ void ETSPartialTypeParameter::IsSubtypeOf(TypeRelation *relation, Type *target) relation->Result(false); if (target->IsETSPartialTypeParameter()) { relation->IsSupertypeOf(target->AsETSPartialTypeParameter()->GetUnderlying(), GetUnderlying()); + } else if (target->IsETSObjectType() && target->AsETSObjectType()->IsGlobalETSObjectType()) { + relation->IsSupertypeOf(target, GetUnderlying()); } } ETSPartialTypeParameter *ETSPartialTypeParameter::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) { - return allocator->New( - GetUnderlying()->Instantiate(allocator, relation, globalTypes)->AsETSTypeParameter(), checker_); + auto *underlying = GetUnderlying(); + ES2PANDA_ASSERT(underlying != nullptr); + auto *instantiated = underlying->Instantiate(allocator, relation, globalTypes); + ES2PANDA_ASSERT(instantiated != nullptr); + auto *typeParam = instantiated->AsETSTypeParameter(); + ES2PANDA_ASSERT(typeParam != nullptr); + return allocator->New(typeParam, checker_); } Type *ETSPartialTypeParameter::Substitute(TypeRelation *relation, const Substitution *substitution) diff --git a/ets2panda/checker/ets/narrowingWideningConverter.h b/ets2panda/checker/types/ets/etsResizableArrayType.cpp similarity index 48% rename from ets2panda/checker/ets/narrowingWideningConverter.h rename to ets2panda/checker/types/ets/etsResizableArrayType.cpp index 8aa21fea56ca759e8d6d5d6940406dd6d6c0212e..464207ceda8e4d8f2c71f898a8cdeb89990fdbe4 100644 --- a/ets2panda/checker/ets/narrowingWideningConverter.h +++ b/ets2panda/checker/types/ets/etsResizableArrayType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 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,25 +13,28 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_WIDENING_CONVERTER_H -#define ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_WIDENING_CONVERTER_H - -#include "checker/ets/narrowingConverter.h" -#include "checker/ets/wideningConverter.h" +#include "etsResizableArrayType.h" +#include "etsUnionType.h" namespace ark::es2panda::checker { -class NarrowingWideningConverter : public NarrowingConverter { -public: - explicit NarrowingWideningConverter(ETSChecker *checker, TypeRelation *relation, Type *target, Type *source) - : NarrowingConverter(checker, relation, target, source) - { - if (Relation()->IsTrue() || Relation()->IsError()) { - return; - } - WideningConverter(checker, relation, target, source); +ETSResizableArrayType *ETSResizableArrayType::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + auto copiedType = ETSObjectType::Substitute(relation, substitution)->AsETSResizableArrayType(); + element_ = TypeArguments()[0]; + return copiedType; +} + +void ETSResizableArrayType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const +{ + if (ElementType() != nullptr) { + if (HasTypeFlag(TypeFlag::READONLY)) { + ss << "readonly "; + } + ss << "Array<"; + ElementType()->ToString(ss, precise); + ss << ">"; } -}; -} // namespace ark::es2panda::checker +} -#endif +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.h b/ets2panda/checker/types/ets/etsResizableArrayType.h new file mode 100644 index 0000000000000000000000000000000000000000..90936ceadfbcb45ac54ccc707dc04d294f067d07 --- /dev/null +++ b/ets2panda/checker/types/ets/etsResizableArrayType.h @@ -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. + */ + +#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; + + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; + +private: + Type *element_; +}; + +} // namespace ark::es2panda::checker + +#endif diff --git a/ets2panda/checker/types/ets/etsStringType.cpp b/ets2panda/checker/types/ets/etsStringType.cpp index 648af3cc0137a144315bc3974bc6f456b31ed8b4..ef98c512f8887eff0ba6f19d14f95fa89d0d081b 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(); } @@ -84,15 +74,4 @@ void ETSStringType::IsSubtypeOf(TypeRelation *relation, Type *source) auto *const checker = relation->GetChecker()->AsETSChecker(); 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..40595517acbb04c5404a68a828a6f2674bc8ffc2 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -21,26 +21,26 @@ namespace ark::es2panda::checker { class ETSStringType : public ETSObjectType { public: - explicit ETSStringType(ArenaAllocator *allocator, ETSObjectType *super) - : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_STRING, nullptr, + explicit ETSStringType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super) + : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_STRING, super->GetDeclNode(), 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, + std::make_tuple(super->GetDeclNode(), ETSObjectFlags::CLASS | ETSObjectFlags::STRING | ETSObjectFlags::RESOLVED_SUPER, relation)) { 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, + std::make_tuple(super->GetDeclNode(), ETSObjectFlags::CLASS | ETSObjectFlags::STRING | ETSObjectFlags::RESOLVED_SUPER, relation)), value_(value) @@ -76,13 +76,6 @@ public: return value_; } - std::tuple ResolveConditionExpr() const override - { - 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 7a18c2ab036c33e5b9cafeea7fb4dfb25c704e21..38930b20a3a519e024ff6bba7b36b785e0619191 100644 --- a/ets2panda/checker/types/ets/etsTupleType.cpp +++ b/ets2panda/checker/types/ets/etsTupleType.cpp @@ -65,7 +65,9 @@ void ETSTupleType::ToDebugInfoType(std::stringstream &ss) const Type *ETSTupleType::GetTypeAtIndex(const TupleSizeType index) const { - ES2PANDA_ASSERT(index < GetTupleSize()); + if (index >= GetTupleSize()) { // happens when dealing with type errors + return nullptr; + } return GetTupleTypesList().at(index); } @@ -123,13 +125,13 @@ void ETSTupleType::AssignmentTarget(TypeRelation *const relation, Type *const so 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)); } - return checker->Allocator()->New(checker, std::move(newTypeList)); + return checker->ProgramAllocator()->New(checker, std::move(newTypeList)); } void ETSTupleType::IsSubtypeOf(TypeRelation *const relation, Type *target) @@ -196,6 +198,7 @@ Type *ETSTupleType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[ma { auto *const checker = relation->GetChecker()->AsETSChecker(); auto *const tupleType = allocator->New(checker, GetTupleTypesList()); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->typeFlags_ = typeFlags_; return tupleType; } diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 53418a226c933ef7bd6fe24e38d68bfc3ba130f4..f6a76125a9f8d2032f1526238b5be2e100543fef 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -28,7 +28,10 @@ public: explicit ETSTupleType(ETSChecker *checker, const ArenaVector &typeList) : Type(checker::TypeFlag::ETS_TUPLE), typeList_(typeList), - wrapperType_(checker->GlobalBuiltinTupleType(typeList_.size())->AsETSObjectType()) + // NOLINTNEXTLINE(readability-implicit-bool-conversion) + wrapperType_(checker->GlobalBuiltinTupleType(typeList_.size()) != nullptr + ? checker->GlobalBuiltinTupleType(typeList_.size())->AsETSObjectType() + : nullptr) { typeFlags_ |= TypeFlag::ETS_TUPLE; } @@ -43,11 +46,6 @@ public: return typeList_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] ETSObjectType *GetWrapperType() const { return wrapperType_; diff --git a/ets2panda/checker/types/ets/etsTypeAliasType.cpp b/ets2panda/checker/types/ets/etsTypeAliasType.cpp index 411b0bbe09f49f9b0f6b77f5f48c6c045bd031c6..c4394f5da3fe266019bd75c6910978978d6bd18b 100644 --- a/ets2panda/checker/types/ets/etsTypeAliasType.cpp +++ b/ets2panda/checker/types/ets/etsTypeAliasType.cpp @@ -250,41 +250,14 @@ bool ETSTypeAliasType::SubstituteTypeArgs(TypeRelation *const relation, ArenaVec for (auto *const arg : typeArguments_) { auto *const newArg = arg->Substitute(relation, substitution); - newTypeArgs.push_back(newArg); + ES2PANDA_ASSERT(newArg->IsETSReferenceType()); + newTypeArgs.emplace_back(newArg); anyChange = anyChange || (newArg != arg); } return anyChange; } -void ETSTypeAliasType::ApplySubstitution(TypeRelation *relation) -{ - ES2PANDA_ASSERT(base_ == nullptr); - - const util::StringView hash = relation->GetChecker()->AsETSChecker()->GetHashFromTypeArguments(typeArguments_); - EmplaceInstantiatedType(hash, this); - - auto getTypes = [this]() { - std::vector types; - - for (auto [name, type] : instantiationMap_) { - if (type->targetType_ == nullptr) { - types.push_back(type); - } - } - - return types; - }; - - std::vector types; - - while (!(types = getTypes(), types.empty())) { - for (auto type : types) { - type->SetTargetType(type->parent_->targetType_->Substitute(relation, type->substitution_)); - } - } -} - void ETSTypeAliasType::SetTypeArguments(ArenaVector typeArguments) { typeArguments_ = std::move(typeArguments); @@ -311,10 +284,13 @@ Type *ETSTypeAliasType::Substitute(TypeRelation *relation, const Substitution *s return copiedType; } + auto arenaSubst = checker->NewArenaSubstitution(); + std::copy(substitution->begin(), substitution->end(), std::inserter(*arenaSubst, arenaSubst->end())); + copiedType = checker->CreateETSTypeAliasType(name_, declNode_, isRecursive_); copiedType->base_ = base_ == nullptr ? this : base_; copiedType->parent_ = this; - copiedType->substitution_ = substitution; + copiedType->substitution_ = arenaSubst; copiedType->typeArguments_ = newTypeArgs; EmplaceInstantiatedType(hash, copiedType); diff --git a/ets2panda/checker/types/ets/etsTypeAliasType.h b/ets2panda/checker/types/ets/etsTypeAliasType.h index a0811891f9a32250542360191c57ad77fe7961e2..3146b63f51500953d1a669ee47eb22d94419eaf1 100644 --- a/ets2panda/checker/types/ets/etsTypeAliasType.h +++ b/ets2panda/checker/types/ets/etsTypeAliasType.h @@ -53,11 +53,6 @@ public: targetType_ = targetType; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetRecursive(bool value = true) { isRecursive_ = value; @@ -87,8 +82,6 @@ public: Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; - void ApplySubstitution(TypeRelation *relation); - void SetTypeArguments(ArenaVector typeArguments); private: @@ -112,7 +105,7 @@ private: Type *targetType_ = nullptr; InstantiationMap instantiationMap_; ArenaVector typeArguments_; - const Substitution *substitution_ = nullptr; + const ArenaSubstitution *substitution_ = nullptr; mutable bool recursionCount_ = false; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index 518a42441bc1d0493b3a90a4a549052fdf48b3b9..53c70fcfcc2cc884654aae6c0b78e1453262d4a5 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -127,6 +127,7 @@ Type *ETSTypeParameter::Instantiate([[maybe_unused]] ArenaAllocator *allocator, auto *const checker = relation->GetChecker()->AsETSChecker(); auto *const copiedType = checker->CreateTypeParameter(); + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->AddTypeFlag(TypeFlag::GENERIC); copiedType->SetDeclNode(GetDeclNode()); copiedType->SetDefaultType(GetDefaultType()); @@ -140,8 +141,14 @@ Type *ETSTypeParameter::Substitute([[maybe_unused]] TypeRelation *relation, cons if (substitution == nullptr || substitution->empty()) { return this; } - if (auto repl = substitution->find(GetOriginal()); repl != substitution->end()) { - // 22955: The result is sometimes primitve. Can be reproduced for type aliases + + auto *type = GetDeclNode()->Name()->Variable()->TsType(); + if (type->IsTypeError()) { + return this; + } + + if (auto repl = substitution->find(type->AsETSTypeParameter()); repl != substitution->end()) { + ES2PANDA_ASSERT(repl->second->IsETSReferenceType()); return repl->second; } return this; @@ -157,7 +164,7 @@ void ETSTypeParameter::ToDebugInfoType(std::stringstream &ss) const GetConstraintType()->ToDebugInfoType(ss); } -ETSTypeParameter *ETSTypeParameter::GetOriginal() const noexcept +ETSTypeParameter *ETSTypeParameter::GetOriginal() const { return GetDeclNode()->Name()->Variable()->TsType()->AsETSTypeParameter(); } diff --git a/ets2panda/checker/types/ets/etsTypeParameter.h b/ets2panda/checker/types/ets/etsTypeParameter.h index d38b1b7b1d11ac0349d5ceb04e8d4b8916fc91f0..7eb6908b4b6ed65630b2a4553d4d35ba362cbae8 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.h +++ b/ets2panda/checker/types/ets/etsTypeParameter.h @@ -38,7 +38,7 @@ public: return declNode_; } - [[nodiscard]] ETSTypeParameter *GetOriginal() const noexcept; + [[nodiscard]] ETSTypeParameter *GetOriginal() const; [[nodiscard]] util::StringView const &Name() const noexcept; void SetDefaultType(Type *type) noexcept diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 2bbdf54442f4f6e4e746f7b52b6a3795a33aedc4..b927ff0afe924d258ec4e245a599525f8585d695 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -34,74 +34,125 @@ void ETSUnionType::ToString(std::stringstream &ss, bool precise) const void ETSUnionType::ToAssemblerType(std::stringstream &ss) const { - assemblerLub_->ToAssemblerTypeWithRank(ss); + ss << GetAssemblerType(); } void ETSUnionType::ToDebugInfoType(std::stringstream &ss) const { - assemblerLub_->ToDebugInfoType(ss); -} - -ETSUnionType::ETSUnionType(ETSChecker *checker, ArenaVector &&constituentTypes) - : Type(TypeFlag::ETS_UNION), constituentTypes_(std::move(constituentTypes)) -{ - ES2PANDA_ASSERT(constituentTypes_.size() > 1); - assemblerLub_ = ComputeAssemblerLUB(checker, this); + if (assemblerConstituentTypes_.size() == 1) { + assemblerConstituentTypes_[0]->ToDebugInfoType(ss); + return; + } + ss << "{U"; + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t idx = 0; idx < assemblerConstituentTypes_.size(); idx++) { + assemblerConstituentTypes_[idx]->ToDebugInfoType(ss); + if (idx != assemblerConstituentTypes_.size() - 1) { + ss << ","; + } + } + ss << "}"; } -bool ETSUnionType::EachTypeRelatedToSomeType(TypeRelation *relation, ETSUnionType *source, ETSUnionType *target) +static std::string GetAssemblerTypeString(Type *type) { - return std::all_of(source->constituentTypes_.begin(), source->constituentTypes_.end(), - [relation, target](auto *s) { return TypeRelatedToSomeType(relation, s, target); }); + std::stringstream ss; + type->ToAssemblerTypeWithRank(ss); + return ss.str(); } -bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, ETSUnionType *target) +void ETSUnionType::InitAssemblerTypeCache(ETSChecker *checker) { - return std::any_of(target->constituentTypes_.begin(), target->constituentTypes_.end(), - [relation, source](auto *t) { return relation->IsIdenticalTo(source, t); }); + ES2PANDA_ASSERT(!assemblerConstituentTypes_.empty()); + std::stringstream ss; + if (assemblerConstituentTypes_.size() == 1) { + assemblerConstituentTypes_[0]->ToAssemblerTypeWithRank(ss); + } else { + ss << "{U"; + for (size_t idx = 0; idx < assemblerConstituentTypes_.size(); idx++) { + if (idx != 0) { + ss << ","; + } + if (assemblerConstituentTypes_[idx]->IsETSNullType()) { + ss << compiler::Signatures::NULL_ASSEMBLY_TYPE; + continue; + } + assemblerConstituentTypes_[idx]->ToAssemblerTypeWithRank(ss); + } + ss << "}"; + } + assemblerTypeCache_ = util::UString(ss.str(), checker->ProgramAllocator()).View(); } -// This function computes effective runtime representation of union type -Type *ETSUnionType::ComputeAssemblerLUB(ETSChecker *checker, ETSUnionType *un) +void ETSUnionType::CanonicalizedAssemblerType(ETSChecker *checker) { - auto *const apparent = checker->GetApparentType(un); + auto *const apparent = checker->GetApparentType(this); if (!apparent->IsETSUnionType()) { - return apparent; + assemblerConstituentTypes_.push_back(apparent); + return; } - if (apparent != un) { - return apparent->AsETSUnionType()->assemblerLub_; + if (apparent != this) { + const auto &types = apparent->AsETSUnionType()->GetAssemblerTypes(); + assemblerConstituentTypes_.insert(assemblerConstituentTypes_.begin(), types.begin(), types.end()); + return; } - un = apparent->AsETSUnionType(); - - Type *lub = nullptr; - for (auto *t : un->ConstituentTypes()) { - if (t->IsTypeError()) { - return checker->GlobalTypeError(); - } - // NOTE(vpukhov): #19701 void refactoring - ES2PANDA_ASSERT(t->IsETSReferenceType() || t->IsETSVoidType()); - t = t->IsETSVoidType() ? checker->GlobalETSUndefinedType() : t; - if (lub == nullptr || lub->IsETSUndefinedType()) { - lub = t; + ES2PANDA_ASSERT(constituentTypes_.size() > 1); + bool hasNull = false; + for (auto *type : constituentTypes_) { + ES2PANDA_ASSERT(!type->IsETSUnionType()); + if (type->IsETSUndefinedType() || type->IsETSVoidType()) { continue; } - if (lub == t || t->IsETSUndefinedType()) { + if (type->IsETSNullType() && !hasNull) { + hasNull = true; + assemblerConstituentTypes_.push_back(type); continue; } - if (t->IsETSNullType()) { - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); + if (type->IsTypeError()) { + assemblerConstituentTypes_.clear(); + assemblerConstituentTypes_.push_back(checker->GlobalTypeError()); + return; } - if (t->IsETSObjectType() && lub->IsETSObjectType()) { - lub = checker->GetClosestCommonAncestor(lub->AsETSObjectType(), t->AsETSObjectType()); - } else if (t->IsETSArrayType() && lub->IsETSArrayType()) { - // NOTE: can compute "common(lub, t)[]" - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); - } else { - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); + auto found = + std::find_if(assemblerConstituentTypes_.begin(), assemblerConstituentTypes_.end(), + [&type](Type *t) { return GetAssemblerTypeString(type) == GetAssemblerTypeString(t); }); + if (found == assemblerConstituentTypes_.end()) { + assemblerConstituentTypes_.push_back(type); } } - return checker->GetNonConstantType(lub); + if (assemblerConstituentTypes_.empty()) { + assemblerConstituentTypes_.push_back(checker->GlobalETSObjectType()); + return; + } + if (assemblerConstituentTypes_.size() == 1) { + return; + } + + std::sort(assemblerConstituentTypes_.begin(), assemblerConstituentTypes_.end(), + [](Type *a, Type *b) { return GetAssemblerTypeString(a) < GetAssemblerTypeString(b); }); +} + +ETSUnionType::ETSUnionType(ETSChecker *checker, ArenaVector &&constituentTypes) + : Type(TypeFlag::ETS_UNION), + constituentTypes_(std::move(constituentTypes)), + assemblerConstituentTypes_(checker->ProgramAllocator()->Adapter()) +{ + ES2PANDA_ASSERT(constituentTypes_.size() > 1); + CanonicalizedAssemblerType(checker); + InitAssemblerTypeCache(checker); +} + +bool ETSUnionType::EachTypeRelatedToSomeType(TypeRelation *relation, ETSUnionType *source, ETSUnionType *target) +{ + return std::all_of(source->constituentTypes_.begin(), source->constituentTypes_.end(), + [relation, target](auto *s) { return TypeRelatedToSomeType(relation, s, target); }); +} + +bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, ETSUnionType *target) +{ + return std::any_of(target->constituentTypes_.begin(), target->constituentTypes_.end(), + [relation, source](auto *t) { return relation->IsIdenticalTo(source, t); }); } void ETSUnionType::Identical(TypeRelation *relation, Type *other) @@ -138,16 +189,7 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co return; } - if (std::any_of(constituentTypes_.begin(), constituentTypes_.end(), - [relation, refsource, relFn](auto *t) { return relFn(relation, refsource, t); })) { - if (refsource != source) { - // 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); - } + if (AnyOfConstituentTypes([relation, refsource, relFn](auto *t) { return relFn(relation, refsource, t); })) { relation->Result(true); return; } @@ -162,8 +204,8 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co if (relFn(relation, source, checker->MaybeUnboxType(ct))) { if (related) { AmbiguousUnionOperation(relation); + return; } - relation->GetNode()->SetBoxingUnboxingFlags(checker->GetBoxingFlag(ct)); related = true; } } @@ -173,98 +215,57 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co bool ETSUnionType::AssignmentSource(TypeRelation *relation, Type *target) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - if (target->HasTypeFlag(TypeFlag::PRIMITIVE)) { - if (!relation->ApplyUnboxing()) { - return relation->Result(false); - } - relation->GetNode()->SetBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(checker->MaybeUnboxType(target))); - } - - return relation->Result(std::all_of(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target](auto *t) { return relation->IsAssignableTo(t, target); })); + ES2PANDA_ASSERT(!target->IsETSPrimitiveType()); + return relation->Result( + AllOfConstituentTypes([relation, target](auto *t) { return relation->IsAssignableTo(t, target); })); } void ETSUnionType::AssignmentTarget(TypeRelation *relation, Type *source) { - auto const relFn = []([[maybe_unused]] TypeRelation *rel, [[maybe_unused]] Type *src, [[maybe_unused]] Type *tgt) { - return rel->IsAssignableTo(src, tgt); - }; + auto const relFn = [](TypeRelation *rel, Type *src, Type *tgt) { return rel->IsAssignableTo(src, tgt); }; RelationTarget(relation, source, relFn); } void ETSUnionType::Cast(TypeRelation *relation, Type *target) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - - if (target->HasTypeFlag(TypeFlag::PRIMITIVE)) { - if (!relation->ApplyUnboxing()) { - relation->Result(false); - return; - } - - relation->GetNode()->SetBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(checker->MaybeUnboxType(target))); - } + ES2PANDA_ASSERT(!target->IsETSPrimitiveType()); if (relation->InCastingContext()) { - relation->Result(std::any_of(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target](auto *t) { return relation->IsCastableTo(t, target); })); + relation->Result( + AnyOfConstituentTypes([relation, target](auto *t) { return relation->IsCastableTo(t, target); })); return; } - relation->Result(std::all_of(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target](auto *t) { return relation->IsCastableTo(t, target); })); + relation->Result(AllOfConstituentTypes([relation, target](auto *t) { return relation->IsCastableTo(t, target); })); } void ETSUnionType::CastTarget(TypeRelation *relation, Type *source) { - auto const relFn = []([[maybe_unused]] TypeRelation *rel, [[maybe_unused]] Type *src, [[maybe_unused]] Type *tgt) { - return rel->IsCastableTo(src, tgt); - }; + auto const relFn = [](TypeRelation *rel, Type *src, Type *tgt) -> bool { return rel->IsCastableTo(src, tgt); }; RelationTarget(relation, source, relFn); } -static auto constexpr ETS_NORMALIZABLE_NUMERIC = TypeFlag(TypeFlag::ETS_NUMERIC); - -static Type *LargestNumeric(Type *t1, Type *t2) -{ - static_assert(TypeFlag::DOUBLE > TypeFlag::FLOAT); - static_assert(TypeFlag::FLOAT > TypeFlag::LONG); - static_assert(TypeFlag::LONG > TypeFlag::INT); - static_assert(TypeFlag::INT > TypeFlag::SHORT); - static_assert(TypeFlag::SHORT > TypeFlag::BYTE); - - auto v1 = t1->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - auto v2 = t2->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v1)); - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v2)); - return v1 > v2 ? t1 : t2; -} - static std::optional TryMergeTypes(TypeRelation *relation, Type *const t1, Type *const t2) { - auto checker = relation->GetChecker()->AsETSChecker(); - auto never = checker->GetGlobalTypesHolder()->GlobalETSNeverType(); + auto *const checker = relation->GetChecker()->AsETSChecker(); + auto *const never = checker->GetGlobalTypesHolder()->GlobalETSNeverType(); + if (relation->IsSupertypeOf(t1, t2) || t2 == never) { return t1; } if (relation->IsSupertypeOf(t2, t1) || t1 == never) { return t2; } - // NOTE(vpukhov): numerics - clarification required return std::nullopt; } void ETSUnionType::LinearizeAndEraseIdentical(TypeRelation *relation, ArenaVector &types) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - // Linearize - size_t const initialSz = types.size(); - for (size_t i = 0; i < initialSz; ++i) { + std::size_t const initialSz = types.size(); + for (std::size_t i = 0U; i < initialSz; ++i) { auto ct = types[i]; + ES2PANDA_ASSERT(ct != nullptr); if (ct->IsETSUnionType()) { auto const &otherTypes = ct->AsETSUnionType()->ConstituentTypes(); types.insert(types.end(), otherTypes.begin(), otherTypes.end()); @@ -273,50 +274,32 @@ void ETSUnionType::LinearizeAndEraseIdentical(TypeRelation *relation, ArenaVecto types[i] = nullptr; } } - size_t insPos = 0; - for (size_t i = 0; i < types.size(); ++i) { - auto *const ct = types[i]; - if (ct != nullptr) { - types[insPos++] = ct; - } - } - types.resize(insPos); - // Promote primitives - for (auto &ct : types) { - ct = checker->MaybeBoxType(ct); - } + // Remove nullptrs + types.erase(std::remove_if(types.begin(), types.end(), [](Type *ct) { return ct == nullptr; }), types.end()); + // Reduce subtypes for (auto cmpIt = types.begin(); cmpIt != types.end(); ++cmpIt) { - for (auto it = std::next(cmpIt); it != types.end();) { - auto merged = TryMergeTypes(relation, *cmpIt, *it); - if (!merged) { + auto it = std::next(cmpIt); + while (it != types.end()) { + if (auto merged = TryMergeTypes(relation, *cmpIt, *it); !merged) { ++it; - continue; - } - - if (merged == *cmpIt) { + } else if (*merged == *cmpIt) { it = types.erase(it); - continue; + } else { + cmpIt = types.erase(cmpIt); + it = cmpIt != types.end() ? std::next(cmpIt) : cmpIt; } - - cmpIt = types.erase(cmpIt); - it = std::next(cmpIt); } } } void ETSUnionType::NormalizeTypes(TypeRelation *relation, ArenaVector &types) { - if (types.size() == 1) { - return; - } - auto const isNumeric = [](auto *ct) { return ct->HasTypeFlag(ETS_NORMALIZABLE_NUMERIC); }; - if (std::all_of(types.begin(), types.end(), isNumeric)) { - types[0] = std::accumulate(std::next(types.begin()), types.end(), types[0], LargestNumeric); - types.resize(1); + if (types.size() == 1U) { return; } + LinearizeAndEraseIdentical(relation, types); } @@ -325,7 +308,7 @@ Type *ETSUnionType::Instantiate(ArenaAllocator *allocator, TypeRelation *relatio auto *const checker = relation->GetChecker()->AsETSChecker(); ArenaVector copiedConstituents(allocator->Adapter()); for (auto *it : constituentTypes_) { - copiedConstituents.push_back(it->Instantiate(allocator, relation, globalTypes)); + copiedConstituents.emplace_back(it->Instantiate(allocator, relation, globalTypes)); } return checker->CreateETSUnionType(std::move(copiedConstituents)); } @@ -335,14 +318,14 @@ Type *ETSUnionType::Substitute(TypeRelation *relation, const Substitution *subst auto *const checker = relation->GetChecker()->AsETSChecker(); ArenaVector substitutedConstituents(checker->Allocator()->Adapter()); for (auto *ctype : constituentTypes_) { - substitutedConstituents.push_back(ctype->Substitute(relation, substitution)); + substitutedConstituents.emplace_back(ctype->Substitute(relation, substitution)); } return checker->CreateETSUnionType(std::move(substitutedConstituents)); } void ETSUnionType::IsSupertypeOf(TypeRelation *relation, Type *source) { - for (auto const &ctype : ConstituentTypes()) { + for (auto const *ctype : ConstituentTypes()) { if (relation->IsSupertypeOf(ctype, source)) { return; } @@ -351,7 +334,7 @@ void ETSUnionType::IsSupertypeOf(TypeRelation *relation, Type *source) void ETSUnionType::IsSubtypeOf(TypeRelation *relation, Type *target) { - for (auto const &ctype : ConstituentTypes()) { + for (auto const *ctype : ConstituentTypes()) { if (!relation->IsSupertypeOf(target, ctype)) { return; } @@ -360,138 +343,74 @@ void ETSUnionType::IsSubtypeOf(TypeRelation *relation, Type *target) void ETSUnionType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) { - for (auto const &ctype : ConstituentTypes()) { + for (auto *ctype : ConstituentTypes()) { relation->CheckVarianceRecursively(ctype, relation->TransferVariant(varianceFlag, VarianceFlag::COVARIANT)); } } -bool ETSUnionType::IsAssignableType(checker::Type *sourceType) const noexcept -{ - if (sourceType->IsETSTypeParameter() || sourceType->IsTypeError()) { - return true; - } - - if (sourceType->IsETSUnionType() || sourceType->IsETSArrayType() || sourceType->IsETSFunctionType()) { - return true; - } - - return false; -} - -checker::Type *ETSUnionType::HandleNumericPrecedence( - checker::ETSChecker *checker, checker::ETSObjectType *objectType, checker::Type *sourceType, - std::map &numericTypes) const noexcept +// ATTENTION! When calling this method we assume that 'AssignmentTarget(...)' check was passes successfully, +// thus the required assignable type (or corresponding supertype) always exists. +checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType, + [[maybe_unused]] std::optional value) const { - 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; + for (auto *ctype : ConstituentTypes()) { + if (checker->Relation()->IsSupertypeOf(ctype, sourceType)) { + return ctype; } } - 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 -{ - if (IsAssignableType(sourceType)) { - 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 (!sourceType->IsBuiltinNumeric()) { + return nullptr; } - if (checker::Type *assignableType = GetAssignableBuiltinType(checker, objectType, isBool, isChar, numericTypes); - assignableType != nullptr) { + // NOTE (DZ): we still keep 'numericTypes` collection for possible processing cases like 'let x: short|double = 1` + // Waiting for complete clearness in spec - now return the highest type in such a case or type itself. + // Maybe 'value' will be used for this purpose + std::map numericTypes {}; + auto *objectType = sourceType->AsETSObjectType(); + if (auto *assignableType = GetAssignableBuiltinType(checker, objectType, numericTypes); assignableType != nullptr) { return assignableType; } - if (auto *assignableType = HandleNumericPrecedence(checker, objectType, sourceType, numericTypes)) { - return assignableType; + if (!numericTypes.empty()) { + return (*std::prev(numericTypes.end())).second; } - - for (auto *constituentType : constituentTypes_) { - if (constituentType->IsETSObjectType() && constituentType->AsETSObjectType()->IsGlobalETSObjectType()) { - return constituentType; - } - } - - return checker->GlobalTypeError(); + return nullptr; } checker::Type *ETSUnionType::GetAssignableBuiltinType( - checker::ETSChecker *checker, checker::ETSObjectType *sourceType, bool const isBool, bool const isChar, - std::map &numericTypes) const noexcept + checker::ETSChecker *checker, checker::ETSObjectType *sourceType, + std::map &numericTypes) const { - checker::Type *assignableType = nullptr; - for (auto *constituentType : constituentTypes_) { if (!constituentType->IsETSObjectType() && !constituentType->IsETSTupleType()) { continue; } - auto *const type = constituentType->IsETSTupleType() ? constituentType->AsETSTupleType()->GetWrapperType() - : constituentType->AsETSObjectType(); - if (type->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { - if (isBool) { - assignableType = constituentType; - break; - } - } else if (type->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { - if (isChar) { - assignableType = constituentType; - break; - } - } else if (auto const id = ETSObjectType::GetPrecedence(checker, type); id > 0U) { - numericTypes.emplace(id, constituentType); - } else if (assignableType == nullptr && sourceType != nullptr && - checker->Relation()->IsSupertypeOf(type, sourceType)) { - assignableType = constituentType; + ETSObjectType *objectType = constituentType->AsETSObjectType(); + if (!objectType->IsBuiltinNumeric()) { + continue; + } + + if (checker->Relation()->IsIdenticalTo(objectType, sourceType)) { + return sourceType; } + + numericTypes.emplace(ETSObjectType::GetPrecedence(checker, objectType), objectType); } - return assignableType; + return nullptr; } -bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::ETSObjectType *sourceType, +bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::Type *source, ArenaVector &unionTypes) noexcept { - std::map::const_iterator> numericTypes {}; - bool const isBool = sourceType->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN); - bool const isChar = sourceType->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR); + source = checker->GetNonConstantType(source); bool rc = false; auto it = unionTypes.cbegin(); while (it != unionTypes.cend()) { - auto *constituentType = *it; + auto *constituentType = (*it)->MaybeBaseTypeOfGradualType(); // Because 'instanceof' expression does not check for type parameters, then for generic types we should // consider that expressions like 'SomeType' and 'SomeType' are identical for smart casting. // We also have to pass through all the union to process cases like 'C|A|B|C|undefined` @@ -499,74 +418,22 @@ bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::ETSObjectT constituentType = constituentType->AsETSTypeParameter()->GetConstraintType(); } else if (constituentType->HasTypeFlag(checker::TypeFlag::GENERIC)) { constituentType = constituentType->Clone(checker); + ES2PANDA_ASSERT(constituentType != nullptr); constituentType->RemoveTypeFlag(checker::TypeFlag::GENERIC); } - if (checker->Relation()->IsIdenticalTo(constituentType, sourceType)) { - rc = true; - it = unionTypes.erase(it); - continue; - } - - if (checker->Relation()->IsSupertypeOf(constituentType, sourceType)) { + if (checker->Relation()->IsIdenticalTo(constituentType, source)) { rc = true; - } else if (!rc && constituentType->IsETSObjectType()) { - auto *const objectType = (*it)->AsETSObjectType(); - if (isBool && objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { - unionTypes.erase(it); - return true; - } - - if (isChar && objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { - unionTypes.erase(it); - return true; - } - - if (auto const id = ETSObjectType::GetPrecedence(checker, objectType); id > 0U) { - numericTypes.emplace(id, it); - } - } - - ++it; - } - - if (rc) { - return true; - } - - if (auto const sourceId = ETSObjectType::GetPrecedence(checker, sourceType); sourceId > 0U) { - for (auto const [id, it1] : numericTypes) { - if (id >= sourceId) { - unionTypes.erase(it1); - return true; + if (!(*it)->IsETSTypeParameter()) { + it = unionTypes.erase(it); + continue; } } - } - - return false; -} - -bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::ETSArrayType *sourceType, - ArenaVector &unionTypes) noexcept -{ - auto it = unionTypes.cbegin(); - - bool rc = false; - while (it != unionTypes.cend()) { - auto *constituentType = *it; - if (constituentType->IsETSTypeParameter()) { - constituentType = constituentType->AsETSTypeParameter()->GetConstraintType(); - } - - if (checker->Relation()->IsIdenticalTo(constituentType, sourceType)) { - rc = true; - unionTypes.erase(it); - continue; - } - if (checker->Relation()->IsSupertypeOf(constituentType, sourceType)) { + if (checker->Relation()->IsSupertypeOf(constituentType, source)) { rc = true; } + ++it; } @@ -577,33 +444,34 @@ std::pair ETSUnionType::GetComplimentaryType(E checker::Type *sourceType) { ArenaVector unionTypes(checker->Allocator()->Adapter()); - for (auto *it : constituentTypes_) { - unionTypes.emplace_back(it); + for (auto *ct : constituentTypes_) { + unionTypes.emplace_back(ct->Clone(checker)); } - bool ok = true; - if (sourceType->IsETSUnionType()) { - for (auto *const constituentType : sourceType->AsETSUnionType()->ConstituentTypes()) { - if (ok = ExtractType(checker, constituentType->AsETSObjectType(), unionTypes); !ok) { - break; - } + auto const extractType = [checker, &unionTypes](Type *&type) -> bool { + ES2PANDA_ASSERT(!type->IsETSPrimitiveType()); + if (type->IsETSEnumType()) { + return true; } - } else if (sourceType->IsETSArrayType()) { - ok = ExtractType(checker, sourceType->AsETSArrayType(), unionTypes); - } else { - // NOTE(vpukhov): #19701 void refactoring - if (sourceType->IsETSPrimitiveType() && !sourceType->IsETSVoidType()) { - sourceType = checker->MaybeBoxInRelation(sourceType); - } else if (sourceType->HasTypeFlag(checker::TypeFlag::GENERIC)) { + if (type->HasTypeFlag(checker::TypeFlag::GENERIC)) { // Because 'instanceof' expression does not check for type parameters, then for generic types we should // consider that expressions like 'SomeType' and 'SomeType' are identical for smart casting. - sourceType = sourceType->Clone(checker); - sourceType->RemoveTypeFlag(checker::TypeFlag::GENERIC); + type = type->Clone(checker); + type->RemoveTypeFlag(checker::TypeFlag::GENERIC); } + return ExtractType(checker, type, unionTypes); + }; - if (sourceType->IsETSObjectType()) { - ok = ExtractType(checker, sourceType->AsETSObjectType(), unionTypes); + bool ok = true; + + if (sourceType->IsETSUnionType()) { + for (auto *constituentType : sourceType->AsETSUnionType()->ConstituentTypes()) { + if (ok = extractType(constituentType); !ok) { + break; + } } + } else { + ok = extractType(sourceType); } if (!ok) { @@ -611,7 +479,9 @@ std::pair ETSUnionType::GetComplimentaryType(E } checker::Type *complimentaryType; - if (unionTypes.size() == 1U) { + if (auto const size = unionTypes.size(); size == 0U) { + complimentaryType = checker->GetGlobalTypesHolder()->GlobalETSNeverType(); + } else if (size == 1U) { complimentaryType = unionTypes.front(); } else { complimentaryType = checker->CreateETSUnionType(std::move(unionTypes)); @@ -620,145 +490,24 @@ std::pair ETSUnionType::GetComplimentaryType(E return std::make_pair(sourceType, complimentaryType); } -Type *ETSUnionType::FindTypeIsCastableToThis(ir::Expression *node, TypeRelation *relation, Type *source) const +Type *ETSUnionType::FindUnboxableType() const noexcept { - ES2PANDA_ASSERT(node); - bool nodeWasSet = false; - if (relation->GetNode() == nullptr) { - nodeWasSet = true; - relation->SetNode(node); - } - // Prioritize object to object conversion - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [relation, source](Type *target) { - relation->IsCastableTo(source, target); - return relation->IsTrue() && source->IsETSReferenceType() && target->IsETSReferenceType(); - }); - if (it != constituentTypes_.end()) { - if (nodeWasSet) { - relation->SetNode(nullptr); - } - return *it; - } - it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [relation, source](Type *target) { - relation->IsCastableTo(source, target); - return relation->IsTrue(); - }); - if (nodeWasSet) { - relation->SetNode(nullptr); - } - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; + return FindSpecificType([](Type *t) { return t->IsETSUnboxableObject(); }); } -Type *ETSUnionType::FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const -{ - ES2PANDA_ASSERT(node); - bool nodeWasSet = false; - if (relation->GetNode() == nullptr) { - nodeWasSet = true; - relation->SetNode(node); - relation->SetFlags(TypeRelationFlag::CASTING_CONTEXT); - } - auto isCastablePred = [](TypeRelation *r, Type *sourceType, Type *targetType) { - if (targetType->IsETSUnionType()) { - auto *foundTargetType = targetType->AsETSUnionType()->FindTypeIsCastableToThis(r->GetNode(), r, sourceType); - r->Result(foundTargetType != nullptr); - } else { - r->IsCastableTo(sourceType, targetType); - } - return r->IsTrue(); - }; - // Prioritize object to object conversion - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { - return isCastablePred(relation, source, target) && source->IsETSReferenceType() && - target->IsETSReferenceType(); - }); // CC-OFF(G.FMT.02) project code style - if (it != constituentTypes_.end()) { - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - return *it; - } - it = std::find_if( - constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { return isCastablePred(relation, source, target); }); - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - -Type *ETSUnionType::FindUnboxableType() const -{ - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), - [](Type *t) { return t->IsETSUnboxableObject(); }); - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - -bool ETSUnionType::HasObjectType(ETSObjectFlags flag) const -{ - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [flag](Type *t) { - return t->IsETSObjectType() && t->AsETSObjectType()->HasObjectFlag(flag); - }); - return it != constituentTypes_.end(); -} - -Type *ETSUnionType::FindExactOrBoxedType(ETSChecker *checker, Type *const type) const -{ - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [checker, type](Type *ct) { - if (ct->IsETSUnboxableObject()) { - auto *const unboxedCt = checker->MaybeUnboxInRelation(ct); - return unboxedCt == type; - } - return ct == type; - }); - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - -std::tuple ETSUnionType::ResolveConditionExpr() const -{ - if (PossiblyETSString()) { - return {false, false}; - } - if (std::all_of(ConstituentTypes().begin(), ConstituentTypes().end(), - [](checker::Type const *ct) { return ct->DefinitelyETSNullish(); })) { - return {true, false}; - } - // We have to test if union can contain builtin numerics or string types to infer "true" - return {false, false}; -} - -bool ETSUnionType::HasType(Type *type) const -{ - for (const auto &cType : constituentTypes_) { - if (cType == type) { - return true; - } - } - return false; -} - -bool ETSUnionType::IsOverlapWith(TypeRelation *relation, Type *type) +bool ETSUnionType::IsOverlapWith(TypeRelation *relation, Type const *type) const noexcept { // NOTE(aakmaev): replace this func with intersection type when it will be implemented - for (auto const &ct : ConstituentTypes()) { + for (auto *ct : constituentTypes_) { if (type->IsETSUnionType() && type->AsETSUnionType()->IsOverlapWith(relation, ct)) { return true; } + if (type->IsETSObjectType() && ct->IsETSObjectType()) { + if (type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC) && + ct->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { + return true; + } + } if (relation->IsSupertypeOf(ct, type) || relation->IsSupertypeOf(type, ct)) { return true; } @@ -766,11 +515,11 @@ bool ETSUnionType::IsOverlapWith(TypeRelation *relation, Type *type) return false; } -ArenaVector ETSUnionType::GetNonConstantTypes(ETSChecker *checker, const ArenaVector &types) +ArenaVector ETSUnionType::GetNonConstantTypes(ETSChecker *checker) const noexcept { ArenaVector nonConstTypes(checker->Allocator()->Adapter()); - for (const auto &ct : types) { - nonConstTypes.push_back(checker->GetNonConstantType(ct)); + for (auto *ct : constituentTypes_) { + nonConstTypes.emplace_back(checker->GetNonConstantType(ct)); } return nonConstTypes; } diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 12ae980aec9d686f2561d43f4309aec0d3710229..0ae2e8a38bdf30728e7547aefc0292a7dea020fe 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -45,39 +45,47 @@ public: void IsSupertypeOf(TypeRelation *relation, Type *source) override; void IsSubtypeOf(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; - Type *FindTypeIsCastableToThis(ir::Expression *node, TypeRelation *relation, Type *source) const; - Type *FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const; - Type *FindUnboxableType() const; - bool HasObjectType(ETSObjectFlags flag) const; - bool HasType(Type *type) const; + [[nodiscard]] Type *FindUnboxableType() const noexcept; - bool IsOverlapWith(TypeRelation *relation, Type *type); - - Type *FindExactOrBoxedType(ETSChecker *checker, Type *type) const; + [[nodiscard]] bool IsOverlapWith(TypeRelation *relation, Type const *type) const noexcept; static void NormalizeTypes(TypeRelation *relation, ArenaVector &types); - static ArenaVector GetNonConstantTypes(ETSChecker *checker, const ArenaVector &types); - - std::tuple ResolveConditionExpr() const override; + [[nodiscard]] ArenaVector GetNonConstantTypes(ETSChecker *checker) const noexcept; - // Do not use it anywhere except codegen - Type *GetAssemblerLUB() const + const util::StringView &GetAssemblerType() const { - return assemblerLub_; + return assemblerTypeCache_; } template - bool AllOfConstituentTypes(UnaryPredicate p) const + [[nodiscard]] bool AllOfConstituentTypes(UnaryPredicate p) const noexcept { 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; + template + [[nodiscard]] bool AnyOfConstituentTypes(UnaryPredicate p) const noexcept + { + return std::any_of(constituentTypes_.cbegin(), constituentTypes_.cend(), p); + } + + template + [[nodiscard]] Type *FindSpecificType(UnaryPredicate p) const noexcept + { + auto const it = std::find_if(constituentTypes_.cbegin(), constituentTypes_.cend(), p); + return it != constituentTypes_.cend() ? *it : nullptr; + } + + template + [[nodiscard]] bool HasSpecificType(UnaryPredicate p) const noexcept + { + return FindSpecificType(p) != nullptr; + } + + [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType, + std::optional value) const; [[nodiscard]] std::pair GetComplimentaryType(ETSChecker *checker, checker::Type *sourceType); @@ -89,21 +97,24 @@ private: void RelationTarget(TypeRelation *relation, Type *source, RelFN const &relFn); static void LinearizeAndEraseIdentical(TypeRelation *relation, ArenaVector &types); - [[nodiscard]] static bool ExtractType(ETSChecker *checker, checker::ETSObjectType *sourceType, - ArenaVector &unionTypes) noexcept; - [[nodiscard]] static bool ExtractType(ETSChecker *checker, checker::ETSArrayType *sourceType, + [[nodiscard]] static bool ExtractType(ETSChecker *checker, checker::Type *source, ArenaVector &unionTypes) noexcept; [[nodiscard]] checker::Type *GetAssignableBuiltinType( - checker::ETSChecker *checker, checker::ETSObjectType *sourceType, bool isBool, bool isChar, - std::map &numericTypes) const noexcept; + checker::ETSChecker *checker, checker::ETSObjectType *sourceType, + std::map &numericTypes) const; - bool IsAssignableType(checker::Type *sourceType) const noexcept; + void CanonicalizedAssemblerType(ETSChecker *checker); + void InitAssemblerTypeCache(ETSChecker *checker); - static Type *ComputeAssemblerLUB(ETSChecker *checker, ETSUnionType *un); + const ArenaVector &GetAssemblerTypes() const + { + return assemblerConstituentTypes_; + } ArenaVector const constituentTypes_; - Type *assemblerLub_ {nullptr}; + ArenaVector assemblerConstituentTypes_; + util::StringView assemblerTypeCache_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsVoidType.cpp b/ets2panda/checker/types/ets/etsVoidType.cpp index bb3e90fb257d0bc0fb0a69f895d449c6e7b0192f..0fe7ede62002e0d284a5238d309d5957cef10b3d 100644 --- a/ets2panda/checker/types/ets/etsVoidType.cpp +++ b/ets2panda/checker/types/ets/etsVoidType.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 @@ void ETSVoidType::Identical(TypeRelation *relation, Type *other) } } +void ETSVoidType::IsSupertypeOf(TypeRelation *const relation, Type *source) +{ + relation->Result(source->IsETSUndefinedType()); +} + bool ETSVoidType::AssignmentSource(TypeRelation *relation, Type *target) { // NOTE(vpukhov): #19701 void refactoring diff --git a/ets2panda/checker/types/ets/etsVoidType.h b/ets2panda/checker/types/ets/etsVoidType.h index bf6f9fcf7ff8261ae4ffdec8213aa4f790a524e2..845d638d89b8a49fd592686f29dcbba5ea15f5ba 100644 --- a/ets2panda/checker/types/ets/etsVoidType.h +++ b/ets2panda/checker/types/ets/etsVoidType.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 @@ -26,6 +26,7 @@ public: void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override diff --git a/ets2panda/checker/types/ets/floatType.cpp b/ets2panda/checker/types/ets/floatType.cpp index 7f69458b1896ea368a70785d9f2cf810d9c0f092..958f338480b0afa1b7787edfc1f443222202edb5 100644 --- a/ets2panda/checker/types/ets/floatType.cpp +++ b/ets2panda/checker/types/ets/floatType.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 @@ -16,7 +16,7 @@ #include "floatType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/ets/wideningConverter.h" namespace ark::es2panda::checker { void FloatType::Identical(TypeRelation *relation, Type *other) @@ -28,10 +28,7 @@ void FloatType::Identical(TypeRelation *relation, Type *other) void FloatType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } bool FloatType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) @@ -57,38 +54,9 @@ void FloatType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/floatType.h b/ets2panda/checker/types/ets/floatType.h index 61f04f8e0b5b37eb34d2b1da22ac6f064d282b11..936effb4b0f1f59e8d5ccc5824f7e1653aab4277 100644 --- a/ets2panda/checker/types/ets/floatType.h +++ b/ets2panda/checker/types/ets/floatType.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 @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_FLOAT; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/intType.cpp b/ets2panda/checker/types/ets/intType.cpp index c21e904b086e871881b70036dd39fd804a7eae0c..3587ee1bc0b071c21700acadf8ecc3315412f5a6 100644 --- a/ets2panda/checker/types/ets/intType.cpp +++ b/ets2panda/checker/types/ets/intType.cpp @@ -16,7 +16,7 @@ #include "intType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/ets/wideningConverter.h" namespace ark::es2panda::checker { void IntType::Identical(TypeRelation *relation, Type *other) @@ -28,10 +28,7 @@ void IntType::Identical(TypeRelation *relation, Type *other) void IntType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } bool IntType::AssignmentSource(TypeRelation *relation, Type *target) @@ -57,38 +54,9 @@ void IntType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/intType.h b/ets2panda/checker/types/ets/intType.h index b1583a869578ff5243ca051353b4a963b54698aa..835cc47d612c7010193530b2196075b5350085c6 100644 --- a/ets2panda/checker/types/ets/intType.h +++ b/ets2panda/checker/types/ets/intType.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 @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/longType.cpp b/ets2panda/checker/types/ets/longType.cpp index 7f4d080115b80bcfc8306baef6c79224046bd87c..7b8c5b34fae0af6e8144ecc4412a82528e8c93ba 100644 --- a/ets2panda/checker/types/ets/longType.cpp +++ b/ets2panda/checker/types/ets/longType.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 @@ -16,7 +16,7 @@ #include "longType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/ets/wideningConverter.h" namespace ark::es2panda::checker { void LongType::Identical(TypeRelation *relation, Type *other) @@ -28,10 +28,7 @@ void LongType::Identical(TypeRelation *relation, Type *other) void LongType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } bool LongType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) @@ -57,38 +54,9 @@ void LongType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::FLOAT | TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/longType.h b/ets2panda/checker/types/ets/longType.h index 898b692072905d627d0f84b0138d0faf46161e87..0823bc7608f4840b9e2db740f130590ba8ee6cec 100644 --- a/ets2panda/checker/types/ets/longType.h +++ b/ets2panda/checker/types/ets/longType.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 @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/shortType.cpp b/ets2panda/checker/types/ets/shortType.cpp index bc2011294ba2ee8c3f735743c3f027abcbdacdc7..c7f79a229ea6be5b256578cf30154725121f5e93 100644 --- a/ets2panda/checker/types/ets/shortType.cpp +++ b/ets2panda/checker/types/ets/shortType.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 @@ -16,7 +16,7 @@ #include "shortType.h" #include "checker/ets/conversion.h" -#include "checker/ets/narrowingWideningConverter.h" +#include "checker/ets/wideningConverter.h" namespace ark::es2panda::checker { void ShortType::Identical(TypeRelation *relation, Type *other) @@ -28,10 +28,7 @@ void ShortType::Identical(TypeRelation *relation, Type *other) void ShortType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } - NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); + WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } bool ShortType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) @@ -57,38 +54,9 @@ void ShortType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::CHAR)) { - conversion::NarrowingPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { - conversion::WideningPrimitive(relation, this, target); - return; - } - - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { - conversion::Boxing(relation, this); - return; - } - - if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE)) { - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(target); - if (unboxedTarget == nullptr) { - conversion::Forbidden(relation); - return; - } - Cast(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return; - } - conversion::Forbidden(relation); - return; - } - - conversion::BoxingWideningReference(relation, this, target->AsETSObjectType()); + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT) && + target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { + conversion::Boxing(relation, this); return; } diff --git a/ets2panda/checker/types/ets/shortType.h b/ets2panda/checker/types/ets/shortType.h index 0cbd73ab16e223a284fa41bd1692c33588f48c6b..4b226806a322536a8c10bb03e5169d534fa8f2b1 100644 --- a/ets2panda/checker/types/ets/shortType.h +++ b/ets2panda/checker/types/ets/shortType.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 @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_SHORT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/types.h b/ets2panda/checker/types/ets/types.h index 89d59b801ed6bc0f632dd6dd7f7adf08473c41f8..e82a8fa0a503b690ae1cd7a15531ebfa873e4fd8 100644 --- a/ets2panda/checker/types/ets/types.h +++ b/ets2panda/checker/types/ets/types.h @@ -32,7 +32,6 @@ #include "etsBigIntType.h" #include "etsObjectType.h" #include "etsTypeAliasType.h" -#include "etsDynamicType.h" #include "etsArrayType.h" #include "wildcardType.h" #include "etsTypeParameter.h" @@ -40,6 +39,8 @@ #include "etsNullishTypes.h" #include "checker/types/signature.h" #include "etsReadonlyType.h" +#include "etsAnyType.h" #include "etsNeverType.h" +#include "etsEnumType.h" #endif /* TYPES_H */ diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 2644c1b7192f9c83e57987746f75fd2c0dc1e8f6..7219b11fdbbba992576e2827c85c178aae4e1b62 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -48,6 +48,7 @@ #include "checker/types/ets/etsNullishTypes.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/wildcardType.h" +#include "checker/types/ets/etsAnyType.h" #include "checker/types/ets/etsNeverType.h" #include "util/helpers.h" @@ -57,12 +58,14 @@ void GlobalTypesHolder::AddETSEscompatLayer() { // ETS escompat layer builtinNameMappings_.emplace("Array", GlobalTypeId::ETS_ARRAY_BUILTIN); + builtinNameMappings_.emplace("ReadonlyArray", GlobalTypeId::ETS_READONLY_ARRAY); builtinNameMappings_.emplace("Date", GlobalTypeId::ETS_DATE_BUILTIN); builtinNameMappings_.emplace("Error", GlobalTypeId::ETS_ERROR_BUILTIN); builtinNameMappings_.emplace("DivideByZeroError", GlobalTypeId::ETS_DIVIDE_BY_ZERO_ERROR_BUILTIN); 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); } @@ -83,7 +86,7 @@ void GlobalTypesHolder::AddFunctionTypes(ArenaAllocator *allocator) addTypes("LambdaR", GlobalTypeId::ETS_LAMBDAR0_CLASS, GlobalTypeId::ETS_LAMBDAR16_CLASS); builtinNameMappings_.emplace("FunctionN", GlobalTypeId::ETS_FUNCTIONN_CLASS); - builtinNameMappings_.emplace("LambdaN", GlobalTypeId::ETS_FUNCTIONN_CLASS); + builtinNameMappings_.emplace("LambdaN", GlobalTypeId::ETS_LAMBDAN_CLASS); } void GlobalTypesHolder::AddTupleTypes(ArenaAllocator *allocator) @@ -147,14 +150,18 @@ void GlobalTypesHolder::AddEtsSpecificTypes(ArenaAllocator *allocator) globalTypes_[static_cast(GlobalTypeId::ETS_UNDEFINED)] = allocator->New(); globalTypes_[static_cast(GlobalTypeId::ETS_WILDCARD)] = allocator->New(); globalTypes_[static_cast(GlobalTypeId::TYPE_ERROR)] = allocator->New(); + globalTypes_[static_cast(GlobalTypeId::ETS_ANY)] = allocator->New(false); + globalTypes_[static_cast(GlobalTypeId::ETS_RELAXED_ANY)] = allocator->New(true); globalTypes_[static_cast(GlobalTypeId::ETS_NEVER)] = allocator->New(); } void GlobalTypesHolder::AddEtsSpecificBuiltinTypes() { + builtinNameMappings_.emplace("Any", GlobalTypeId::ETS_ANY); builtinNameMappings_.emplace("Boolean", GlobalTypeId::ETS_BOOLEAN_BUILTIN); builtinNameMappings_.emplace("Byte", GlobalTypeId::ETS_BYTE_BUILTIN); builtinNameMappings_.emplace("Char", GlobalTypeId::ETS_CHAR_BUILTIN); + builtinNameMappings_.emplace("Class", GlobalTypeId::ETS_CLASS_BUILTIN); builtinNameMappings_.emplace("Comparable", GlobalTypeId::ETS_COMPARABLE_BUILTIN); builtinNameMappings_.emplace("Console", GlobalTypeId::ETS_CONSOLE_BUILTIN); builtinNameMappings_.emplace("Double", GlobalTypeId::ETS_DOUBLE_BUILTIN); @@ -164,6 +171,7 @@ void GlobalTypesHolder::AddEtsSpecificBuiltinTypes() builtinNameMappings_.emplace("Int", GlobalTypeId::ETS_INT_BUILTIN); builtinNameMappings_.emplace("Integral", GlobalTypeId::ETS_INTEGRAL_BUILTIN); builtinNameMappings_.emplace("Long", GlobalTypeId::ETS_LONG_BUILTIN); + builtinNameMappings_.emplace("Numeric", GlobalTypeId::ETS_NUMERIC_BUILTIN); builtinNameMappings_.emplace("Object", GlobalTypeId::ETS_OBJECT_BUILTIN); builtinNameMappings_.emplace("Runtime", GlobalTypeId::ETS_RUNTIME_BUILTIN); builtinNameMappings_.emplace("RuntimeLinker", GlobalTypeId::ETS_RUNTIME_LINKER_BUILTIN); @@ -216,10 +224,6 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *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); } Type *GlobalTypesHolder::GlobalNumberType() @@ -402,19 +406,29 @@ Type *GlobalTypesHolder::GlobalETSUndefinedType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_UNDEFINED)); } +Type *GlobalTypesHolder::GlobalETSAnyType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_ANY)); +} + +Type *GlobalTypesHolder::GlobalETSRelaxedAnyType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_RELAXED_ANY)); +} + Type *GlobalTypesHolder::GlobalETSNeverType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_NEVER)); } -Type *GlobalTypesHolder::GlobalETSNullishObjectType() +Type *GlobalTypesHolder::GlobalETSUnionUndefinedNullObject() { - return globalTypes_.at(static_cast(GlobalTypeId::ETS_NULLISH_OBJECT)); + return globalTypes_.at(static_cast(GlobalTypeId::ETS_UNION_UNDEFINED_NULL_OBJECT)); } -Type *GlobalTypesHolder::GlobalETSNullishType() +Type *GlobalTypesHolder::GlobalETSUnionUndefinedNull() { - return globalTypes_.at(static_cast(GlobalTypeId::ETS_NULLISH_TYPE)); + return globalTypes_.at(static_cast(GlobalTypeId::ETS_UNION_UNDEFINED_NULL)); } Type *GlobalTypesHolder::GlobalWildcardType() @@ -432,6 +446,11 @@ Type *GlobalTypesHolder::GlobalByteBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_BYTE_BUILTIN)); } +Type *GlobalTypesHolder::GlobalClassBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_CLASS_BUILTIN)); +} + Type *GlobalTypesHolder::GlobalCharBuiltinType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_CHAR_BUILTIN)); @@ -482,11 +501,21 @@ Type *GlobalTypesHolder::GlobalLongBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_LONG_BUILTIN)); } +Type *GlobalTypesHolder::GlobalNumericBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_NUMERIC_BUILTIN)); +} + 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)); @@ -602,19 +631,14 @@ Type *GlobalTypesHolder::GlobalArrayBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_ARRAY_BUILTIN)); } -Type *GlobalTypesHolder::GlobalBoxBuiltinType() +Type *GlobalTypesHolder::GlobalReadonlyArray() { - return globalTypes_.at(static_cast(GlobalTypeId::ETS_BOX_BUILTIN)); + return globalTypes_.at(static_cast(GlobalTypeId::ETS_READONLY_ARRAY)); } -Type *GlobalTypesHolder::GlobalJSRuntimeBuiltinType() -{ - return globalTypes_.at(static_cast(GlobalTypeId::ETS_INTEROP_JSRUNTIME_BUILTIN)); -} - -Type *GlobalTypesHolder::GlobalJSValueBuiltinType() +Type *GlobalTypesHolder::GlobalBoxBuiltinType() { - return globalTypes_.at(static_cast(GlobalTypeId::ETS_INTEROP_JSVALUE_BUILTIN)); + return globalTypes_.at(static_cast(GlobalTypeId::ETS_BOX_BUILTIN)); } Type *GlobalTypesHolder::GlobalBooleanBoxBuiltinType() diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index 39a9a1319ae20a609785df1b17c6481caa589ef7..d2392cf099b9b1168796c7f39ae233af63f974a4 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -16,7 +16,6 @@ #ifndef ES2PANDA_COMPILER_CHECKER_TYPES_GLOBAL_TYPES_HOLDER_H #define ES2PANDA_COMPILER_CHECKER_TYPES_GLOBAL_TYPES_HOLDER_H -#include "ir/astNodeFlags.h" #include "checker/types/type.h" namespace ark::es2panda::checker { @@ -57,12 +56,15 @@ enum class GlobalTypeId : std::size_t { ETS_OBJECT_BUILTIN, ETS_NULL, ETS_UNDEFINED, - ETS_NULLISH_TYPE, + ETS_UNION_UNDEFINED_NULL, + ETS_ANY, + ETS_RELAXED_ANY, ETS_NEVER, - ETS_NULLISH_OBJECT, + ETS_UNION_UNDEFINED_NULL_OBJECT, ETS_WILDCARD, ETS_BOOLEAN_BUILTIN, ETS_BYTE_BUILTIN, + ETS_CLASS_BUILTIN, ETS_CHAR_BUILTIN, ETS_COMPARABLE_BUILTIN, ETS_CONSOLE_BUILTIN, @@ -74,7 +76,9 @@ enum class GlobalTypeId : std::size_t { ETS_INT_BUILTIN, ETS_INTEGRAL_BUILTIN, ETS_LONG_BUILTIN, + ETS_NUMERIC_BUILTIN, ETS_MAP_BUILTIN, + ETS_RECORD_BUILTIN, ETS_ERROR_BUILTIN, ETS_RUNTIME_BUILTIN, ETS_RUNTIME_LINKER_BUILTIN, @@ -97,8 +101,6 @@ enum class GlobalTypeId : std::size_t { ETS_FUNCTION_BUILTIN, ETS_REGEXP_BUILTIN, ETS_ARRAY_BUILTIN, - ETS_INTEROP_JSRUNTIME_BUILTIN, - ETS_INTEROP_JSVALUE_BUILTIN, ETS_BOX_BUILTIN, ETS_BOOLEAN_BOX_BUILTIN, ETS_BYTE_BOX_BUILTIN, @@ -110,6 +112,8 @@ enum class GlobalTypeId : std::size_t { ETS_DOUBLE_BOX_BUILTIN, ETS_BIG_INT_BUILTIN, ETS_BIG_INT, + ETS_ARRAY, + ETS_READONLY_ARRAY, ETS_FUNCTION0_CLASS, ETS_FUNCTION1_CLASS, @@ -265,12 +269,15 @@ public: Type *GlobalETSObjectType(); Type *GlobalETSNullType(); Type *GlobalETSUndefinedType(); + Type *GlobalETSAnyType(); + Type *GlobalETSRelaxedAnyType(); Type *GlobalETSNeverType(); - Type *GlobalETSNullishType(); - Type *GlobalETSNullishObjectType(); + Type *GlobalETSUnionUndefinedNull(); + Type *GlobalETSUnionUndefinedNullObject(); Type *GlobalWildcardType(); Type *GlobalETSBooleanBuiltinType(); Type *GlobalByteBuiltinType(); + Type *GlobalClassBuiltinType(); Type *GlobalCharBuiltinType(); Type *GlobalComparableBuiltinType(); Type *GlobalConsoleBuiltinType(); @@ -281,6 +288,7 @@ public: Type *GlobalIntegerBuiltinType(); Type *GlobalIntegralBuiltinType(); Type *GlobalLongBuiltinType(); + Type *GlobalNumericBuiltinType(); Type *GlobalErrorBuiltinType(); Type *GlobalRuntimeBuiltinType(); Type *GlobalShortBuiltinType(); @@ -318,18 +326,16 @@ public: // ETS escompat layer Type *GlobalArrayBuiltinType(); + Type *GlobalReadonlyArray(); Type *GlobalAssertionErrorBuiltinType(); Type *GlobalDivideByZeroErrorBuiltinType(); Type *GlobalNullPointerErrorBuiltinType(); Type *GlobalUncaughtExceptionErrorBuiltinType(); Type *GlobalMapBuiltinType(); + Type *GlobalRecordBuiltinType(); Type *GlobalRegExpBuiltinType(); Type *GlobalSetBuiltinType(); - // JS specific types - Type *GlobalJSRuntimeBuiltinType(); - Type *GlobalJSValueBuiltinType(); - Type *GlobalTypeError(); void InitializeBuiltin(util::StringView name, Type *type); diff --git a/ets2panda/checker/types/gradualType.cpp b/ets2panda/checker/types/gradualType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ccf3f35b6c558b42ac42bcc1b1b6d1710b55c86f --- /dev/null +++ b/ets2panda/checker/types/gradualType.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 "gradualType.h" + +#include "checker/ETSchecker.h" +#include "checker/ets/conversion.h" + +namespace ark::es2panda::checker { +void GradualType::Identical(TypeRelation *relation, Type *other) +{ + if (other->IsGradualType()) { + baseType_->Identical(relation, other->AsGradualType()->GetBaseType()); + } else { + baseType_->Identical(relation, other); + } +} + +void GradualType::AssignmentTarget(TypeRelation *relation, Type *source) +{ + if (source->IsGradualType()) { + baseType_->AssignmentTarget(relation, source->AsGradualType()->GetBaseType()); + } else { + baseType_->AssignmentTarget(relation, source); + } +} + +bool GradualType::AssignmentSource(TypeRelation *relation, Type *target) +{ + if (target->IsGradualType()) { + return baseType_->AssignmentSource(relation, target->AsGradualType()->GetBaseType()); + } + return baseType_->AssignmentSource(relation, target); +} + +void GradualType::Compare(TypeRelation *relation, Type *other) +{ + if (other->IsGradualType()) { + baseType_->Compare(relation, other->AsGradualType()->GetBaseType()); + } else { + baseType_->Compare(relation, other); + } +} + +void GradualType::Cast(TypeRelation *relation, Type *target) +{ + if (target->IsGradualType()) { + baseType_->Cast(relation, target->AsGradualType()->GetBaseType()); + } else { + baseType_->Cast(relation, target); + } +} + +void GradualType::CastTarget(TypeRelation *relation, Type *source) +{ + if (source->IsGradualType()) { + baseType_->CastTarget(relation, source->AsGradualType()->GetBaseType()); + } else { + baseType_->CastTarget(relation, source); + } +} + +void GradualType::IsSubtypeOf(TypeRelation *relation, Type *target) +{ + if (target->IsGradualType()) { + baseType_->IsSubtypeOf(relation, target->AsGradualType()->GetBaseType()); + } else { + baseType_->IsSubtypeOf(relation, target); + } +} + +void GradualType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + if (source->IsGradualType()) { + relation->IsSupertypeOf(baseType_, source->AsGradualType()->GetBaseType()); + } else { + baseType_->IsSupertypeOf(relation, source); + } +} + +void GradualType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const +{ + baseType_->ToString(ss); +} + +Type *GradualType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) +{ + auto baseType = baseType_->Instantiate(allocator, relation, globalTypes); + return relation->GetChecker()->AsETSChecker()->CreateGradualType(baseType); +} + +Type *GradualType::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + return baseType_->Substitute(relation, substitution); +} + +void GradualType::ToAssemblerType(std::stringstream &ss) const +{ + baseType_->ToAssemblerType(ss); +} + +void GradualType::ToDebugInfoType(std::stringstream &ss) const +{ + baseType_->ToDebugInfoType(ss); +} + +void GradualType::ToAssemblerTypeWithRank(std::stringstream &ss) const +{ + baseType_->ToAssemblerTypeWithRank(ss); +} + +void GradualType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) +{ + // The type of array should be Invariant + relation->CheckVarianceRecursively(baseType_, varianceFlag); +} +} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/gradualType.h b/ets2panda/checker/types/gradualType.h new file mode 100644 index 0000000000000000000000000000000000000000..eb1978e8d64d03011ffa14443c8b8607c8559850 --- /dev/null +++ b/ets2panda/checker/types/gradualType.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 ES2PANDA_COMPILER_CHECKER_TYPES_GRADUAL_TYPE_H +#define ES2PANDA_COMPILER_CHECKER_TYPES_GRADUAL_TYPE_H + +#include "checker/types/type.h" +#include "ir/astNode.h" + +namespace ark::es2panda::checker { +class GradualType : public Type { +public: + explicit GradualType(checker::Type *baseType) + : Type(TypeFlag::GRADUAL_TYPE), baseType_(baseType), lang_(es2panda::Language(Language::Id::ETS)) + { + } + + explicit GradualType(checker::Type *baseType, Language lang) + : Type(TypeFlag::GRADUAL_TYPE), baseType_(baseType), lang_(lang) + { + } + + void Identical(TypeRelation *relation, Type *other) override; + void AssignmentTarget(TypeRelation *relation, Type *source) override; + bool AssignmentSource(TypeRelation *relation, Type *target) override; + void Compare(TypeRelation *relation, Type *other) override; + void Cast(TypeRelation *relation, Type *target) override; + void CastTarget(TypeRelation *relation, Type *source) override; + void IsSubtypeOf(TypeRelation *relation, Type *target) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; + void ToString(std::stringstream &ss, bool precise) const override; + void ToAssemblerType(std::stringstream &ss) const override; + void ToDebugInfoType(std::stringstream &ss) const override; + void ToAssemblerTypeWithRank(std::stringstream &ss) const override; + Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; + Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; + + const Type *GetBaseType() const + { + auto baseType = baseType_; + while (baseType->IsGradualType()) { + baseType = baseType->AsGradualType()->BaseType(); + } + return baseType; + } + + Type *GetBaseType() + { + auto baseType = baseType_; + while (baseType->IsGradualType()) { + baseType = baseType->AsGradualType()->BaseType(); + } + return baseType; + } + + Type *BaseType() + { + return baseType_; + } + + Type *BaseType() const + { + return baseType_; + } + + es2panda::Language Language() const + { + return lang_; + } + +private: + Type *baseType_; + es2panda::Language lang_; +}; +} // namespace ark::es2panda::checker + +#endif \ No newline at end of file diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 34b2d8a74e3ada647e58b00c84a1ff81b9940f23..0aaeab306651b74f0c87a99d36bc33cd095b239f 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -32,10 +32,10 @@ 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); - + ES2PANDA_ASSERT(newSigInfo != nullptr); if (!signatureInfo_->typeParams.empty()) { for (auto *tparam : signatureInfo_->typeParams) { auto *newTparam = tparam->Substitute(relation, substitution); @@ -51,6 +51,10 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub if (newParamType != param->TsType()) { anyChange = true; newParam = param->Copy(allocator, param->Declaration()); + if (newParamType->IsETSVoidType()) { + // since `void` is not allowed to be used as param type + newParamType = checker->GlobalETSUndefinedType(); + } newParam->SetTsType(newParamType); } newSigInfo->params.push_back(newParam); @@ -82,6 +86,7 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub Signature *Signature::CreateSignatureForSubstitute(ArenaAllocator *allocator, SignatureInfo *sigInfo, Type *returnType) { auto *result = allocator->New(sigInfo, returnType, func_); + ES2PANDA_ASSERT(result != nullptr); result->flags_ = flags_; result->internalName_ = internalName_; result->ownerObj_ = ownerObj_; @@ -110,9 +115,9 @@ void Signature::ToAssemblerType(std::stringstream &ss) const Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) { SignatureInfo *copiedInfo = allocator->New(signatureInfo_, allocator); - + ES2PANDA_ASSERT(copiedInfo != nullptr); for (size_t idx = 0U; idx < signatureInfo_->params.size(); ++idx) { - auto *const paramType = signatureInfo_->params[idx]->TsType(); + auto *const paramType = signatureInfo_->params[idx]->TsType()->MaybeBaseTypeOfGradualType(); if (paramType->HasTypeFlag(TypeFlag::GENERIC) && paramType->IsETSObjectType()) { copiedInfo->params[idx]->SetTsType(paramType->Instantiate(allocator, relation, globalTypes)); auto originalTypeArgs = paramType->AsETSObjectType()->GetOriginalBaseType()->TypeArguments(); @@ -124,6 +129,7 @@ Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, Gl } auto *const copiedSignature = allocator->New(copiedInfo, returnType_, func_); + ES2PANDA_ASSERT(copiedSignature != nullptr); copiedSignature->flags_ = flags_; copiedSignature->internalName_ = internalName_; copiedSignature->ownerObj_ = ownerObj_; @@ -186,12 +192,6 @@ void Signature::ToString(std::stringstream &ss, const varbinder::Variable *varia } returnType_->ToString(ss, precise); - - if (HasSignatureFlag(SignatureFlags::THROWS)) { - ss << " throws"; - } else if (HasSignatureFlag(SignatureFlags::RETHROWS)) { - ss << " rethrows"; - } } std::string Signature::ToString() const @@ -287,14 +287,16 @@ 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); + ES2PANDA_ASSERT(sigInfo != nullptr); for (auto param : sigInfo->params) { param->SetTsType(checker->MaybeBoxType(param->TsType())); } auto *retType = checker->MaybeBoxType(returnType_); auto *resultSig = allocator->New(sigInfo, retType); + ES2PANDA_ASSERT(resultSig != nullptr); resultSig->flags_ = flags_; resultSig->SetOwner(Owner()); resultSig->SetOwnerVar(OwnerVar()); diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 2a4f8ec06d417aed65fdc416c2ac9a38ee6fd543..4051395469791c11047011856c61c70fa52f8dca 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -49,6 +49,7 @@ public: if (other->restVar != nullptr) { restVar = other->restVar->Copy(allocator, other->restVar->Declaration()); + ES2PANDA_ASSERT(restVar != nullptr); restVar->SetTsType(other->restVar->TsType()); } } @@ -90,6 +91,8 @@ enum class SignatureFlags : uint32_t { RETHROWS = 1U << 17U, EXTENSION_FUNCTION = 1U << 18U, DUPLICATE_ASM = 1U << 19U, + BRIDGE = 1U << 20U, + DEFAULT = 1U << 21U, INTERNAL_PROTECTED = INTERNAL | PROTECTED, GETTER_OR_SETTER = GETTER | SETTER, @@ -223,6 +226,11 @@ public: return signatureInfo_->restVar; } + [[nodiscard]] varbinder::LocalVariable *RestVar() noexcept + { + return signatureInfo_->restVar; + } + [[nodiscard]] uint8_t ProtectionFlag() const noexcept { if ((flags_ & SignatureFlags::PRIVATE) != 0) { diff --git a/ets2panda/checker/types/ts/interfaceType.cpp b/ets2panda/checker/types/ts/interfaceType.cpp index 724bee9caa8d13e7521140aece70a67359c3dacd..ff846e5d8ee23a37b1567938cd0789559647da71 100644 --- a/ets2panda/checker/types/ts/interfaceType.cpp +++ b/ets2panda/checker/types/ts/interfaceType.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -148,6 +148,7 @@ Type *InterfaceType::Instantiate(ArenaAllocator *allocator, TypeRelation *relati Type *newInterfaceType = allocator->New(allocator, name_, copiedDesc); + ES2PANDA_ASSERT(newInterfaceType != nullptr); for (auto *it : bases_) { newInterfaceType->AsObjectType()->AsInterfaceType()->AddBase( it->Instantiate(allocator, relation, globalTypes)->AsObjectType()); diff --git a/ets2panda/checker/types/ts/objectDescriptor.cpp b/ets2panda/checker/types/ts/objectDescriptor.cpp index a418e6815ba44d59aa5f44e684de97144d9447bd..ccd7d48a60bb566487fd5bd2f727025ea334ead7 100644 --- a/ets2panda/checker/types/ts/objectDescriptor.cpp +++ b/ets2panda/checker/types/ts/objectDescriptor.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -34,9 +34,11 @@ varbinder::LocalVariable *ObjectDescriptor::FindProperty(const util::StringView void ObjectDescriptor::Copy(ArenaAllocator *allocator, ObjectDescriptor *copiedDesc, TypeRelation *relation, GlobalTypesHolder *globalTypes) { + ES2PANDA_ASSERT(copiedDesc != nullptr); // copy by hand for (auto *it : properties) { auto *copiedProp = it->Copy(allocator, it->Declaration()); + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(it->TsType()->Instantiate(allocator, relation, globalTypes)); copiedDesc->properties.push_back(copiedProp); } diff --git a/ets2panda/checker/types/ts/unionType.cpp b/ets2panda/checker/types/ts/unionType.cpp index 8ba291ba7b360e44ee5e333de3e3ae6fd3557059..fe540ce69eed998cb223d590e9c936cbe6536e8e 100644 --- a/ets2panda/checker/types/ts/unionType.cpp +++ b/ets2panda/checker/types/ts/unionType.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -111,6 +111,7 @@ void UnionType::RemoveDuplicatedTypes(TypeRelation *relation, ArenaVectorHasConstituentFlag(TypeFlag::ANY)) { return globalTypesHolder->GlobalAnyType(); } @@ -184,6 +185,7 @@ Type *UnionType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, Type *newUnionType = allocator->New(allocator, std::move(copiedConstituents)); + ES2PANDA_ASSERT(newUnionType != nullptr); return HandleUnionType(newUnionType->AsUnionType(), globalTypes); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index b3cb8780497aac7fb57002db6d8332c71d9f69e4..694499259016b06b0bea17986aa1a3dc766f89e3 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -18,10 +18,23 @@ #include "checker/types/typeFlag.h" #include "checker/types/typeRelation.h" #include "checker/types/ets/etsObjectType.h" +#include "checker/types/gradualType.h" #include "checker/checker.h" namespace ark::es2panda::checker { +std::mutex Type::idLock_ {}; + +bool Type::IsETSResizableArrayType() const +{ + return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_ARRAY); +} + +bool Type::IsETSReadonlyArrayType() const +{ + return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_READONLY_ARRAY); +} + bool Type::IsETSStringType() const { return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::STRING); @@ -42,6 +55,11 @@ bool Type::IsETSAsyncFuncReturnType() const return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::ASYNC_FUNC_RETURN_TYPE); } +bool Type::IsBuiltinNumeric() const noexcept +{ + return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC); +} + bool Type::IsLambdaObject() const { if (IsETSObjectType() && (AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::FUNCTIONAL_INTERFACE) || @@ -136,7 +154,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) @@ -144,39 +162,18 @@ Type *Type::Substitute([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] return this; } -std::uint32_t Type::GetPrecedence(Type const *type) noexcept +bool IsTypeError(Type const *tp) { - ES2PANDA_ASSERT(type != nullptr); - if (type->HasTypeFlag(TypeFlag::BYTE)) { - return 1U; - } - if (type->HasTypeFlag(TypeFlag::CHAR)) { - return 2U; - } - if (type->HasTypeFlag(TypeFlag::SHORT)) { - return 3U; - } - if (type->HasTypeFlag(TypeFlag::INT)) { - return 4U; - } - if (type->HasTypeFlag(TypeFlag::LONG)) { - return 5U; - } - if (type->HasTypeFlag(TypeFlag::FLOAT)) { - return 6U; - } - if (type->HasTypeFlag(TypeFlag::DOUBLE)) { - return 7U; - } - if (type->HasTypeFlag(TypeFlag::BIGINT)) { - return 8U; - } - return 0U; + return tp != nullptr && tp->IsTypeError(); } -bool IsTypeError(Type const *tp) +Type *Type::MaybeBaseTypeOfGradualType() { - return tp != nullptr && tp->IsTypeError(); + auto res = this; + while (res->IsGradualType()) { + res = res->AsGradualType()->GetBaseType(); + } + return res; } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 423ad7b5c565e68d786506c28da9f94879624ece..91fceb516e6fed3db6a04cde2737cab1ce3eb8ac 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" @@ -28,12 +29,11 @@ class Variable; namespace ark::es2panda::checker { class ObjectDescriptor; class GlobalTypesHolder; -class ETSDynamicType; class ETSAsyncFuncReturnType; class ETSChecker; -class ETSDynamicFunctionType; class ETSTypeParameter; class ETSEnumType; +class GradualType; // CC-OFFNXT(G.PRE.02) name part // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -42,14 +42,18 @@ TYPE_MAPPING(DECLARE_TYPENAMES) #undef DECLARE_TYPENAMES class ETSStringType; class ETSBigIntType; +class ETSResizableArrayType; -using Substitution = ArenaMap; +using Substitution = std::map; +using ArenaSubstitution = ArenaMap; class Type { public: explicit Type(TypeFlag flag) : typeFlags_(flag) { - static uint64_t typeId = 0; + std::lock_guard lock(idLock_); + static uint32_t typeId = 0; + ES2PANDA_ASSERT(typeId < std::numeric_limits::max()); id_ = ++typeId; } @@ -57,6 +61,7 @@ public: NO_MOVE_SEMANTIC(Type); virtual ~Type() = default; + static std::mutex idLock_; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TYPE_IS_CHECKS(typeFlag, typeName) \ @@ -74,12 +79,20 @@ public: /* CC-OFFNXT(G.PRE.02) name part*/ \ typeName *As##typeName() \ { \ + if (IsTypeError()) { \ + LOG(INFO, ES2PANDA) << "Erroneous cast to '" << #typeName << "' type."; \ + throw std::exception(); \ + } \ ES2PANDA_ASSERT(Is##typeName()); \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \ return reinterpret_cast(this); /* CC-OFF(G.PRE.02) name part*/ \ } \ const typeName *As##typeName() const \ { \ + if (IsTypeError()) { \ + LOG(INFO, ES2PANDA) << "Erroneous cast to '" << #typeName << "' type."; \ + throw std::exception(); \ + } \ ES2PANDA_ASSERT(Is##typeName()); \ /* CC-OFFNXT(G.PRE.05) The macro is used to generate a function. Return is needed*/ \ return reinterpret_cast(this); \ @@ -87,17 +100,19 @@ public: TYPE_MAPPING(TYPE_AS_CASTS) #undef TYPE_AS_CASTS + bool IsETSResizableArrayType() const; + bool IsETSReadonlyArrayType() const; bool IsETSStringType() const; bool IsETSCharType() const; bool IsETSBigIntType() const; bool IsETSArrowType() const; bool IsETSMethodType() const; + bool IsETSRelaxedAnyType() const; bool IsETSPrimitiveType() const; bool IsETSReferenceType() const; bool IsETSAsyncFuncReturnType() const; bool IsETSUnboxableObject() const; bool IsETSPrimitiveOrEnumType() const; - bool IsETSResizableArrayType() const; bool PossiblyETSNull() const; bool PossiblyETSUndefined() const; @@ -109,6 +124,8 @@ public: bool PossiblyETSValueTyped() const; bool PossiblyETSValueTypedExceptNullish() const; + bool PossiblyInForeignDomain() const; + ETSStringType *AsETSStringType() { ES2PANDA_ASSERT(IsETSObjectType()); @@ -127,22 +144,19 @@ public: return reinterpret_cast(this); } - bool IsETSDynamicType() const + ETSResizableArrayType *AsETSResizableArrayType() { - return IsETSObjectType() && HasTypeFlag(TypeFlag::ETS_DYNAMIC_FLAG); + ES2PANDA_ASSERT(IsETSResizableArrayType()); + return reinterpret_cast(this); } - ETSDynamicType *AsETSDynamicType() + const ETSResizableArrayType *AsETSResizableArrayType() const { - ES2PANDA_ASSERT(IsETSDynamicType()); - return reinterpret_cast(this); + ES2PANDA_ASSERT(IsETSResizableArrayType()); + return reinterpret_cast(this); } - const ETSDynamicType *AsETSDynamicType() const - { - ES2PANDA_ASSERT(IsETSDynamicType()); - return reinterpret_cast(this); - } + [[nodiscard]] bool IsBuiltinNumeric() const noexcept; ETSAsyncFuncReturnType *AsETSAsyncFuncReturnType() { @@ -156,32 +170,17 @@ public: return reinterpret_cast(this); } - bool IsETSDynamicFunctionType() const - { - return TypeFlags() == TypeFlag::ETS_DYNAMIC_FUNCTION_TYPE; - } - - ETSDynamicFunctionType *AsETSDynamicFunctionType() - { - ES2PANDA_ASSERT(IsETSDynamicFunctionType()); - return reinterpret_cast(this); - } - - const ETSDynamicFunctionType *AsETSDynamicFunctionType() const + bool IsConstantType() const { - ES2PANDA_ASSERT(IsETSDynamicFunctionType()); - return reinterpret_cast(this); + return HasTypeFlag(checker::TypeFlag::CONSTANT); } - bool IsConditionalExprType() const + bool IsAnyETSArrayOrTupleType() const { - return HasTypeFlag(TypeFlag::CONDITION_EXPRESSION_TYPE); + return IsETSArrayType() || IsETSResizableArrayType() || IsETSReadonlyArrayType() || IsETSTupleType(); } - bool IsConstantType() const - { - return HasTypeFlag(checker::TypeFlag::CONSTANT); - } + Type *MaybeBaseTypeOfGradualType(); TypeFlag TypeFlags() const { @@ -203,7 +202,7 @@ public: typeFlags_ &= ~typeFlag; } - uint64_t Id() const + uint32_t Id() const { return id_; } @@ -254,15 +253,24 @@ public: ToAssemblerType(ss); } - virtual uint32_t Rank() const + std::string ToAssemblerType() const { - return 0; + std::stringstream ss; + ToAssemblerType(ss); + return ss.str(); } - virtual std::tuple ResolveConditionExpr() const + std::string ToAssemblerTypeWithRank() const { - ES2PANDA_UNREACHABLE(); - }; + std::stringstream ss; + ToAssemblerTypeWithRank(ss); + return ss.str(); + } + + virtual uint32_t Rank() const + { + return 0; + } virtual void Identical(TypeRelation *relation, Type *other); virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0; @@ -277,7 +285,6 @@ public: [[maybe_unused]] VarianceFlag varianceFlag) { } - [[nodiscard]] static std::uint32_t GetPrecedence(Type const *type) noexcept; virtual Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); [[nodiscard]] virtual Type *Clone(Checker *checker); @@ -287,7 +294,7 @@ protected: // NOLINTBEGIN(misc-non-private-member-variables-in-classes) TypeFlag typeFlags_; varbinder::Variable *variable_ {}; // Variable associated with the type if any - uint64_t id_; + uint32_t id_; // NOLINTEND(misc-non-private-member-variables-in-classes) }; diff --git a/ets2panda/checker/types/typeError.h b/ets2panda/checker/types/typeError.h index 9b2d87c4075983d6df1c4a553fad6b2c8f7b3a55..df378a1fa6a7f5954c2dcfee7fe5bbf3b4747588 100644 --- a/ets2panda/checker/types/typeError.h +++ b/ets2panda/checker/types/typeError.h @@ -42,8 +42,52 @@ public: { ss << ERROR_TYPE; } + + Type *Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, + [[maybe_unused]] GlobalTypesHolder *globalTypes) override + { + return this; + } }; } // namespace ark::es2panda::checker +// NOLINTBEGIN(cppcoreguidelines-macro-usage) +#define EMPTY_VALUE + +// CC-OFFNXT(G.PRE.02-CPP) TypeError handling macro definition +#define ERROR_SANITY_CHECK(etsChecker, test, whatIfFails) \ + if (!(test)) { \ + ES2PANDA_ASSERT((etsChecker)->IsAnyError()); \ + whatIfFails; \ + } + +// CC-OFFNXT(G.PRE.02-CPP) TypeError handling macro definition +#define ERROR_TYPE_CHECK(etsChecker, testType, whatIfError) \ + ES2PANDA_ASSERT((testType) != nullptr); \ + if ((testType)->IsTypeError()) { \ + ES2PANDA_ASSERT((etsChecker)->IsAnyError()); \ + whatIfError; \ + } + +// CC-OFFNXT(G.PRE.02-CPP) TypeError handling macro definition +#define FORWARD_TYPE_ERROR(etsChecker, testType, target) \ + ES2PANDA_ASSERT((testType) != nullptr); \ + if ((testType)->IsTypeError()) { \ + ES2PANDA_ASSERT((etsChecker)->IsAnyError()); \ + /* CC-OFFNXT(G.PRE.05) error handling. */ \ + return (target)->SetTsType((etsChecker)->GlobalTypeError()); \ + } + +// CC-OFFNXT(G.PRE.02-CPP) TypeError handling macro definition +#define FORWARD_VALUE_ON_TYPE_ERROR(etsChecker, testType, target, value) \ + ES2PANDA_ASSERT((testType) != nullptr); \ + if ((testType)->IsTypeError()) { \ + ES2PANDA_ASSERT((etsChecker)->IsAnyError()); \ + (target)->SetTsType((etsChecker)->GlobalTypeError()); \ + /* CC-OFFNXT(G.PRE.05) error handling. */ \ + return value; \ + } +// NOLINTEND(cppcoreguidelines-macro-usage) + #endif diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index 86e149f3a3d2ce2c4816b00280f55012f2b91548..9245b2a7e555d13ce6afbaecc5a089be94c76614 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -48,8 +48,7 @@ enum class TypeFlag : uint64_t { INTERSECTION = 1ULL << 19ULL, // x: a & b INDEX = 1ULL << 20ULL, // keyof x INDEX_ACCESS = 1ULL << 21ULL, // x[a] - CONDITIONAL = 1ULL << 22ULL, // x extends a ? b : c - TEMPLATE_LITERAL = 1ULL << 23ULL, // x: `hello ${World}` + ETS_AWAITED = 1ULL << 23ULL, // ETS Awaited type ANY = 1ULL << 24ULL, // x: any ARRAY = 1ULL << 25ULL, // x: number[] FUNCTION = 1ULL << 26ULL, // x: (a) => b @@ -70,11 +69,10 @@ enum class TypeFlag : uint64_t { ETS_ARRAY = 1ULL << 41ULL, // ETS array type WILDCARD = 1ULL << 42ULL, // new A() ETS_TYPE_PARAMETER = 1ULL << 43ULL, // ETS type parameter - ETS_TYPE_REFERENCE = 1ULL << 44ULL, // ETS type reference GENERIC = 1ULL << 45ULL, // ETS Generic ETS_INT_ENUM = 1ULL << 46ULL, // ETS Enum ETS_STRING_ENUM = 1ULL << 47ULL, // ETS string-type Enumeration - ETS_DYNAMIC_FLAG = 1ULL << 48ULL, // ETS Dynamic flag + GRADUAL_TYPE = 1ULL << 48ULL, // gradual type GETTER = 1ULL << 49ULL, // ETS Getter SETTER = 1ULL << 50ULL, // ETS Setter ETS_EXTENSION_FUNC_HELPER = 1ULL << 51ULL, // ETS Extension Function Helper @@ -88,21 +86,16 @@ enum class TypeFlag : uint64_t { ETS_PARTIAL_TYPE_PARAMETER = 1ULL << 59ULL, // ETS Partial type parameter TYPE_ERROR = 1ULL << 60ULL, // type error ETS_TYPE_ALIAS = 1ULL << 61ULL, // ETS Type alias + ETS_ANY = 1ULL << 22ULL, // ETS any, the value was *stolen* from the CONDITIONAL type kind ETS_NEVER = 1ULL << 62ULL, // ETS never ETS_METHOD = 1ULL << 63ULL, // ETS method (or function in module) (possibly overloaded) - ETS_DYNAMIC_TYPE = ETS_OBJECT | ETS_DYNAMIC_FLAG, - ETS_DYNAMIC_FUNCTION_TYPE = FUNCTION | ETS_DYNAMIC_FLAG, - ETS_TYPE = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_VOID | ETS_OBJECT | ETS_ARRAY | - FUNCTION | WILDCARD | ETS_TYPE_PARAMETER | ETS_DYNAMIC_TYPE | ETS_UNION | ETS_NULL | ETS_UNDEFINED | - ETS_NONNULLISH | ETS_READONLY | ETS_REQUIRED_TYPE_PARAMETER | ETS_PARTIAL_TYPE_PARAMETER | ETS_NEVER | - ETS_TUPLE, ETS_INTEGRAL_NUMERIC = BYTE | SHORT | INT | LONG, ETS_FLOATING_POINT = FLOAT | DOUBLE, ETS_NUMERIC = ETS_INTEGRAL_NUMERIC | ETS_FLOATING_POINT, ETS_INTEGRAL = ETS_INTEGRAL_NUMERIC | CHAR, ETS_ENUM = ETS_INT_ENUM | ETS_STRING_ENUM, ETS_ARRAY_INDEX = BYTE | SHORT | INT, - ETS_CONVERTIBLE_TO_NUMERIC = ETS_NUMERIC | CHAR | ETS_INT_ENUM, + ETS_CONVERTIBLE_TO_NUMERIC = ETS_NUMERIC | CHAR | ETS_INT_ENUM, // NOTE char should be removed VALID_SWITCH_TYPE = ETS_INTEGRAL, ETS_ARRAY_OR_OBJECT = ETS_ARRAY | ETS_OBJECT, ANY_OR_UNKNOWN = ANY | UNKNOWN, @@ -123,9 +116,6 @@ enum class TypeFlag : uint64_t { VALID_ARITHMETIC_TYPE = ANY | NUMBER_LIKE | BIGINT_LIKE | ENUM, UNIT = LITERAL | UNDEFINED | NULL_TYPE, GETTER_SETTER = GETTER | SETTER, - CONDITION_EXPRESSION_TYPE = ETS_NULL | ETS_UNDEFINED | ETS_OBJECT | ETS_ARRAY | ETS_UNION | CONSTANT | BYTE | CHAR | - SHORT | INT | LONG | FLOAT | DOUBLE | ETS_BOOLEAN | ETS_INT_ENUM | ETS_STRING_ENUM | - FUNCTION | ETS_TUPLE, }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/typeMapping.h b/ets2panda/checker/types/typeMapping.h index 4964190828798d93cc53c3a26e0c5e4aabd8f83e..0ab8b04c640a65123ddad29a541726fe15ad6b5e 100644 --- a/ets2panda/checker/types/typeMapping.h +++ b/ets2panda/checker/types/typeMapping.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 @@ -53,6 +53,7 @@ _(TypeFlag::ETS_VOID, ETSVoidType) \ _(TypeFlag::ETS_NULL, ETSNullType) \ _(TypeFlag::ETS_UNDEFINED, ETSUndefinedType) \ + _(TypeFlag::ETS_ANY, ETSAnyType) \ _(TypeFlag::ETS_NEVER, ETSNeverType) \ _(TypeFlag::FUNCTION, ETSFunctionType) \ _(TypeFlag::ETS_OBJECT, ETSObjectType) \ @@ -63,6 +64,7 @@ _(TypeFlag::ETS_TYPE_PARAMETER, ETSTypeParameter) \ _(TypeFlag::ETS_NONNULLISH, ETSNonNullishType) \ _(TypeFlag::ETS_READONLY, ETSReadonlyType) \ + _(TypeFlag::ETS_AWAITED, ETSAwaitedType) \ _(TypeFlag::ETS_INT_ENUM, ETSIntEnumType) \ _(TypeFlag::ETS_STRING_ENUM, ETSStringEnumType) \ _(TypeFlag::ETS_ENUM, ETSEnumType) \ @@ -70,6 +72,7 @@ _(TypeFlag::ETS_TUPLE, ETSTupleType) \ _(TypeFlag::ETS_PARTIAL_TYPE_PARAMETER, ETSPartialTypeParameter) \ _(TypeFlag::TYPE_ERROR, TypeError) \ + _(TypeFlag::GRADUAL_TYPE, GradualType) \ _(TypeFlag::ETS_TYPE_ALIAS, ETSTypeAliasType) #define OBJECT_TYPE_MAPPING(_) \ diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 2a7bf8a2f9be59a6169df8fabe0274e5ba620e28..c4b2fbb0869b7b727e396bd6b0eafb50eb559609 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -23,30 +23,26 @@ 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, RelationType type) const { - if (result_ == RelationResult::CACHE_MISS) { - 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()) { + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + auto res = holder.Find(key); + if (res == nullptr) { return RelationResult::CACHE_MISS; } - if (res->second.type >= type && res->second.result == RelationResult::TRUE) { + if (res->type >= type && res->result == RelationResult::TRUE) { return RelationResult::TRUE; } - if (res->second.type <= type && res->second.result == RelationResult::FALSE) { + if (res->type <= type && res->result == RelationResult::FALSE) { return RelationResult::FALSE; } @@ -69,7 +65,8 @@ bool TypeRelation::IsIdenticalTo(Type *source, Type *target) checker_->ResolveStructuredTypeMembers(target); result_ = RelationResult::FALSE; target->Identical(this, source); - checker_->IdenticalResults().cached.insert({{source->Id(), target->Id()}, {result_, RelationType::IDENTICAL}}); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->IdenticalResults().Insert(key, {result_, RelationType::IDENTICAL}); } return IsTrue(); @@ -114,7 +111,6 @@ bool TypeRelation::IsIdenticalTo(IndexInfo *source, IndexInfo *target) return result_ == RelationResult::TRUE; } -// NOTE: applyNarrowing -> flag bool TypeRelation::IsAssignableTo(Type *source, Type *target) { if (source == target) { @@ -125,11 +121,15 @@ bool TypeRelation::IsAssignableTo(Type *source, Type *target) if (result_ == RelationResult::CACHE_MISS) { // NOTE: we support assigning T to Readonly, but do not support assigning Readonly to T // more details in spec + ES2PANDA_ASSERT(source != nullptr); + ES2PANDA_ASSERT(target != nullptr); if (source->HasTypeFlag(TypeFlag::READONLY) && !target->HasTypeFlag(TypeFlag::READONLY)) { result_ = RelationResult::FALSE; } + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); if (result_ != RelationResult::FALSE && IsIdenticalTo(source, target)) { + checker_->AssignableResults().Insert(key, {result_, RelationType::ASSIGNABLE}); return true; } @@ -144,8 +144,7 @@ bool TypeRelation::IsAssignableTo(Type *source, Type *target) } if (flags_ == TypeRelationFlag::NONE) { - checker_->AssignableResults().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::ASSIGNABLE}}); + checker_->AssignableResults().Insert(key, {result_, RelationType::ASSIGNABLE}); } } @@ -155,14 +154,8 @@ bool TypeRelation::IsAssignableTo(Type *source, Type *target) bool TypeRelation::IsComparableTo(Type *source, Type *target) { result_ = CacheLookup(source, target, checker_->ComparableResults(), RelationType::COMPARABLE); - - // NOTE: vpukhov. reimplement dynamic comparison and remove this check - if (source->IsETSDynamicType() || target->IsETSDynamicType()) { - if (!(source->IsETSDynamicType() && target->IsETSDynamicType())) { - return false; - } - } - + ES2PANDA_ASSERT(source != nullptr); + ES2PANDA_ASSERT(target != nullptr); if (result_ == RelationResult::CACHE_MISS) { if (IsAssignableTo(source, target)) { return true; @@ -170,8 +163,9 @@ bool TypeRelation::IsComparableTo(Type *source, Type *target) result_ = RelationResult::FALSE; target->Compare(this, source); - checker_->ComparableResults().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::COMPARABLE}}); + ES2PANDA_ASSERT(source != nullptr); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->ComparableResults().Insert(key, {result_, RelationType::COMPARABLE}); } return result_ == RelationResult::TRUE; @@ -193,12 +187,9 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) return false; } - // NOTE: Can't cache if the node has BoxingUnboxingFlags. These flags should be stored and restored on the node - // on cache hit. - if (UncheckedCast() && node_->GetBoxingUnboxingFlags() == ir::BoxingUnboxingFlags::NONE && - !node_->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { - checker_->UncheckedCastableResult().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::UNCHECKED_CASTABLE}}); + if (UncheckedCast() && !node_->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->UncheckedCastableResult().Insert(key, {result_, RelationType::UNCHECKED_CASTABLE}); } return true; @@ -209,21 +200,44 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) { - if (!target->IsETSReferenceType() || !source->IsETSReferenceType()) { + ETSChecker *checker = this->GetChecker()->AsETSChecker(); + + if (target == nullptr || source == nullptr) { return false; } + + if (target->IsETSUnionType() && source->IsETSObjectType()) { + Type *sourceUnboxedType = checker->MaybeUnboxType(source); + if (sourceUnboxedType == nullptr || !sourceUnboxedType->IsETSPrimitiveType()) { + return false; + } + Type *boxedUnionTarget = target->AsETSUnionType()->FindUnboxableType(); + if (boxedUnionTarget == nullptr) { + return false; + } + Type *targetUnboxedType = checker->MaybeUnboxType(boxedUnionTarget); + if (targetUnboxedType == nullptr || !targetUnboxedType->IsETSPrimitiveType()) { + return false; + } + bool res = this->Result(this->IsAssignableTo(sourceUnboxedType, target)); + return res; + } + if (!target->IsETSObjectType() || !source->IsETSObjectType()) { return false; } - if (!target->AsETSObjectType()->IsBoxedPrimitive() || !source->AsETSObjectType()->IsBoxedPrimitive()) { + + if (!target->AsETSObjectType()->IsBoxedPrimitive() && !source->AsETSObjectType()->IsBoxedPrimitive()) { return false; } - ETSChecker *checker = this->GetChecker()->AsETSChecker(); - Type *targetUnboxedType = checker->MaybeUnboxType(target); Type *sourceUnboxedType = checker->MaybeUnboxType(source); + if (source->IsETSIntEnumType()) { + targetUnboxedType = checker->GlobalIntType(); + } + if (targetUnboxedType == nullptr || sourceUnboxedType == nullptr) { return false; } @@ -231,33 +245,33 @@ bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) return false; } - return this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + bool res = this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + return res; } bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) { - if (super == sub) { + if (LIKELY(super == sub)) { return Result(true); } - if (sub == nullptr) { return false; } + if (super->IsETSPrimitiveType() != sub->IsETSPrimitiveType()) { + return false; + } result_ = CacheLookup(super, sub, checker_->SupertypeResults(), RelationType::SUPERTYPE); if (result_ == RelationResult::CACHE_MISS) { - if (IsIdenticalTo(super, sub)) { - return true; - } - - result_ = RelationResult::FALSE; - if (super->IsSupertypeOf(this, sub), !IsTrue()) { - sub->IsSubtypeOf(this, super); + if (!IsIdenticalTo(super, sub)) { + result_ = RelationResult::FALSE; + if (super->IsSupertypeOf(this, sub), !IsTrue()) { + sub->IsSubtypeOf(this, super); + } } - if (flags_ == TypeRelationFlag::NONE) { - checker_->SupertypeResults().cached.insert({{super->Id(), sub->Id()}, {result_, RelationType::SUPERTYPE}}); - } + auto key = RelationHolder::MakeKey(super->Id(), sub->Id()); + checker_->SupertypeResults().Insert(key, {result_, RelationType::SUPERTYPE}); } return result_ == RelationResult::TRUE; diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 4fadbde95edcf70b50e043e8e2da9d2b11492897..33c32e789cfada5d83580cd839f5aacf80fa48e5 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" @@ -36,7 +37,6 @@ using ENUMBITOPS_OPERATORS; enum class TypeRelationFlag : uint32_t { NONE = 0U, - NARROWING = 1U << 0U, WIDENING = 1U << 1U, BOXING = 1U << 2U, UNBOXING = 1U << 3U, @@ -63,15 +63,17 @@ enum class TypeRelationFlag : uint32_t { OVERRIDING_CONTEXT = 1U << 25U, IGNORE_REST_PARAM = 1U << 26U, STRING_TO_CHAR = 1U << 27U, + OVERLOADING_CONTEXT = 1U << 28U, + NO_SUBSTITUTION_NEEDED = 1U << 29U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, - BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS | NO_RETURN_TYPE_CHECK, - CASTING_CONTEXT = NARROWING | WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, + BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS, + CASTING_CONTEXT = WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, }; -enum class RelationResult { TRUE, FALSE, UNKNOWN, MAYBE, CACHE_MISS, ERROR }; +enum class RelationResult : uint8_t { TRUE, FALSE, UNKNOWN, MAYBE, CACHE_MISS, ERROR }; -enum class RelationType { COMPARABLE, ASSIGNABLE, IDENTICAL, UNCHECKED_CASTABLE, SUPERTYPE }; +enum class RelationType : uint8_t { COMPARABLE, ASSIGNABLE, IDENTICAL, UNCHECKED_CASTABLE, SUPERTYPE }; enum class VarianceFlag { COVARIANT, CONTRAVARIANT, INVARIANT }; @@ -83,40 +85,45 @@ struct enumbitops::IsAllowedType : std namespace ark::es2panda::checker { -class RelationKey { +class RelationHolder { public: - uint64_t sourceId; - uint64_t targetId; -}; + using RelationKey = uint64_t; -class RelationKeyHasher { -public: - size_t operator()(const RelationKey &key) const noexcept + class RelationEntry { + public: + RelationResult result; + RelationType type; + }; + + explicit RelationHolder(ThreadSafeArenaAllocator *allocator) : cached_(allocator->Adapter()) {} + + static RelationKey MakeKey(uint32_t sourceId, uint32_t targetId) { - return static_cast(key.sourceId ^ key.targetId); + constexpr size_t U32_NR_BITS = 32; // CC-OFF(G.NAM.03-CPP) project code style + return (static_cast(sourceId) << U32_NR_BITS) | targetId; } -}; -class RelationKeyComparator { -public: - bool operator()(const RelationKey &lhs, const RelationKey &rhs) const + const RelationEntry *Find(RelationKey key) const { - return lhs.sourceId == rhs.sourceId && lhs.targetId == rhs.targetId; + auto it = cached_.find(key); + if (it == cached_.cend()) { + return nullptr; + } + return &it->second; } -}; -class RelationEntry { -public: - RelationResult result; - RelationType type; -}; + void Insert(RelationKey key, RelationEntry entry) + { + cached_.insert({key, entry}); + } -using RelationMap = std::unordered_map; + void Clear() + { + cached_.clear(); + } -class RelationHolder { -public: - RelationMap cached; - RelationType type {}; +private: + ArenaUnorderedMap cached_; }; class TypeRelation { @@ -136,11 +143,6 @@ public: return result_ == RelationResult::ERROR; } - bool ApplyNarrowing() const - { - return (flags_ & TypeRelationFlag::NARROWING) != 0; - } - bool ApplyWidening() const { return (flags_ & TypeRelationFlag::WIDENING) != 0; @@ -156,11 +158,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 +231,11 @@ public: return checker_; } + void SetChecker(Checker *checker) + { + checker_ = checker; + } + ir::Expression *GetNode() const { return node_; @@ -246,6 +248,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 +265,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; @@ -307,7 +312,6 @@ public: void RaiseError(const diagnostic::DiagnosticKind &kind, const lexer::SourcePosition &loc) const; void RaiseError(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const; - void LogError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const; bool Result(bool res) { @@ -343,6 +347,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/cmake/PandaCmakeFunctions.cmake b/ets2panda/cmake/PandaCmakeFunctions.cmake new file mode 100644 index 0000000000000000000000000000000000000000..a698304d3a14ad355e84b3c942b593317a7b0441 --- /dev/null +++ b/ets2panda/cmake/PandaCmakeFunctions.cmake @@ -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. + +# 32-bits pointers optimization in Panda for objects => addresses usage low 4GB +# We need use linker scripts for section replacement above 4GB +# Note: AddressSanitizer reserves (mmap) addresses for its own needs, +# so we have difference start addresses for asan and default buildings + +function(panda_frontend_add_executable target) + if(PANDA_FRONTEND_BUILD) + set(ARGV "${ARGV};FORCE_REBUILD") + endif() + panda_add_executable(${ARGV}) +endfunction() + +function(panda_frontend_add_library target) + if(PANDA_FRONTEND_BUILD) + set(ARGV "${ARGV};FORCE_REBUILD") + endif() + panda_add_library(${ARGV}) +endfunction() diff --git a/ets2panda/cmake/coverage.cmake b/ets2panda/cmake/coverage.cmake index d0233f52758fb02a0f7af9799b89969508e5a6b7..e9a3af2269c7e01040caf3cb035dae0893cfd3a1 100644 --- a/ets2panda/cmake/coverage.cmake +++ b/ets2panda/cmake/coverage.cmake @@ -18,7 +18,7 @@ include(${PANDA_ROOT}/cmake/toolchain/coverage/unit_tests_lcov.cmake) add_custom_target(es2panda_coverage DEPENDS etsstdlib es2panda verifier ark) if (NOT DEFINED ES2PANDA_PATH) - set(ES2PANDA_PATH ${PANDA_ROOT}/tools/es2panda) + file(REAL_PATH ${PANDA_ROOT}/tools/es2panda ES2PANDA_PATH) endif() add_custom_command(TARGET es2panda_coverage POST_BUILD diff --git a/ets2panda/compiler/base/condition.cpp b/ets2panda/compiler/base/condition.cpp index c8a7d0de4dbbc06d728f934d25c777bec1edc21a..e0ebfb209d394f0c6fa1371fc705cf0490346194 100644 --- a/ets2panda/compiler/base/condition.cpp +++ b/ets2panda/compiler/base/condition.cpp @@ -15,6 +15,7 @@ #include "condition.h" +#include "checker/ETSAnalyzerHelpers.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/expressions/assignmentExpression.h" @@ -235,7 +236,6 @@ void Condition::Compile(ETSGen *etsg, const ir::Expression *expr, Label *falseLa etsg->BranchIfTrue(expr, falseLabel); return; } - ES2PANDA_ASSERT(expr->TsType()->IsConditionalExprType()); expr->Compile(etsg); etsg->ApplyConversion(expr, etsg->Checker()->GlobalETSBooleanType()); etsg->ResolveConditionalResultIfFalse(expr, falseLabel); diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index 2b0f685dd595b88d6fb13b6ef64a11d1ae322157..852eb72ba2fbe9f75eaa01bd76326b106a6a5c3c 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -69,6 +69,10 @@ LReference::LReferenceBase LReference::CreateBase(CodeGen *cg, const ir::AstNode case ir::AstNodeType::TS_NON_NULL_EXPRESSION: { return CreateBase(cg, node->AsTSNonNullExpression()->Expr(), isDeclaration); } + case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION: { + ES2PANDA_ASSERT(node->AsETSNewClassInstanceExpression()->GetArguments().size() == 1); + return CreateBase(cg, node->AsETSNewClassInstanceExpression()->GetArguments()[0], isDeclaration); + } default: { ES2PANDA_UNREACHABLE(); } @@ -183,8 +187,8 @@ ETSLReference::ETSLReference(CodeGen *cg, const ir::AstNode *node, ReferenceKind const auto *memberExpr = Node()->AsMemberExpression(); staticObjRef_ = memberExpr->Object()->TsType(); - if (!memberExpr->IsComputed() && etsg_->Checker()->IsVariableStatic(memberExpr->PropVar()) && - !staticObjRef_->IsETSDynamicType()) { + if (!memberExpr->IsComputed() && memberExpr->PropVar() != nullptr && + etsg_->Checker()->IsVariableStatic(memberExpr->PropVar())) { return; } @@ -197,7 +201,8 @@ ETSLReference::ETSLReference(CodeGen *cg, const ir::AstNode *node, ReferenceKind TargetTypeContext pttctx(etsg_, memberExpr->Property()->TsType()); memberExpr->Property()->Compile(etsg_); etsg_->ApplyConversion(memberExpr->Property()); - ES2PANDA_ASSERT(etsg_->GetAccumulatorType()->HasTypeFlag(checker::TypeFlag::ETS_INTEGRAL)); + ES2PANDA_ASSERT(memberExpr->Object()->TsType()->IsETSAnyType() || + etsg_->GetAccumulatorType()->HasTypeFlag(checker::TypeFlag::ETS_INTEGRAL)); propReg_ = etsg_->AllocReg(); etsg_->StoreAccumulator(node, propReg_); } @@ -281,8 +286,12 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *memberExpr) con { const auto *const objectType = memberExpr->Object()->TsType(); - if (objectType->IsETSDynamicType()) { - etsg_->StoreElementDynamic(Node(), baseReg_, propReg_); + if (objectType->IsETSAnyType()) { + if (memberExpr->Property()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + etsg_->StoreByIndexAny(memberExpr, baseReg_, propReg_); + } else { + etsg_->StoreByValueAny(memberExpr, baseReg_, propReg_); + } return; } @@ -295,17 +304,26 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *memberExpr) con return; } - ES2PANDA_ASSERT(objectType->IsETSArrayType()); - etsg_->StoreArrayElement(Node(), baseReg_, propReg_, etsg_->GetVRegType(baseReg_)->AsETSArrayType()->ElementType()); + if (objectType->IsETSArrayType() || objectType->IsETSResizableArrayType()) { + auto vRegtype = etsg_->GetVRegType(baseReg_); + ES2PANDA_ASSERT(vRegtype != nullptr); + auto *elementType = vRegtype->IsETSArrayType() ? vRegtype->AsETSArrayType()->ElementType() + : vRegtype->AsETSResizableArrayType()->ElementType(); + etsg_->StoreArrayElement(Node(), baseReg_, propReg_, elementType); + return; + } + + ES2PANDA_ASSERT(objectType->IsETSNeverType()); // nothing to do, we're in dead code anyway } void ETSLReference::SetValueGetterSetter(const ir::MemberExpression *memberExpr) const { + ES2PANDA_ASSERT(memberExpr->PropVar() != nullptr); const auto *sig = memberExpr->PropVar()->TsType()->AsETSFunctionType()->FindSetter(); + ES2PANDA_ASSERT(sig->Function() != nullptr); auto argReg = etsg_->AllocReg(); etsg_->StoreAccumulator(Node(), argReg); - if (sig->Function()->IsStatic()) { etsg_->CallExact(Node(), sig->InternalName(), argReg); } else if (memberExpr->Object()->IsSuperExpression()) { @@ -324,6 +342,7 @@ void ETSLReference::SetValue() const const auto *const memberExpr = Node()->AsMemberExpression(); const auto *const memberExprTsType = memberExpr->TsType(); + auto const *objectType = memberExpr->Object()->TsType(); if (!memberExpr->IsIgnoreBox()) { etsg_->ApplyConversion(Node(), memberExprTsType); @@ -334,6 +353,12 @@ void ETSLReference::SetValue() const return; } + if (objectType->IsETSAnyType()) { + etsg_->StorePropertyByNameAny(memberExpr, baseReg_, memberExpr->Property()->AsIdentifier()->Name()); + return; + } + + ES2PANDA_ASSERT(memberExpr->PropVar() != nullptr); if (memberExpr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { SetValueGetterSetter(memberExpr); return; @@ -343,19 +368,8 @@ void ETSLReference::SetValue() const if (memberExpr->PropVar()->HasFlag(varbinder::VariableFlags::STATIC)) { const util::StringView fullName = etsg_->FormClassPropReference(staticObjRef_->AsETSObjectType(), propName); - if (staticObjRef_->IsETSDynamicType()) { - etsg_->StorePropertyDynamic(Node(), memberExprTsType, baseReg_, propName); - } else { - etsg_->StoreStaticProperty(Node(), memberExprTsType, fullName); - } - - return; - } - - auto const *objectType = memberExpr->Object()->TsType(); + etsg_->StoreStaticProperty(Node(), memberExprTsType, fullName); - if (objectType->IsETSDynamicType()) { - etsg_->StorePropertyDynamic(Node(), memberExprTsType, baseReg_, propName); return; } 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/CFG.cpp b/ets2panda/compiler/core/CFG.cpp index cfafe5d7922d24e1ebdbeb0be82e26b6c0d3d52a..701a766ef76d6906c28549e7b1959abe55aa113f 100644 --- a/ets2panda/compiler/core/CFG.cpp +++ b/ets2panda/compiler/core/CFG.cpp @@ -32,6 +32,7 @@ size_t CFG::BasicBlock::AddNode(ir::AstNode *node) std::pair CFG::BasicBlock::AddSuccessor(BasicBlock *successor) { + ES2PANDA_ASSERT(successor != nullptr); succs_.push_back(successor); successor->preds_.push_back(this); return std::make_pair(succs_.size() - 1, successor->preds_.size() - 1); @@ -200,6 +201,7 @@ CFG::BasicBlock *CFG::Build(ir::ScriptFunction *scriptFunctionNode) } BasicBlock *entryBB = CreateNewBB({}); + ES2PANDA_ASSERT(entryBB != nullptr); entryBB->SetFlag(BasicBlockFlags::ENTRY); functionNodeBBMap_[scriptFunctionNode] = entryBB; if (scriptFunctionNode->Id() != nullptr) { @@ -208,6 +210,7 @@ CFG::BasicBlock *CFG::Build(ir::ScriptFunction *scriptFunctionNode) } ES2PANDA_ASSERT(scriptFunctionNode->Body()->IsBlockStatement()); auto exitBB = Build(scriptFunctionNode->Body()->AsBlockStatement(), entryBB); + ES2PANDA_ASSERT(exitBB != nullptr); exitBB->SetFlag(BasicBlockFlags::EXIT); return entryBB; } @@ -231,6 +234,7 @@ CFG::BasicBlock *CFG::CreateNewBB(const std::vector &&preds, const std::vector &&labels) { auto bb = allocator_->New(allocator_, basicBlockIdx_++); + ES2PANDA_ASSERT(bb != nullptr); if (inLoop_ > 0) { bb->SetFlag(BasicBlockFlags::LOOP); } @@ -504,6 +508,7 @@ CFG::BasicBlock *CFG::Build(ir::WhileStatement *whileStatementNode, BasicBlock * { ++inLoop_; auto testBB = CreateNewBB({bb}); + ES2PANDA_ASSERT(testBB != nullptr); testBB->SetFlag(BasicBlockFlags::CONDITION); --inLoop_; auto falseBB = CreateNewBB({testBB}, {&falseLabel_}); @@ -512,6 +517,7 @@ CFG::BasicBlock *CFG::Build(ir::WhileStatement *whileStatementNode, BasicBlock * bb = Build(whileStatementNode->Test(), testBB); auto trueBB = CreateNewBB({bb}, {&trueLabel_}); trueBB = Build(whileStatementNode->Body(), trueBB); + ES2PANDA_ASSERT(trueBB != nullptr); trueBB->AddSuccessor(testBB); --inLoop_; return falseBB; @@ -522,12 +528,14 @@ CFG::BasicBlock *CFG::Build(ir::DoWhileStatement *doWhileStatementNode, BasicBlo ++inLoop_; auto bodyBB = CreateNewBB({bb}); auto testBB = CreateNewBB({}); + ES2PANDA_ASSERT(testBB != nullptr); testBB->SetFlag(BasicBlockFlags::CONDITION); --inLoop_; auto falseBB = CreateNewBB({testBB}, {&falseLabel_}); ++inLoop_; loopStmtJumpTargetMap_[doWhileStatementNode] = std::make_pair(testBB, falseBB); bb = Build(doWhileStatementNode->Body(), bodyBB); + ES2PANDA_ASSERT(bb != nullptr); testBB = Build(doWhileStatementNode->Test(), testBB); bb->AddSuccessor(testBB); AddBBEdge(testBB, bodyBB, &trueLabel_); @@ -633,6 +641,7 @@ CFG::BasicBlock *CFG::Build(ir::ForOfStatement *forOfStatementNode, BasicBlock * loopStmtJumpTargetMap_[forOfStatementNode] = std::make_pair(bb, nextBB); bb = Build(forOfStatementNode->Body(), bb); --inLoop_; + ES2PANDA_ASSERT(bb != nullptr); bb->AddSuccessor(loopBB); bb->AddSuccessor(nextBB); return nextBB; @@ -653,6 +662,7 @@ CFG::BasicBlock *CFG::Build(ir::ForUpdateStatement *forUpdateStatementNode, Basi testBB = Build(forUpdateStatementNode->Test(), testBB); auto bodyBB = Build(forUpdateStatementNode->Body(), trueBB); bodyBB = Build(forUpdateStatementNode->Update(), bodyBB); + ES2PANDA_ASSERT(bodyBB != nullptr); bodyBB->AddSuccessor(testBB); --inLoop_; return falseBB; @@ -664,6 +674,7 @@ CFG::BasicBlock *CFG::Build(ir::ForUpdateStatement *forUpdateStatementNode, Basi loopStmtJumpTargetMap_[forUpdateStatementNode] = std::make_pair(bodyStartBB, nextBB); auto bodyBB = Build(forUpdateStatementNode->Body(), bodyStartBB); bodyBB = Build(forUpdateStatementNode->Update(), bodyBB); + ES2PANDA_ASSERT(bodyBB != nullptr); bodyBB->AddSuccessor(bodyStartBB); --inLoop_; return nextBB; @@ -840,6 +851,7 @@ size_t CFG::AddNodeToBB(ir::AstNode *node, BasicBlock *bb) if (bb == nullptr) { bb = CreateNewBB({}); } + ES2PANDA_ASSERT(bb != nullptr); size_t index = bb->AddNode(node); nodeBBMap_[node] = std::make_pair(bb, index); return index; diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 2a24c1055fafb7859c77904e16dc5c56115b9e2b..fc921010efd67abd01808af32ff58f76ca59f6a1 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -16,15 +16,18 @@ #include "ETSCompiler.h" #include "compiler/base/catchTable.h" -#include "checker/ets/dynamic/dynamicCall.h" #include "compiler/base/condition.h" -#include "compiler/core/ETSGen-inl.h" #include "compiler/base/lreference.h" #include "compiler/core/switchBuilder.h" +#include "compiler/core/targetTypeContext.h" +#include "compiler/core/vReg.h" #include "compiler/function/functionBuilder.h" #include "checker/ETSchecker.h" -#include "checker/types/ets/etsDynamicFunctionType.h" #include "checker/types/ets/etsTupleType.h" +#include "ETSGen-inl.h" +#include "generated/signatures.h" +#include "util/es2pandaMacros.h" +#include "varbinder/ETSBinder.h" namespace ark::es2panda::compiler { @@ -53,15 +56,11 @@ void ETSCompiler::Compile(const ir::ClassProperty *st) const auto ttctx = compiler::TargetTypeContext(etsg, st->TsType()); compiler::RegScope rs(etsg); - ir::BoxingUnboxingFlags flags = - (st->Value() != nullptr) ? st->Value()->GetBoxingUnboxingFlags() : ir::BoxingUnboxingFlags::NONE; - if (st->Value() == nullptr) { etsg->LoadDefaultValue(st, st->TsType()); } else { st->Value()->Compile(etsg); etsg->ApplyConversion(st->Value(), st->TsType()); - st->Value()->SetBoxingUnboxingFlags(flags); } if (st->IsStatic()) { @@ -98,43 +97,15 @@ void ETSCompiler::Compile(const ir::ETSClassLiteral *expr) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); } -void ETSCompiler::Compile(const ir::ETSFunctionType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::ETSIntrinsicNode *node) const { - ETSGen *etsg = GetETSGen(); - etsg->LoadAccumulatorPoison(node, node->TsType()); + ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::ETSLaunchExpression *expr) const +void ETSCompiler::Compile(const ir::ETSFunctionType *node) 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 + etsg->LoadAccumulatorPoison(node, node->TsType()); } void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const @@ -171,8 +142,8 @@ void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const if (expr->Signature() != nullptr) { const compiler::TargetTypeContext ttctx2(etsg, elementType); - ArenaVector arguments(GetCodeGen()->Allocator()->Adapter()); - etsg->InitObject(expr, expr->Signature(), arguments); + static const ArenaVector ARGUMENTS(GetCodeGen()->Allocator()->Adapter()); + etsg->InitObject(expr, expr->Signature(), ARGUMENTS); } else { etsg->LoadAccumulatorPoison(expr, elementType); } @@ -189,44 +160,10 @@ void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); } -static std::pair LoadDynamicName(compiler::ETSGen *etsg, const ir::AstNode *node, - const ArenaVector &dynName, bool isConstructor) -{ - auto *checker = const_cast(etsg->Checker()->AsETSChecker()); - auto *callNames = checker->DynamicCallNames(isConstructor); - - auto qnameStart = etsg->AllocReg(); - auto qnameLen = etsg->AllocReg(); - - TargetTypeContext ttctx(etsg, nullptr); // without this ints will be cast to JSValue - etsg->LoadAccumulatorInt(node, callNames->at(dynName)); - etsg->StoreAccumulator(node, qnameStart); - etsg->LoadAccumulatorInt(node, dynName.size()); - etsg->StoreAccumulator(node, qnameLen); - return {qnameStart, qnameLen}; -} - -static void CreateDynamicObject(const ir::AstNode *node, compiler::ETSGen *etsg, const ir::Expression *typeRef, - checker::Signature *signature, const ArenaVector &arguments) -{ - auto objReg = etsg->AllocReg(); - - auto callInfo = checker::DynamicCall::ResolveCall(etsg->VarBinder(), typeRef); - if (callInfo.obj->IsETSImportDeclaration()) { - etsg->LoadAccumulatorDynamicModule(node, callInfo.obj->AsETSImportDeclaration()); - } else { - callInfo.obj->Compile(etsg); - } - - etsg->StoreAccumulator(node, objReg); - - auto [qnameStart, qnameLen] = LoadDynamicName(etsg, node, callInfo.name, true); - etsg->CallDynamic(ETSGen::CallDynamicData {node, objReg, qnameStart}, qnameLen, signature, arguments); -} - 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); @@ -242,6 +179,7 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::E elements.emplace_back(expr->GetArguments()[i]); } auto *arrayExpression = checker->AllocNode(std::move(elements), checker->Allocator()); + ES2PANDA_ASSERT(arrayExpression != nullptr); arrayExpression->SetParent(const_cast(expr)); auto restType = expr->GetSignature()->RestVar()->TsType()->AsETSArrayType(); arrayExpression->SetTsType(restType); @@ -277,6 +215,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); } @@ -284,12 +224,10 @@ 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 - etsg->ApplyCastToBoxingFlags(st, ir::BoxingUnboxingFlags::BOX_TO_CHAR); - etsg->EmitBoxingConversion(ir::BoxingUnboxingFlags::BOX_TO_CHAR, st); - etsg->CastToChar(st); + etsg->LoadStringChar(st, unionReg, *countReg, true); } } @@ -316,15 +254,17 @@ static void GetSizeInForOf(compiler::ETSGen *etsg, checker::Type const *const ex void ETSCompiler::Compile(const ir::ETSNewClassInstanceExpression *expr) const { ETSGen *etsg = GetETSGen(); - if (expr->TsType()->IsETSDynamicType()) { + + if (expr->TsType()->IsETSAnyType()) { compiler::RegScope rs(etsg); - auto *name = expr->GetTypeRef(); - CreateDynamicObject(expr, etsg, name, expr->signature_, expr->GetArguments()); + auto objReg = etsg->AllocReg(); + expr->GetTypeRef()->Compile(etsg); + etsg->StoreAccumulator(expr->GetTypeRef(), objReg); + etsg->CallAnyNew(expr, Span(expr->GetArguments()), objReg); } else { ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), expr); etsg->InitObject(expr, expr->signature_, expr->GetArguments()); } - etsg->SetAccumulatorType(expr->TsType()); } @@ -362,6 +302,11 @@ void ETSCompiler::Compile(const ir::ETSTypeReferencePart *node) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), node->TsType())); } +void ETSCompiler::Compile(const ir::OpaqueTypeNode *node) const +{ + GetETSGen()->SetAccumulatorType(node->TsType()); +} + void ETSCompiler::Compile([[maybe_unused]] const ir::ETSWildcardType *node) const { ES2PANDA_UNREACHABLE(); @@ -448,9 +393,7 @@ void ETSCompiler::Compile(const ir::AssignmentExpression *expr) const etsg->CreateBigIntObject(expr, value, Signatures::BUILTIN_BIGINT_CTOR_BIGINT); } - ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), exprType) || - etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), - etsg->Checker()->GlobalBuiltinJSValueType())); + ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), exprType)); lref.SetValue(); } @@ -551,6 +494,17 @@ static void CompileLogical(compiler::ETSGen *etsg, const ir::BinaryExpression *e etsg->SetAccumulatorType(expr->TsType()); } +static void CompileAnyInstanceOf(compiler::ETSGen *etsg, const VReg lhs, const ir::Expression *expr) +{ + RegScope rs(etsg); + VReg objReg = etsg->AllocReg(); + expr->Compile(etsg); + etsg->StoreAccumulator(expr, objReg); + etsg->LoadAccumulator(expr, lhs); + etsg->EmitAnyIsinstance(expr, objReg); + etsg->SetAccumulatorType(etsg->Checker()->GlobalETSBooleanType()); +} + static void CompileInstanceof(compiler::ETSGen *etsg, const ir::BinaryExpression *expr) { ES2PANDA_ASSERT(expr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF); @@ -561,13 +515,10 @@ static void CompileInstanceof(compiler::ETSGen *etsg, const ir::BinaryExpression expr->Left()->Compile(etsg); etsg->ApplyConversionAndStoreAccumulator(expr->Left(), lhs, expr->OperationType()); - if (expr->Left()->TsType()->IsETSDynamicType() || expr->Right()->TsType()->IsETSDynamicType()) { - auto rhs = etsg->AllocReg(); - expr->Right()->Compile(etsg); - etsg->StoreAccumulator(expr, rhs); - etsg->IsInstanceDynamic(expr, lhs, rhs); + auto target = expr->Right()->TsType(); + if (target->IsETSAnyType() && target->AsETSAnyType()->IsRelaxed()) { + CompileAnyInstanceOf(etsg, lhs, expr->Right()); } else { - auto target = expr->Right()->TsType(); etsg->IsInstance(expr, lhs, target); } ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); @@ -665,7 +616,7 @@ void ETSCompiler::Compile(const ir::BinaryExpression *expr) const compiler::VReg lhs = etsg->AllocReg(); if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS && expr->OperationType()->IsETSStringType()) { - etsg->BuildString(expr); + etsg->BuildString(expr, lhs); return; } @@ -681,7 +632,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); @@ -700,6 +652,7 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::C elements.emplace_back(expr->Arguments()[i]); } auto *arrayExpression = checker->AllocNode(std::move(elements), checker->Allocator()); + ES2PANDA_ASSERT(arrayExpression != nullptr); arrayExpression->SetParent(const_cast(expr)); auto restType = signature->RestVar()->TsType()->AsETSArrayType(); arrayExpression->SetTsType(restType); @@ -727,46 +680,58 @@ void ETSCompiler::Compile(const ir::BlockExpression *expr) const expr->Scope()->SetParent(oldParent); } -void ETSCompiler::CompileDynamic(const ir::CallExpression *expr, compiler::VReg &calleeReg) const +bool IsCastCallName(util::StringView name) { - ETSGen *etsg = GetETSGen(); - auto callInfo = checker::DynamicCall::ResolveCall(etsg->VarBinder(), expr->Callee()); - if (callInfo.obj->IsETSImportDeclaration()) { - etsg->LoadAccumulatorDynamicModule(expr, callInfo.obj->AsETSImportDeclaration()); - } else { - callInfo.obj->Compile(etsg); - } - etsg->StoreAccumulator(expr, calleeReg); - - if (!callInfo.name.empty()) { - auto [qnameStart, qnameLen] = LoadDynamicName(etsg, expr, callInfo.name, false); - etsg->CallDynamic(ETSGen::CallDynamicData {expr, calleeReg, qnameStart}, qnameLen, expr->Signature(), - expr->Arguments()); - } else { - compiler::VReg dynParam2 = etsg->AllocReg(); + return name == Signatures::BYTE_CAST || name == Signatures::SHORT_CAST || name == Signatures::INT_CAST || + name == Signatures::LONG_CAST || name == Signatures::FLOAT_CAST || name == Signatures::DOUBLE_CAST || + name == Signatures::CHAR_CAST; +} - auto lang = expr->Callee()->TsType()->IsETSDynamicFunctionType() - ? expr->Callee()->TsType()->AsETSDynamicFunctionType()->Language() - : expr->Callee()->TsType()->AsETSDynamicType()->Language(); - etsg->LoadUndefinedDynamic(expr, lang); - etsg->StoreAccumulator(expr, dynParam2); - etsg->CallDynamic(ETSGen::CallDynamicData {expr, calleeReg, dynParam2}, expr->Signature(), expr->Arguments()); - } - etsg->SetAccumulatorType(expr->Signature()->ReturnType()); +bool IsCastCall(checker::Signature *signature) +{ + ES2PANDA_ASSERT(signature->HasSignatureFlag(checker::SignatureFlags::STATIC)); + auto *func = signature->Function(); + return (func->Parent()->Parent()->IsMethodDefinition() && IsCastCallName(func->Id()->Name()) && + util::Helpers::ContainingClass(func)->AsETSObjectType()->IsBoxedPrimitive() && + (signature->Params().size() == 1) && signature->Params()[0]->TsType()->IsETSPrimitiveType()); +} - if (etsg->GetAccumulatorType() != expr->TsType()) { - etsg->ApplyConversion(expr, expr->TsType()); +void ETSCompiler::CompileAny(const ir::CallExpression *expr, const ir::Expression *callee, + compiler::VReg &calleeReg) const +{ + ETSGen *etsg = GetETSGen(); + auto memberExpr = callee->AsMemberExpression(); + memberExpr->Object()->Compile(etsg); + compiler::VReg objReg = etsg->AllocReg(); + etsg->StoreAccumulator(expr, objReg); + auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); + if (expr->Signature()->Function() != nullptr && expr->Signature()->Function()->IsStatic()) { + etsg->LoadPropertyByNameAny(memberExpr, objReg, memberExpr->Property()->AsIdentifier()->Name()); + etsg->StoreAccumulator(expr, calleeReg); + etsg->CallAny(callee->AsMemberExpression()->Object(), Span(expr->Arguments()), + calleeReg); + } else { + etsg->CallAnyThis(expr, memberExpr->Property()->AsIdentifier()->Name(), + Span(expr->Arguments()), objReg); } + etsg->EmitAnyCheckCast(expr, expr->TsType()); } void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, checker::Signature *signature) const { ETSGen *etsg = GetETSGen(); - if (expr->Callee()->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { - etsg->ApplyConversionAndStoreAccumulator(expr->Callee(), calleeReg, nullptr); - } if (signature->HasSignatureFlag(checker::SignatureFlags::STATIC)) { + if (IsCastCall(signature)) { + ES2PANDA_ASSERT(expr->Arguments().size() == 1); + auto *param = expr->Arguments()[0]; + param->Compile(etsg); + + const auto *const targetType = etsg->Checker()->GetApparentType(expr->TsType()); + auto ttctx = compiler::TargetTypeContext(etsg, nullptr); + CompileCastPrimitives(param, targetType); + return; + } etsg->CallExact(expr, expr->Signature(), expr->Arguments()); } else if (expr->Callee()->IsMemberExpression()) { auto me = expr->Callee()->AsMemberExpression(); @@ -776,6 +741,7 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle // NOTE: need to refactor: type of member expression object can be obtained via // me->ObjType() or me->Object()->TsType() and they may differ!!!! } else if (me->ObjType() == etsg->Checker()->GlobalETSObjectType() && + (etsg->Checker()->GetApparentType(me->Object()->TsType()) != nullptr) && (etsg->Checker()->GetApparentType(me->Object()->TsType())->IsETSUnionType())) { etsg->CallByName(expr, signature, calleeReg, expr->Arguments()); } else { @@ -797,14 +763,16 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const auto const callee = expr->Callee(); checker::Signature *const signature = expr->Signature(); + ES2PANDA_ASSERT(signature != nullptr); + ES2PANDA_ASSERT(!callee->TsType()->IsETSArrowType()); // should have been lowered bool const isStatic = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); ConvertRestArguments(const_cast(etsg->Checker()->AsETSChecker()), expr, signature); - if (callee->TsType()->HasTypeFlag(checker::TypeFlag::ETS_DYNAMIC_FLAG)) { - CompileDynamic(expr, calleeReg); + if (expr->IsDynamicCall()) { + CompileAny(expr, callee, calleeReg); } else if (callee->IsIdentifier()) { if (!isStatic) { etsg->LoadThis(expr); @@ -825,10 +793,6 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const } else { ES2PANDA_UNREACHABLE(); } - - if (expr->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG | ir::BoxingUnboxingFlags::BOXING_FLAG)) { - etsg->ApplyConversion(expr, expr->TsType()); - } } void ETSCompiler::Compile(const ir::ConditionalExpression *expr) const @@ -838,6 +802,7 @@ void ETSCompiler::Compile(const ir::ConditionalExpression *expr) const auto *falseLabel = etsg->AllocLabel(); auto *endLabel = etsg->AllocLabel(); + compiler::RegScope rs(etsg); compiler::Condition::Compile(etsg, expr->Test(), falseLabel); auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); @@ -860,6 +825,7 @@ void ETSCompiler::Compile(const ir::Identifier *expr) const ETSGen *etsg = GetETSGen(); auto const *smartType = expr->TsType(); + ES2PANDA_ASSERT(smartType != nullptr); if (smartType->IsETSTypeParameter() || smartType->IsETSPartialTypeParameter() || smartType->IsETSNonNullishType()) { smartType = etsg->Checker()->GetApparentType(smartType); } @@ -881,15 +847,15 @@ void ETSCompiler::Compile(const ir::Identifier *expr) const etsg->SetAccumulatorType(smartType); } -static void LoadETSDynamicTypeFromMemberExpr(compiler::ETSGen *etsg, const ir::MemberExpression *expr, - compiler::VReg objReg) +static void LoadETSAnyTypeFromMemberExpr(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()); + if (expr->Property()->TsType()->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + etsg->LoadByIndexAny(expr, objReg); } else { - etsg->LoadElementDynamic(expr, objReg); + etsg->LoadByValueAny(expr, objReg); } + etsg->EmitAnyCheckCast(expr, expr->TsType()); } bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr) @@ -917,8 +883,8 @@ bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpres 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 if (objectType->IsETSAnyType()) { + LoadETSAnyTypeFromMemberExpr(etsg, expr, objReg); } else { ES2PANDA_ASSERT(objectType->IsETSArrayType()); etsg->LoadArrayElement(expr, objReg); @@ -931,6 +897,23 @@ bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpres return true; } +bool ETSCompiler::CompileAny(compiler::ETSGen *etsg, const ir::MemberExpression *expr) const +{ + if (!etsg->Checker()->GetApparentType(expr->Object()->TsType())->IsETSAnyType()) { + return false; + } + auto ottctx = compiler::TargetTypeContext(etsg, expr->Object()->TsType()); + etsg->CompileAndCheck(expr->Object()); + + compiler::VReg objReg = etsg->AllocReg(); + etsg->StoreAccumulator(expr, objReg); + + auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); + etsg->LoadPropertyByNameAny(expr, objReg, expr->Property()->AsIdentifier()->Name()); + etsg->EmitAnyCheckCast(expr, expr->TsType()); + return true; +} + void ETSCompiler::Compile(const ir::MemberExpression *expr) const { ETSGen *etsg = GetETSGen(); @@ -941,6 +924,10 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const return; } + if (CompileAny(etsg, expr)) { + return; + } + if (HandleArrayTypeLengthProperty(expr, etsg)) { return; } @@ -962,18 +949,31 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); ES2PANDA_ASSERT(expr->PropVar()->TsType() != nullptr); const checker::Type *const variableType = expr->PropVar()->TsType(); + ES2PANDA_ASSERT(variableType != nullptr); if (variableType->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { if (expr->Object()->IsSuperExpression()) { etsg->CallExact(expr, variableType->AsETSFunctionType()->FindGetter()->InternalName(), objReg); } else { etsg->CallVirtual(expr, variableType->AsETSFunctionType()->FindGetter(), objReg); } - } else if (objectType->IsETSDynamicType()) { - etsg->LoadPropertyDynamic(expr, expr->TsType(), objReg, propName); } else if (objectType->IsETSUnionType()) { etsg->LoadPropertyByName(expr, objReg, checker::ETSChecker::FormNamedAccessMetadata(expr->PropVar())); } else { - const auto fullName = etsg->FormClassPropReference(objectType->AsETSObjectType(), propName); + auto *id = expr->Property()->AsIdentifier(); + auto *var = id->Variable(); + ES2PANDA_ASSERT(var != nullptr && var->Declaration() != nullptr); + + auto *decl = var->Declaration(); + ES2PANDA_ASSERT(decl->Node() != nullptr); + + auto *declNode = decl->Node(); + ES2PANDA_ASSERT(declNode->Parent() != nullptr && declNode->Parent()->IsTyped()); + + auto *typedOwner = declNode->Parent()->AsTyped(); + const checker::Type *expectedObjType = typedOwner->TsType(); + ES2PANDA_ASSERT(expectedObjType != nullptr && expectedObjType->IsETSObjectType()); + + const auto fullName = etsg->FormClassPropReference(expectedObjType->AsETSObjectType(), propName); etsg->LoadProperty(expr, variableType, objReg, fullName); } etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->TsType()); @@ -984,6 +984,7 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const bool ETSCompiler::HandleArrayTypeLengthProperty(const ir::MemberExpression *expr, ETSGen *etsg) const { auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); + ES2PANDA_ASSERT(objectType != nullptr); auto &propName = expr->Property()->AsIdentifier()->Name(); if (objectType->IsETSArrayType() && propName.Is("length")) { auto ottctx = compiler::TargetTypeContext(etsg, objectType); @@ -1007,6 +1008,7 @@ bool ETSCompiler::HandleStaticProperties(const ir::MemberExpression *expr, ETSGe if (auto const *const varType = variable->TsType(); varType->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { checker::Signature *sig = varType->AsETSFunctionType()->FindGetter(); + ES2PANDA_ASSERT(sig != nullptr); etsg->CallExact(expr, sig->InternalName()); etsg->SetAccumulatorType(expr->TsType()); } else { @@ -1030,9 +1032,6 @@ void ETSCompiler::Compile(const ir::ObjectExpression *expr) const compiler::RegScope rs {etsg}; compiler::VReg objReg = etsg->AllocReg(); - // NOTE: object expressions of dynamic type are not handled in objectLiteralLowering phase - ES2PANDA_ASSERT(expr->TsType()->IsETSDynamicType()); - auto *signatureInfo = etsg->Allocator()->New(etsg->Allocator()); auto *createObjSig = etsg->Allocator()->New(signatureInfo, nullptr, nullptr); createObjSig->SetInternalName(compiler::Signatures::BUILTIN_JSRUNTIME_CREATE_OBJECT); @@ -1060,11 +1059,7 @@ void ETSCompiler::Compile(const ir::ObjectExpression *expr) const value->Compile(etsg); etsg->ApplyConversion(value, key->TsType()); - if (expr->TsType()->IsETSDynamicType()) { - etsg->StorePropertyDynamic(expr, value->TsType(), objReg, pname); - } else { - etsg->StoreProperty(expr, key->TsType(), objReg, pname); - } + etsg->StoreProperty(expr, key->TsType(), objReg, pname); } etsg->LoadAccumulator(expr, objReg); @@ -1283,7 +1278,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(); @@ -1440,9 +1436,9 @@ void ETSCompiler::Compile(const ir::ReturnStatement *st) const return; } - auto ttctx = compiler::TargetTypeContext(etsg, etsg->ReturnType()); + auto ttctx = compiler::TargetTypeContext(etsg, st->ReturnType()); argument->Compile(etsg); - etsg->ApplyConversion(argument, etsg->ReturnType()); + etsg->ApplyConversion(argument, st->ReturnType()); if (etsg->ExtendWithFinalizer(st->Parent(), st)) { return; @@ -1467,7 +1463,7 @@ static void CompileImpl(const ir::SwitchStatement *self, ETSGen *etsg) compiler::VReg tag = etsg->AllocReg(); builder.CompileTagOfSwitch(tag); - uint32_t defaultIndex = 0; + int32_t defaultIndex = -1; for (size_t i = 0; i < self->Cases().size(); i++) { const auto *clause = self->Cases()[i]; @@ -1480,7 +1476,7 @@ static void CompileImpl(const ir::SwitchStatement *self, ETSGen *etsg) builder.JumpIfCase(tag, i); } - if (defaultIndex > 0) { + if (defaultIndex >= 0) { builder.JumpToDefault(defaultIndex); } else { builder.Break(); @@ -1554,6 +1550,7 @@ void ETSCompiler::Compile(const ir::VariableDeclarator *st) const etsg->LoadDefaultValue(st, st->Id()->AsIdentifier()->Variable()->TsType()); } + // ????????????????????????????????????? is this meaningfull???? etsg->ApplyConversion(st, st->TsType()); lref.SetValue(); } @@ -1596,46 +1593,9 @@ void ETSCompiler::Compile(const ir::TSArrayType *node) const etsg->LoadAccumulatorPoison(node, node->TsType()); } -void ETSCompiler::CompileCastUnboxable(const ir::TSAsExpression *expr) const -{ - ETSGen *etsg = GetETSGen(); - auto *targetType = etsg->Checker()->GetApparentType(expr->TsType()); - ES2PANDA_ASSERT(targetType->IsETSObjectType()); - - switch (targetType->AsETSObjectType()->UnboxableKind()) { - case checker::ETSObjectFlags::BUILTIN_BOOLEAN: - etsg->CastToBoolean(expr); - break; - case checker::ETSObjectFlags::BUILTIN_BYTE: - etsg->CastToByte(expr); - break; - case checker::ETSObjectFlags::BUILTIN_CHAR: - etsg->CastToChar(expr); - break; - case checker::ETSObjectFlags::BUILTIN_SHORT: - etsg->CastToShort(expr); - break; - case checker::ETSObjectFlags::BUILTIN_INT: - etsg->CastToInt(expr); - break; - case checker::ETSObjectFlags::BUILTIN_LONG: - etsg->CastToLong(expr); - break; - case checker::ETSObjectFlags::BUILTIN_FLOAT: - etsg->CastToFloat(expr); - break; - case checker::ETSObjectFlags::BUILTIN_DOUBLE: - etsg->CastToDouble(expr); - break; - default: - ES2PANDA_UNREACHABLE(); - } -} - -void ETSCompiler::CompileCastPrimitives(const ir::TSAsExpression *expr) const +void ETSCompiler::CompileCastPrimitives(const ir::Expression *expr, checker::Type const *targetType) const { ETSGen *etsg = GetETSGen(); - auto *targetType = etsg->Checker()->GetApparentType(expr->TsType()); switch (checker::ETSChecker::TypeKind(targetType)) { case checker::TypeFlag::ETS_BOOLEAN: { @@ -1674,12 +1634,25 @@ void ETSCompiler::CompileCastPrimitives(const ir::TSAsExpression *expr) const ES2PANDA_UNREACHABLE(); } } + etsg->SetAccumulatorType(targetType); +} + +// NOTE(gogabr): will be needed once we forbid as conversions +/* +static void CastIfDynamic(ETSGen *etsg, ir::Expression const *expr, checker::TypeFlag typeFlag) +{ + // CC-OFFNXT(redundant_code[C++]) tmp code + if (checker::ETSChecker::TypeKind(expr->TsType()) == checker::TypeFlag::ETS_DYNAMIC_TYPE) { + etsg->CastDynamicToe(expr, typeFlag); + return; + } + ES2PANDA_UNREACHABLE(); } +*/ -void ETSCompiler::CompileCast(const ir::TSAsExpression *expr) const +void ETSCompiler::CompileCast(const ir::TSAsExpression *expr, checker::Type const *targetType) const { ETSGen *etsg = GetETSGen(); - auto *targetType = etsg->Checker()->GetApparentType(expr->TsType()); switch (checker::ETSChecker::TypeKind(targetType)) { case checker::TypeFlag::ETS_ARRAY: @@ -1690,17 +1663,35 @@ void ETSCompiler::CompileCast(const ir::TSAsExpression *expr) const case checker::TypeFlag::ETS_NONNULLISH: case checker::TypeFlag::ETS_PARTIAL_TYPE_PARAMETER: case checker::TypeFlag::ETS_UNION: + case checker::TypeFlag::ETS_ANY: case checker::TypeFlag::ETS_NULL: case checker::TypeFlag::ETS_UNDEFINED: { etsg->CastToReftype(expr, targetType, expr->isUncheckedCast_); break; } - case checker::TypeFlag::ETS_DYNAMIC_TYPE: { - etsg->CastToDynamic(expr, targetType->AsETSDynamicType()); + // NOTE(gogabr): will be needed once we forbid as conversion + /* + // CC-OFFNXT(redundant_code[C++]) tmp code + case checker::TypeFlag::DOUBLE: + case checker::TypeFlag::STRING: + case checker::TypeFlag::ETS_BOOLEAN: { + CastIfDynamic(etsg, expr->Expr(), targetType->TypeFlags()); + break; // no further conversion + } + case checker::TypeFlag::BYTE: + case checker::TypeFlag::SHORT: + case checker::TypeFlag::INT: + case checker::TypeFlag::LONG: + case checker::TypeFlag::FLOAT: + case checker::TypeFlag::CHAR: { + CastIfDynamic(etsg, expr->Expr(), targetType->TypeFlags()); + CompileCastPrimitives(expr, targetType); break; } + */ default: { - CompileCastPrimitives(expr); + CompileCastPrimitives(expr, targetType); + break; } } } @@ -1712,26 +1703,11 @@ void ETSCompiler::Compile(const ir::TSAsExpression *expr) const 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()); + if (!etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), targetType)) { + auto ttctx = compiler::TargetTypeContext(etsg, nullptr); + CompileCast(expr, targetType); + ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), targetType)); } - - if (targetType->IsETSObjectType() && - ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U || - (expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) && - checker::ETSChecker::TypeKind(etsg->GetAccumulatorType()) != checker::TypeFlag::ETS_OBJECT) { - if (targetType->IsETSUnboxableObject()) { - CompileCastUnboxable(expr); - } - } - - if ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U) { - etsg->ApplyBoxingConversion(expr->Expr()); - } - - CompileCast(expr); - ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), targetType)); } void ETSCompiler::Compile([[maybe_unused]] const ir::TSInterfaceDeclaration *st) const {} @@ -1744,18 +1720,22 @@ void ETSCompiler::Compile(const ir::TSNonNullExpression *expr) const expr->Expr()->Compile(etsg); if (etsg->GetAccumulatorType()->PossiblyETSNullish()) { - auto arg = etsg->AllocReg(); - etsg->StoreAccumulator(expr, arg); - etsg->LoadAccumulator(expr, arg); + if (!etsg->GetAccumulatorType()->PossiblyETSNull()) { + etsg->EmitNullcheck(expr); + etsg->SetAccumulatorType(expr->OriginalType()); + } else { + auto arg = etsg->AllocReg(); + etsg->StoreAccumulator(expr, arg); - auto endLabel = etsg->AllocLabel(); + auto endLabel = etsg->AllocLabel(); - etsg->BranchIfNotNullish(expr, endLabel); - etsg->EmitNullishException(expr); + etsg->BranchIfNotNullish(expr, endLabel); + etsg->EmitNullishException(expr); - etsg->SetLabel(expr, endLabel); - etsg->LoadAccumulator(expr, arg); - etsg->AssumeNonNullish(expr, expr->OriginalType()); + etsg->SetLabel(expr, endLabel); + etsg->LoadAccumulator(expr, arg); + etsg->AssumeNonNullish(expr, expr->OriginalType()); + } } ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->OriginalType())); @@ -1763,4 +1743,17 @@ void ETSCompiler::Compile(const ir::TSNonNullExpression *expr) const void ETSCompiler::Compile([[maybe_unused]] const ir::TSTypeAliasDeclaration *st) const {} +void ETSCompiler::Compile(const ir::TSQualifiedName *expr) const +{ + ES2PANDA_ASSERT(expr->Left()->IsMemberExpression()); + + ETSGen *etsg = GetETSGen(); + expr->Left()->Compile(etsg); + + compiler::VReg objReg = etsg->AllocReg(); + etsg->StoreAccumulator(expr->Left(), objReg); + etsg->LoadPropertyByNameAny(expr->Left(), objReg, expr->Right()->AsIdentifier()->Name()); + etsg->EmitAnyCheckCast(expr, expr->Right()->AsIdentifier()->Variable()->TsType()); +} + } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/core/ETSCompiler.h b/ets2panda/compiler/core/ETSCompiler.h index 94cd1e8f35b8cdbe204d965a029984772d864185..868ce81e497e15dbcb51d9a6dd65191d2249dc58 100644 --- a/ets2panda/compiler/core/ETSCompiler.h +++ b/ets2panda/compiler/core/ETSCompiler.h @@ -35,10 +35,9 @@ public: private: void GetDynamicNameParts(const ir::CallExpression *expr, ArenaVector &parts) const; - void CompileDynamic(const ir::CallExpression *expr, compiler::VReg &calleeReg) const; - void CompileCastUnboxable(const ir::TSAsExpression *expr) const; - void CompileCastPrimitives(const ir::TSAsExpression *expr) const; - void CompileCast(const ir::TSAsExpression *expr) const; + void CompileAny(const ir::CallExpression *expr, const ir::Expression *callee, compiler::VReg &calleeReg) const; + void CompileCastPrimitives(const ir::Expression *expr, checker::Type const *targetType) const; + void CompileCast(const ir::TSAsExpression *expr, checker::Type const *targetType) const; 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; @@ -46,6 +45,7 @@ private: void CompileTupleCreation(const ir::ArrayExpression *tupleInitializer) const; static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr); + bool CompileAny(compiler::ETSGen *etsg, const ir::MemberExpression *expr) const; ETSGen *GetETSGen() const; }; diff --git a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp index 3f3908e8206d4f92de117ae319809c813e6dc108..77abdb301f86cd6b76c5033bbadab54716439844 100644 --- a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp +++ b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp @@ -52,6 +52,11 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::MethodDefinition *node) con ES2PANDA_UNREACHABLE(); } +void ETSCompiler::Compile([[maybe_unused]] const ir::OverloadDeclaration *node) const +{ + ES2PANDA_UNREACHABLE(); +} + void ETSCompiler::Compile([[maybe_unused]] const ir::Property *expr) const { ES2PANDA_UNREACHABLE(); @@ -117,6 +122,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(); @@ -188,11 +198,6 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::OmittedExpression *expr) co ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::OpaqueTypeNode *node) const -{ - ES2PANDA_UNREACHABLE(); -} - void ETSCompiler::Compile([[maybe_unused]] const ir::BrokenTypeNode *node) const { ES2PANDA_UNREACHABLE(); @@ -419,11 +424,6 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::TSParenthesizedType *node) ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::TSQualifiedName *expr) const -{ - ES2PANDA_UNREACHABLE(); -} - void ETSCompiler::Compile([[maybe_unused]] const ir::TSStringKeyword *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 30b7bcf5e1b741d64e20cd57063d6212f6807ee3..bd09f10ff1bd697d8165bce7941c4439d09ecde6 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -13,12 +13,15 @@ * limitations under the License. */ -#include "ETSGen.h" #include "ETSGen-inl.h" +#include "compiler/core/codeGen.h" +#include "compiler/core/regScope.h" +#include "generated/isa.h" #include "generated/signatures.h" #include "ir/base/scriptFunction.h" #include "ir/base/classDefinition.h" +#include "ir/expression.h" #include "ir/statement.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/identifier.h" @@ -30,14 +33,15 @@ #include "ir/statements/continueStatement.h" #include "ir/statements/tryStatement.h" #include "ir/ts/tsInterfaceDeclaration.h" -#include "varbinder/variableFlags.h" #include "compiler/base/lreference.h" #include "compiler/base/catchTable.h" #include "compiler/core/dynamicContext.h" +#include "macros.h" +#include "util/es2pandaMacros.h" #include "varbinder/ETSBinder.h" #include "varbinder/variable.h" #include "checker/types/type.h" -#include "checker/types/typeFlag.h" +#include "checker/types/signature.h" #include "checker/checker.h" #include "checker/ETSchecker.h" #include "checker/types/ets/etsObjectType.h" @@ -86,6 +90,7 @@ void ETSGen::CompileAndCheck(const ir::Expression *expr) return; } + ES2PANDA_ASSERT(accType != nullptr); if (accType->IsETSPrimitiveType() && ((accType->TypeFlags() ^ exprType->TypeFlags()) & ~checker::TypeFlag::CONSTANT) == 0) { return; @@ -97,7 +102,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 @@ -216,6 +221,7 @@ checker::Type const *ETSGen::TypeForVar(varbinder::Variable const *var) const no void ETSGen::MoveVreg(const ir::AstNode *const node, const VReg vd, const VReg vs) { const auto *const sourceType = GetVRegType(vs); + ES2PANDA_ASSERT(sourceType != nullptr); if (sourceType->IsETSReferenceType()) { Ra().Emit(node, vd, vs); @@ -236,71 +242,8 @@ void ETSGen::LoadAccumulatorPoison(const ir::AstNode *node, const checker::Type SetAccumulatorType(type); } -util::StringView ETSGen::FormDynamicModulePropReference(const varbinder::Variable *var) -{ - ES2PANDA_ASSERT(VarBinder()->IsDynamicModuleVariable(var) || VarBinder()->IsDynamicNamespaceVariable(var)); - - auto *data = VarBinder()->DynamicImportDataForVar(var); - ES2PANDA_ASSERT(data != nullptr); - - auto *import = data->import; - - return FormDynamicModulePropReference(import); -} - -void ETSGen::LoadAccumulatorDynamicModule(const ir::AstNode *node, const ir::ETSImportDeclaration *import) -{ - ES2PANDA_ASSERT(import->Language().IsDynamic()); - LoadStaticProperty(node, Checker()->GlobalBuiltinDynamicType(import->Language()), - FormDynamicModulePropReference(import)); -} - -util::StringView ETSGen::FormDynamicModulePropReference(const ir::ETSImportDeclaration *import) -{ - std::stringstream ss; - ss << VarBinder()->Program()->ModulePrefix(); - ss << compiler::Signatures::DYNAMIC_MODULE_CLASS; - ss << '.'; - ss << import->AssemblerName(); - return util::UString(ss.str(), Allocator()).View(); -} - -void ETSGen::LoadDynamicModuleVariable(const ir::AstNode *node, varbinder::Variable const *const var) -{ - RegScope rs(this); - - auto *data = VarBinder()->DynamicImportDataForVar(var); - auto *import = data->import; - - LoadStaticProperty(node, var->TsType(), FormDynamicModulePropReference(var)); - - auto objReg = AllocReg(); - StoreAccumulator(node, objReg); - - auto *id = data->specifier->AsImportSpecifier()->Imported(); - auto lang = import->Language(); - LoadPropertyDynamic(node, Checker()->GlobalBuiltinDynamicType(lang), objReg, id->Name()); - - ApplyConversion(node); -} - -void ETSGen::LoadDynamicNamespaceVariable(const ir::AstNode *node, varbinder::Variable const *const var) -{ - LoadStaticProperty(node, var->TsType(), FormDynamicModulePropReference(var)); -} - void ETSGen::LoadVar(const ir::Identifier *node, varbinder::Variable const *const var) { - if (VarBinder()->IsDynamicModuleVariable(var)) { - LoadDynamicModuleVariable(node, var); - return; - } - - if (VarBinder()->IsDynamicNamespaceVariable(var)) { - LoadDynamicNamespaceVariable(node, var); - return; - } - auto *local = var->AsLocalVariable(); switch (ETSLReference::ResolveReferenceKind(var)) { @@ -310,6 +253,7 @@ void ETSGen::LoadVar(const ir::Identifier *node, varbinder::Variable const *cons break; } case ReferenceKind::FIELD: { + ES2PANDA_ASSERT(GetVRegType(GetThisReg()) != nullptr); const auto fullName = FormClassPropReference(GetVRegType(GetThisReg())->AsETSObjectType(), var->Name()); LoadProperty(node, var->TsType(), GetThisReg(), fullName); break; @@ -361,6 +305,7 @@ void ETSGen::StoreVar(const ir::Identifier *node, const varbinder::ConstScopeFin util::StringView ETSGen::FormClassPropReference(const checker::ETSObjectType *classType, const util::StringView &name) { std::stringstream ss; + ES2PANDA_ASSERT(classType != nullptr); ss << classType->AssemblerName().Mutf8() << Signatures::METHOD_SEPARATOR << name; return util::StringView(*ProgElement()->Strings().emplace(ss.str()).first); } @@ -390,11 +335,30 @@ void ETSGen::StoreStaticProperty(const ir::AstNode *const node, const checker::T } } +static bool StaticAccessRequiresReferenceSafetyCheck(const ir::AstNode *const node, const checker::Type *propType) +{ + if (propType->PossiblyETSUndefined()) { + return false; + } + auto parent = node->Parent(); + if (parent->IsMemberExpression()) { + return false; + } + if (parent->IsCallExpression() && parent->AsCallExpression()->Callee() == node) { + return false; + } + return true; +} + void ETSGen::LoadStaticProperty(const ir::AstNode *const node, const checker::Type *propType, const util::StringView &fullName) { + ES2PANDA_ASSERT(propType != nullptr); if (propType->IsETSReferenceType()) { Sa().Emit(node, fullName); + if (StaticAccessRequiresReferenceSafetyCheck(node, propType)) { + EmitNullcheck(node); + } } else if (IsWidePrimitiveType(propType)) { Sa().Emit(node, fullName); } else { @@ -407,6 +371,7 @@ void ETSGen::LoadStaticProperty(const ir::AstNode *const node, const checker::Ty void ETSGen::StoreProperty(const ir::AstNode *const node, const checker::Type *propType, const VReg objReg, const util::StringView &name) { + ES2PANDA_ASSERT(Checker()->GetApparentType(GetVRegType(objReg)) != nullptr); auto *objType = Checker()->GetApparentType(GetVRegType(objReg))->AsETSObjectType(); const auto fullName = FormClassPropReference(objType, name); @@ -419,6 +384,22 @@ void ETSGen::StoreProperty(const ir::AstNode *const node, const checker::Type *p } } +void ETSGen::StorePropertyByNameAny(const ir::AstNode *const node, const VReg objReg, const util::StringView &fullName) +{ + ES2PANDA_ASSERT(node->IsMemberExpression() && + Checker()->GetApparentType(node->AsMemberExpression()->Object()->TsType())->IsETSAnyType()); + Ra().Emit(node, objReg, fullName); + SetAccumulatorType(node->AsMemberExpression()->TsType()); +} + +void ETSGen::LoadPropertyByNameAny(const ir::AstNode *const node, const VReg objReg, const util::StringView &fullName) +{ + ES2PANDA_ASSERT(node->IsMemberExpression() && + Checker()->GetApparentType(node->AsMemberExpression()->Object()->TsType())->IsETSAnyType()); + Ra().Emit(node, objReg, fullName); + SetAccumulatorType(node->AsMemberExpression()->TsType()); +} + void ETSGen::LoadProperty(const ir::AstNode *const node, const checker::Type *propType, const VReg objReg, const util::StringView &fullName) { @@ -472,137 +453,46 @@ void ETSGen::LoadPropertyByName([[maybe_unused]] const ir::AstNode *const node, #endif // PANDA_WITH_ETS } -void ETSGen::StorePropertyDynamic(const ir::AstNode *node, const checker::Type *propType, VReg objReg, - const util::StringView &propName) -{ - auto const lang = GetVRegType(objReg)->AsETSDynamicType()->Language(); - std::string_view methodName {}; - if (propType->IsETSBooleanType()) { - methodName = Signatures::Dynamic::SetPropertyBooleanBuiltin(lang); - } else if (propType->IsByteType()) { - methodName = Signatures::Dynamic::SetPropertyByteBuiltin(lang); - } else if (propType->IsCharType()) { - methodName = Signatures::Dynamic::SetPropertyCharBuiltin(lang); - } else if (propType->IsShortType()) { - methodName = Signatures::Dynamic::SetPropertyShortBuiltin(lang); - } else if (propType->IsIntType()) { - methodName = Signatures::Dynamic::SetPropertyIntBuiltin(lang); - } else if (propType->IsLongType()) { - methodName = Signatures::Dynamic::SetPropertyLongBuiltin(lang); - } else if (propType->IsFloatType()) { - methodName = Signatures::Dynamic::SetPropertyFloatBuiltin(lang); - } else if (propType->IsDoubleType()) { - methodName = Signatures::Dynamic::SetPropertyDoubleBuiltin(lang); - } else if (propType->IsETSStringType()) { - methodName = Signatures::Dynamic::SetPropertyStringBuiltin(lang); - } else if (propType->IsETSObjectType() || propType->IsETSTypeParameter()) { - methodName = Signatures::Dynamic::SetPropertyDynamicBuiltin(lang); - // NOTE: vpukhov. add non-dynamic builtin - if (!propType->IsETSDynamicType()) { - CastToDynamic(node, Checker()->GlobalBuiltinDynamicType(lang)->AsETSDynamicType()); - } - } else { - ASSERT_PRINT(false, "Unsupported property type"); - } - - RegScope rs(this); - VReg propValueReg = AllocReg(); - VReg propNameReg = AllocReg(); - - StoreAccumulator(node, propValueReg); - - // Load property name - LoadAccumulatorString(node, propName); - StoreAccumulator(node, propNameReg); - - // Set property by name - Ra().Emit(node, methodName, objReg, propNameReg, propValueReg, dummyReg_); - SetAccumulatorType(Checker()->GlobalBuiltinJSValueType()); -} - -void ETSGen::LoadPropertyDynamic(const ir::AstNode *node, const checker::Type *propType, VReg objReg, - std::variant property) -{ - auto const lang = GetVRegType(objReg)->AsETSDynamicType()->Language(); - auto *type = propType; - std::string_view methodName {}; - if (propType->IsETSBooleanType()) { - methodName = Signatures::Dynamic::GetPropertyBooleanBuiltin(lang); - } else if (propType->IsByteType()) { - methodName = Signatures::Dynamic::GetPropertyByteBuiltin(lang); - } else if (propType->IsCharType()) { - methodName = Signatures::Dynamic::GetPropertyCharBuiltin(lang); - } else if (propType->IsShortType()) { - methodName = Signatures::Dynamic::GetPropertyShortBuiltin(lang); - } else if (propType->IsIntType()) { - methodName = Signatures::Dynamic::GetPropertyIntBuiltin(lang); - } else if (propType->IsLongType()) { - methodName = Signatures::Dynamic::GetPropertyLongBuiltin(lang); - } else if (propType->IsFloatType()) { - methodName = Signatures::Dynamic::GetPropertyFloatBuiltin(lang); - } else if (propType->IsDoubleType()) { - methodName = Signatures::Dynamic::GetPropertyDoubleBuiltin(lang); - } else if (propType->IsETSStringType()) { - methodName = Signatures::Dynamic::GetPropertyStringBuiltin(lang); - } else if (propType->IsETSObjectType() || propType->IsETSTypeParameter()) { - methodName = Signatures::Dynamic::GetPropertyDynamicBuiltin(lang); - type = Checker()->GlobalBuiltinDynamicType(lang); - } else { - ASSERT_PRINT(false, "Unsupported property type"); - } - +void ETSGen::StoreByIndexAny(const ir::MemberExpression *node, VReg objectReg, VReg index) +{ RegScope rs(this); - VReg propNameObject; - - if (node->IsMemberExpression() && node->AsMemberExpression()->IsComputed()) { - (std::get(property))->Compile(this); - } else { - // Load property name - LoadAccumulatorString(node, std::get(property)); - } - - propNameObject = AllocReg(); - StoreAccumulator(node, propNameObject); + // Store property by index + Ra().Emit(node, objectReg, index); + SetAccumulatorType(Checker()->GlobalVoidType()); +} - // Get property - Ra().Emit(node, methodName, objReg, propNameObject); +void ETSGen::LoadByIndexAny(const ir::MemberExpression *node, VReg objectReg) +{ + RegScope rs(this); - SetAccumulatorType(type); + VReg indexReg = AllocReg(); + StoreAccumulator(node, indexReg); - if (propType != type && !propType->IsETSDynamicType()) { - CastDynamicToObject(node, propType); - } + // Get property by index + Ra().Emit(node, objectReg); + SetAccumulatorType(node->TsType()); } -void ETSGen::StoreElementDynamic(const ir::AstNode *node, VReg objectReg, VReg index) +void ETSGen::StoreByValueAny(const ir::MemberExpression *node, VReg objectReg, VReg value) { - auto const lang = GetVRegType(objectReg)->AsETSDynamicType()->Language(); - std::string_view methodName = Signatures::Dynamic::SetElementDynamicBuiltin(lang); - RegScope rs(this); - VReg valueReg = AllocReg(); - StoreAccumulator(node, valueReg); - - // Set property by index - Ra().Emit(node, methodName, objectReg, index, valueReg, dummyReg_); + // Store property by value + Ra().Emit(node, objectReg, value); SetAccumulatorType(Checker()->GlobalVoidType()); } -void ETSGen::LoadElementDynamic(const ir::AstNode *node, VReg objectReg) +void ETSGen::LoadByValueAny(const ir::MemberExpression *node, VReg objectReg) { - auto const lang = GetVRegType(objectReg)->AsETSDynamicType()->Language(); - std::string_view methodName = Signatures::Dynamic::GetElementDynamicBuiltin(lang); - RegScope rs(this); - VReg indexReg = AllocReg(); - StoreAccumulator(node, indexReg); + VReg valueReg = AllocReg(); + StoreAccumulator(node, valueReg); - // Get property by index - Ra().Emit(node, methodName, objectReg, indexReg); - SetAccumulatorType(Checker()->GlobalBuiltinDynamicType(lang)); + // Get property by value + Ra().Emit(node, objectReg, valueReg); + SetAccumulatorType(node->TsType()); } void ETSGen::CallRangeFillUndefined(const ir::AstNode *const node, checker::Signature *const signature, @@ -624,13 +514,6 @@ void ETSGen::CallRangeFillUndefined(const ir::AstNode *const node, checker::Sign Rra().Emit(node, argStart, signature->ArgCount() + 1, signature->InternalName(), argStart); } -void ETSGen::LoadUndefinedDynamic(const ir::AstNode *node, Language lang) -{ - RegScope rs(this); - Ra().Emit(node, Signatures::Dynamic::GetUndefinedBuiltin(lang), dummyReg_, dummyReg_); - SetAccumulatorType(Checker()->GlobalBuiltinDynamicType(lang)); -} - void ETSGen::LoadThis(const ir::AstNode *node) { LoadAccumulator(node, GetThisReg()); @@ -659,6 +542,18 @@ const checker::Type *ETSGen::LoadDefaultValue(const ir::AstNode *node, const che if (type->IsETSReferenceType()) { if (checker->Relation()->IsSupertypeOf(type, checker->GlobalETSUndefinedType())) { LoadAccumulatorUndefined(node); + } else if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { + // Call default constructor for boxed primitive types. + static auto const DUMMY_ARGS = ArenaVector(checker->Allocator()->Adapter()); + auto const &signatures = type->AsETSObjectType()->ConstructSignatures(); + auto const it = std::find_if(signatures.cbegin(), signatures.cend(), [](checker::Signature *signature) { + return signature->ArgCount() == 0U && !signature->HasRestParameter(); + }); + if (it != signatures.cend()) { + InitObject(node, *it, DUMMY_ARGS); + } else { + LoadAccumulatorPoison(node, type); + } } else { LoadAccumulatorPoison(node, type); } @@ -682,6 +577,7 @@ void ETSGen::EmitReturnVoid(const ir::AstNode *node) void ETSGen::ReturnAcc(const ir::AstNode *node) { const auto *const accType = GetAccumulatorType(); + ES2PANDA_ASSERT(accType != nullptr); if (accType->IsETSReferenceType()) { Sa().Emit(node); @@ -692,128 +588,23 @@ void ETSGen::ReturnAcc(const ir::AstNode *node) } } -static bool IsAnyReferenceSupertype(checker::Type const *type) +bool ETSGen::IsNullUnsafeObjectType(checker::Type const *type) const { - if (!type->IsETSUnionType()) { - return false; - } - auto const &constituent = type->AsETSUnionType()->ConstituentTypes(); - return constituent.size() == 3U && std::all_of(constituent.begin(), constituent.end(), [](checker::Type *t) { - return t->IsETSUndefinedType() || t->IsETSNullType() || - (t->IsETSObjectType() && t->AsETSObjectType()->IsGlobalETSObjectType()); - }); // CC-OFF(G.FMT.02) project code style -} - -static bool IsNullUnsafeObjectType(checker::Type const *type) -{ - return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); -} - -void ETSGen::IsInstanceDynamic(const ir::BinaryExpression *const node, const VReg srcReg, - [[maybe_unused]] const VReg tgtReg) -{ - ES2PANDA_ASSERT(node->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF); - const checker::Type *lhsType = node->Left()->TsType(); - const checker::Type *rhsType = node->Right()->TsType(); - ES2PANDA_ASSERT(rhsType->IsETSDynamicType() || lhsType->IsETSDynamicType()); - - const RegScope rs(this); - if (rhsType->IsETSDynamicType()) { - ES2PANDA_ASSERT(node->Right()->TsType()->AsETSDynamicType()->HasDecl()); - if (lhsType->IsETSDynamicType()) { - VReg dynTypeReg = MoveAccToReg(node); - // Semantics: - // let dyn_val: JSValue = ... - // dyn_value instanceof DynamicDecl - // Bytecode: - // call runtime intrinsic_dynamic - CallExact(node, Signatures::BUILTIN_JSRUNTIME_INSTANCE_OF_DYNAMIC, srcReg, dynTypeReg); - } else if (lhsType == Checker()->GlobalETSObjectType()) { - // Semantics: - // let obj: Object = ... - // obj instanceof DynamicDecl - // Bytecode: - // if isinstance : - // checkcast - // return call runtime intrinsic_dynamic - // return false - Label *ifFalse = AllocLabel(); - Language lang = rhsType->AsETSDynamicType()->Language(); - VReg dynTypeReg = MoveAccToReg(node); - LoadAccumulator(node, srcReg); - Sa().Emit(node, Checker()->GlobalBuiltinDynamicType(lang)->AssemblerName()); - BranchIfFalse(node, ifFalse); - LoadAccumulator(node, srcReg); - Sa().Emit(node, Checker()->GlobalBuiltinDynamicType(lang)->AssemblerName()); - CallExact(node, Signatures::BUILTIN_JSRUNTIME_INSTANCE_OF_DYNAMIC, srcReg, dynTypeReg); - SetLabel(node, ifFalse); - } else { - // Semantics: - // let obj: EtsType = ... - // obj instanceof DynamicDecl - // Bytecode: - // False - Sa().Emit(node, 0); - } - } else { - if (lhsType->IsETSDynamicType()) { - if (rhsType == Checker()->GlobalETSObjectType()) { - // Semantics: - // let dyn_val: JSValue = ... - // dyn_val instanceof Object - // Bytecode: - // True - Sa().Emit(node, 1); - } else { - // Semantics: - // let dyn_val: JSValue = ... - // dyn_val instanceof EtsType - // Bytecode: - // lda.type + call runtime instrinsic_static - Sa().Emit(node, rhsType->AsETSObjectType()->AssemblerName()); - VReg typeReg = MoveAccToReg(node); - CallExact(node, Signatures::BUILTIN_JSRUNTIME_INSTANCE_OF_STATIC, srcReg, typeReg); - } - } else { - ES2PANDA_UNREACHABLE(); - } - } - 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); + ES2PANDA_ASSERT(type != nullptr); + auto const checker = const_cast(Checker()); + return checker->Relation()->IsSupertypeOf(checker->GetApparentType(type), checker->GlobalETSObjectType()); } // Implemented on top of the runtime type system, do not relax checks, do not introduce new types -void ETSGen::TestIsInstanceConstituent(const ir::AstNode *const node, std::tuple() + +// case3 +class A { + u: number = 0 +} + +class B { + u: number = 0 +} + +(): A => { return new B() } + +class A { + v: number = 0 +} + +class B { + v: number = 0 +} +class C { + u: T; +} + +let b: C = new C(); // 违反规则 +``` + +**ArkTS1.2** + +```typescript +// case1 +class A { + v: number = 0 +} + +class B { + v: number = 0 +} + +let a = new B() + +// case2 +class C { + u: T +} + +let b: C = new C() + +// case3 +class A { + u: number = 0 +} + +class B { + u: number = 0 +} + +(): B => { return new B() } + +class A { + v: number = 0 +} + +class B { + v: number = 0 +} +let b: C = new C(); // 使用相同的泛型类型 + +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe300.md b/ets2panda/linter/docs/rules-cn/recipe300.md new file mode 100644 index 0000000000000000000000000000000000000000..71a8a5e419fd5646db5f6b157a56f78c4f637b69 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe300.md @@ -0,0 +1,50 @@ +## 不支持TS-like `Function`类型的调用方式 + +**规则:**`arkts-no-ts-like-function-call` + +**级别:error** + +ArkTS1.2会对函数类型进行更严格的编译器检查。函数返回类型需要严格定义来保证类型安全,因此不支持TS-like`Function`类型。 + +**ArkTS1.1** + +```typescript +let f: Function = () => {} // 违反规则 + +function run(fn: Function) { // 违反规则 + fn(); +} + +let fn: Function = (x: number) => x + 1; // 违反规则 + +class A { + func: Function = () => {}; // 违反规则 +} + +function getFunction(): Function { // 违反规则 + return () => {}; +} +``` + +**ArkTS1.2** + +```typescript +type F = () => R; +type F1 = (p: P) => R + +let f: F = () => {} + +function run(fn: () => void) { // 指定返回类型 + fn(); +} + +let fn: (x: number) => number = (x) => x + 1; // 明确参数类型 + +class A { + func: () => void = () => {}; // 明确类型 +} + +function getFunction(): () => void { // 明确返回类型 + return () => {}; +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe302.md b/ets2panda/linter/docs/rules-cn/recipe302.md new file mode 100644 index 0000000000000000000000000000000000000000..1500874327688c104a2b2a5a50e74866bc4681a4 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe302.md @@ -0,0 +1,40 @@ +### ArkTS1.2Object内置方法作用在ArkTS1.1对象 + +**规则:** arkts-interop-d2s-static-object-on-dynamic-instance + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ets +export class X { + a = 1; +} + +// file2.ets +import { X } from 'file1'; +export function foo(prx: Object) { + Object.entries(prx); // [a, 1] + Object.keys(prx); // ["a"] + Object.values(prx); // [1] +} +foo(new X()); +``` + +**ArkTS1.2** +```typescript +// file1.ets ArkTS1.1 +export class X { + a = 1; +} + +// file2.ets ArkTS 1.2 +'use static' +import { X } from 'file1'; +export function foo(prx: Object) { + Object.entries(prx); // [a, 1] + Object.keys(prx); // ["a"] + Object.values(prx); // [1] +} +foo(new X()); // 编译报错 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe303.md b/ets2panda/linter/docs/rules-cn/recipe303.md new file mode 100644 index 0000000000000000000000000000000000000000..5b378e5dea4501adf69349a603a227ce349111c7 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe303.md @@ -0,0 +1,47 @@ +### ArkTS1.2Reflect内置方法作用在ArkTS1.1对象 + +**规则:** arkts-interop-d2s-static-reflect-on-dynamic-instance + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ets ArkTS1.1 +class X { + a: string = 'hello'; + getName() { + return this.a; + } +} + +// file2.ets ArkTS1.2 +'use static' +import { X } from './file1'; +export function foo(prx: Object) { + Reflect.get(prx, 'a'); // 'hello' + Reflect.set(prx, 'a', 'world'); // true + Reflect.ownKeys(prx); // ['a'] +} +foo(new X()); +``` + +**ArkTS1.2** +```typescript +// file1.ets ArkTS1.1 +class X { + a: string = 'hello'; + getName() { + return this.a; + } +} + +// file2.ets ArkTS1.2 +'use static' +import { X } from './file1'; +export function foo(prx: Object) { + Reflect.get(prx, 'a'); // 'hello' + Reflect.set(prx, 'a', 'world'); // true + Reflect.ownKeys(prx); // ['a'] +} +foo(new X()); // 编译报错 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe304.md b/ets2panda/linter/docs/rules-cn/recipe304.md new file mode 100644 index 0000000000000000000000000000000000000000..910d614ede6de60ba9dd7a8ea180c9c5bbff825b --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe304.md @@ -0,0 +1,40 @@ +## namespace内方法不能重名 + +**规则:**`arkts-no-duplicate-function-name` + +**级别:error** + +由于ArkTS1.2中会将多个名称相同的namespace合并成一个namespace,所以namespace内方法不能重名,否则会导致冲突。 + +**ArkTS1.1** + +```typescript +namespace A { + export function foo() { // 错误:命名空间 'A' 中重复导出函数 'foo'. + console.log('test1'); + } +} + +namespace A { + export function foo() { // 错误:命名空间 'A' 中重复导出函数 'foo'. + console.log('test2'); + } +} + +``` + +**ArkTS1.2** + +```typescript +namespace A { + export function foo1() { // 重命名导出函数 + console.log('test1'); + } +} + +namespace A { + export function foo2() { + console.log('test2'); + } +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe306.md b/ets2panda/linter/docs/rules-cn/recipe306.md new file mode 100644 index 0000000000000000000000000000000000000000..afee2e00cfe5fdb919bf89c9bcd550468d2258ef --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe306.md @@ -0,0 +1,66 @@ +### ArkTS1.2访问TS独有类型的实体 + +**规则:** arkts-interop-ts2s-static-access-ts-type + +TS独有类型包括如下类型: +- any +- unknown +- symbol +- Function +- object literal (例如 {x: number, y: string}) +- mixing enum (例如 enum X {a = 0, b = '1'}) +- call signature (例如 {(arg: number): string}) +- constructor signature (例如 {new(): Object}) +- index signature (例如 {[index: number]: string}) +- intersection (例如 TypeA & TypeB) +- keyof (例如 interface X { props: keyof T}) +- typeof(例如 let p = {x: 1, y: ''}, let q: typeof p) +- indexed access type(例如 MyArray = [{ name: "Alice", age: 15 }] type Person = typeof MyArray[number]) +- conditional types (例如 type Swap = T extends A ? B : A) +- mapped types (例如 type A = {[K in keyof T]: T[K]}) +- template literal types (例如 type AB = "A" | "B", type AllLocaleIDs = `${AB}_id`) +- Pick +- Omit +- Exclude +- Extract +- NonNullable +- Parameters +- ConstructorParameters +- ReturnType +- InstanceType +- NoInfer +- ThisParameterType +- OmitThisParameter +- ThisType +- Uppercase +- Lowercase +- Capitalize +- Uncapitalize + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ts +export let obj: Symbol; + +// file2.ets +import { obj } from './file1'; +let val = obj.prop; +obj.prop = 1; +obj.foo(); +let item = obj[0]; +``` + +**ArkTS1.2** +```typescript +// file1.ts +export let obj: Symbol; +// 从ArkTS1.2看来,这个声明为 +// export let obj: ESValue + +// file2.ets ArkTS1.2 +'use static' +import { obj } from './file1'; +obj.setProperty('prop', ESValue.wrap(1)); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe307.md b/ets2panda/linter/docs/rules-cn/recipe307.md new file mode 100644 index 0000000000000000000000000000000000000000..99303cceeded609d8c62ae551bdd189806332b21 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe307.md @@ -0,0 +1,41 @@ +### ArkTS1.2处理TS非常规异常 + +**规则:** arkts-interop-ts2s-ts-exception + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ts +export function foo() { + throw 123; +} + +// file2.ets +import { foo } from './file1'; + +try { + foo(); +} catch (e) { + console.log("result is " + (e as number)); // 123 +} +``` + +**ArkTS1.2** +```typescript +// file1.ts +export function foo() { + throw 123; +} + +// file2.ets // ArkTS1.2 +'use static' +import { foo } from './file1'; + +try { + foo(); +} catch (e) { + let err: ESValue = (e as ESError).getValue(); + err.toNumber(); // 123 +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe317.md b/ets2panda/linter/docs/rules-cn/recipe317.md new file mode 100644 index 0000000000000000000000000000000000000000..ed695e7b175e3404eb81a6b992f792aa331cf0c1 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe317.md @@ -0,0 +1,21 @@ +## 共享模块不需要use shared修饰 + +**规则:** arkts-limited-stdlib-no-use-shared + +**级别:** error + +新增对象天然共享特性,无需添加use shared。 + +**ArkTS1.1** +```typescript +// test.ets +export let num = 1; +// shared.ets +'use shared' +export {num} from './test'; +``` + +**ArkTS1.2** +```typescript +export let num = 1; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe318.md b/ets2panda/linter/docs/rules-cn/recipe318.md new file mode 100644 index 0000000000000000000000000000000000000000..d202675128f8fba9dc91ea044ec0d90ed8df5f7c --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe318.md @@ -0,0 +1,19 @@ +## 共享函数不需要use concurrent修饰 + +**规则:** arkts-limited-stdlib-no-use-concurrent + +**级别:** error + +新增对象天然共享特性,无需添加use concurrent。 + +**ArkTS1.1** +```typescript +function func() { +'use concurrent' +} +``` + +**ArkTS1.2** +```typescript +function func() {} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe319.md b/ets2panda/linter/docs/rules-cn/recipe319.md new file mode 100644 index 0000000000000000000000000000000000000000..b9ef4d7be95441c4a9f5b85c9ea4b481361e18aa --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe319.md @@ -0,0 +1,57 @@ +## 方法继承/实现参数遵循逆变原则,返回类型遵循协变原则 + +**规则:**`arkts-method-inherit-rule` + +**级别:error** + +ArkTS1.2子类方法覆写父类方法,参数类型须遵循逆变原则,可以通过编译时检查保证类型安全,将潜在的运行时错误提前到编译期,避免运行时失败,无需运行时检查,从而提高执行性能。 + +**逆变/协变:** 用来描述类型转换后的继承关系,如果A、B表示类型,f()表示类型转换,≤表示继承关系(A≤B表示A是由B派生出来的子类),则有: + +- f()为逆变时,当A≤B时有f(B)≤f(A)成立。 + +- f()为协变时,当A≤B时有f(A)≤f(B)成立。 + +**ArkTS1.1** + +```typescript +// ArkTS1.1 +class A { + a: number = 0; +} +class B { + b: number = 0; +} + +class Base { + foo(obj: A | B): void {} +} +class Derived extends Base { + override foo(obj: A): void { // 可以覆写父类方法,ArkTS1.2编译错误 + console.info(obj.a.toString()); + } +} +``` + +**ArkTS1.2** + +```typescript +// ArkTS1.2 +class A { + a: number = 0; +} +class B { + b: number = 0; +} + +class Base { + foo(obj: A | B): void {} +} +class Derived extends Base { + override foo(obj: A | B): void { + if (obj instanceof A) { + console.info(obj.a.toString()); + } + } +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe321.md b/ets2panda/linter/docs/rules-cn/recipe321.md new file mode 100644 index 0000000000000000000000000000000000000000..bd8047302c4139a3541034dfb53cddda71a1f322 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe321.md @@ -0,0 +1,24 @@ +## taskpool不需要import + +**规则:** arkts-limited-stdlib-no-import-concurrency + +**级别:** error + +taskpool实现基于ArkTS提供,不依赖其他模块,不再需要import。 + +**ArkTS1.1** +```typescript +import { taskpool } from '@kit.ArkTS'; + +@Concurrent +function test() {} + +taskpool.execute(test); +``` + +**ArkTS1.2** +```typescript +function test() {} + +taskpool.execute(test); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe322.md b/ets2panda/linter/docs/rules-cn/recipe322.md new file mode 100644 index 0000000000000000000000000000000000000000..05e36074f78dded9c886e51f9eda0fbc061b7988 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe322.md @@ -0,0 +1,18 @@ +## 不提供isConcurrent接口 + +**规则:** arkts-limited-stdlib-no-support-isConcurrent + +**级别:** error + +新增对象天然共享特性,所有函数都是共享的,不需要提供isConcurrent。 + +**ArkTS1.1** +```typescript +import { taskpool } from '@kit.ArkTS'; +@Concurrent +function test() {} +let result: Boolean = taskpool.isConcurrent(test); +``` + +**ArkTS1.2** +不支持isConcurrent接口。 diff --git a/ets2panda/linter/docs/rules-cn/recipe323.md b/ets2panda/linter/docs/rules-cn/recipe323.md new file mode 100644 index 0000000000000000000000000000000000000000..be425c289d49ad32f4bbaec36cbe0670dde5eff1 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe323.md @@ -0,0 +1,35 @@ +### ArkTS1.2导出js实体 + +**规则:** arkts-interop-js2s-export-js + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export function foo() {} +export class A {} + +// file2.ets +import { foo } from './file1'; +export { foo }; + +export { A } from './file1'; + +// 函数、类、变量、枚举 +``` + +**ArkTS1.2** +```typescript +// file1.js +export function foo() {} +export class A {} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let A = mod.getProperty('A'); + +export { foo, A }; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe325.md b/ets2panda/linter/docs/rules-cn/recipe325.md new file mode 100644 index 0000000000000000000000000000000000000000..74eefad55b4270e67585dc9c985c0a509cb9b84b --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe325.md @@ -0,0 +1,23 @@ +## 默认参数必须放在必选参数之后 + +**规则:**`arkts-default-args-behind-required-args` + +**级别:error** + +默认参数放在必选参数之前没有意义,ArkTS1.1上调用该接口时仍须传递每个默认参数。 + +**ArkTS1.1** + +```typescript +function add(left: number = 0, right: number) { + return left + right; +} +``` + +**ArkTS1.2** + +```typescript +function add(left: number, right: number) { + return left + right; +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe326.md b/ets2panda/linter/docs/rules-cn/recipe326.md new file mode 100644 index 0000000000000000000000000000000000000000..fb658ad34e112f86a87d3f1e10d8ceb6056d6dec --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe326.md @@ -0,0 +1,56 @@ +### ArkTS1.1创建ArkTS1.2对象字面量 + +**规则:** arkts-interop-s2d-object-literal + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ets +export class X { + name: string = ''; + constructor(arg: string) { + this.name = arg; + } +} +export interface Y { + data: number; +} +export type MyRecord = Record; +export function foo(arg: X) {} +export function bar(arg: Y) {} + +// file2.ets +import { X, Y } from './file1'; +let x = { name: 'hello' }; +let y: Y = { data: 123 }; +foo({ name: 'world' }); +bar({ data: 456 }); +// 返回值 zoo(): X { return {..}} +// 嵌套场景 +interface Z { + x: X; +} +let z: Z = {x: { name: 'hello' }}; +``` + +**ArkTS1.2** +```typescript +// file1.ets ArkTS1.2 +'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 +} + +// file2.ets ArkTS1.1 +import { X, Y, createY } from "./file1" +let x: X = new X("hello") +let y: Y = createY(123) +foo(new X("world")) +bar(createY(456)) +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe327.md b/ets2panda/linter/docs/rules-cn/recipe327.md new file mode 100644 index 0000000000000000000000000000000000000000..137301896d90742ecb270eb46dabceda3435b4c0 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe327.md @@ -0,0 +1,41 @@ +### ArkTS1.2创建ArkTS1.1具有二义性的对象字面量 + +**规则:** arkts-interop-d2s-object-literal-no-ambiguity + +**级别:** error + +当一个对象的类型被声明为联合类型,而右侧实际赋值的是一个类的实例时,会引发类型系统的二义性(对象可以是联合类型的任一类型,但实际运行时明确是一个类的实例,这种差异会导致类型检查或运行时的不确定性)。 + +**ArkTS1.1** +```typescript +// file1.ets +export class X { + name: string = ''; +} +export interface Y { + name: string; + age?: number; +} + +// file2.ets +import { X, Y } from './file1'; +let x: X | Y = { name: 'hello' }; +``` + +**ArkTS1.2** +```typescript +// file1.ets // 1.0 +export class X { + name: string = ''; +} +export interface Y { + name: string; + age?: number; +} + +// file2.ets // 1.2 +'use static' +import { X, Y } from './file1'; +let x: X | Y = { name: 'hello' }; //编译报错 +let x: X | Y = new X('hello'); // OK +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe328.md b/ets2panda/linter/docs/rules-cn/recipe328.md new file mode 100644 index 0000000000000000000000000000000000000000..58519c0b1482358a3c942c6793afc75c658f8821 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe328.md @@ -0,0 +1,34 @@ +### ArkTS1.2创建ArkTS1.1的没有无参构造函数的类的对象字面量 + +**规则:** arkts-interop-d2s-object-literal-no-args-constructor + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.ets +export class X { + name: string; + constructor(arg: string) { + this.name = arg; + } +} +// file2.ets +import { X } from './file1'; +let x = new X('hello'); +``` + +**ArkTS1.2** +```typescript +// file1.ets ArkTS1.1 +export class X { + name: string; + constructor(arg: string) { + this.name = arg; + } +} +// file2.ets ArkTS1.2 +'use static' +import { X } from './file1'; +let x: X = new X('hello') // 编译报错 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe329.md b/ets2panda/linter/docs/rules-cn/recipe329.md new file mode 100644 index 0000000000000000000000000000000000000000..375cbbb6f75b3e3133492c2c7d224a022f9f0a71 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe329.md @@ -0,0 +1,35 @@ +## Enum不可以通过索引访问成员 + +**规则:**`arkts-enum-no-props-by-index` + +**级别:error** + +1. ArkTS1.1上已对索引访问元素的语法做了限制,ArkTS1.2对枚举场景增强约束。具体内容请参考[不支持通过索引访问字段](typescript-to-arkts-migration-guide.md#不支持通过索引访问字段)。 + +2. ArkTS1.1上枚举是动态对象,ArkTS1.2是静态类型,枚举具有运行时类型。为获得更高的性能,对[]访问做了限制。 + +**ArkTS1.1** + +```typescript +enum TEST { + A, + B, + C +} + +TEST['A']; // ArkTS1.2上不支持这种语法 +TEST[0]; // ArkTS1.2上不支持这种语法 +``` + +**ArkTS1.2** + +```typescript +enum TEST { + A, + B, + C +} + +TEST.A; // 使用.操作符或者enum的值 +TEST.A.getName(); // 使用enum对应的方法获取enum的key +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe330.md b/ets2panda/linter/docs/rules-cn/recipe330.md new file mode 100644 index 0000000000000000000000000000000000000000..a5d8149d1674b8ec56c34fff40775d0aa17b986a --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe330.md @@ -0,0 +1,25 @@ +### ArkTS1.2导入js文件 + +**规则:** arkts-interop-js2s-import-js + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export function foo() {} + +// file2.ets +import { foo } from './file1'; +``` + +**ArkTS1.2** +```typescript +// file1.js +export function foo() {} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe331.md b/ets2panda/linter/docs/rules-cn/recipe331.md new file mode 100644 index 0000000000000000000000000000000000000000..c25c8d537d2eacd49ef2979da4c77c166b222d2b --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe331.md @@ -0,0 +1,32 @@ +### ArkTS1.2调用js函数和传参 + +**规则:** arkts-interop-js2s-call-js-func + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export function foo() {} +export function bar(a) {} + +// file2.ets +import { foo, bar } from './file1'; +foo(); +bar(123); +``` + +**ArkTS1.2** +```typescript +// file1.js +export function foo() {} +export function bar(a) {} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let bar = mod.getProperty('bar'); +foo.invoke(); +bar.invoke(ESValue.wrap(123)); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe332.md b/ets2panda/linter/docs/rules-cn/recipe332.md new file mode 100644 index 0000000000000000000000000000000000000000..da8b232e283da1382e8473c51a3b68c002a0cfa0 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe332.md @@ -0,0 +1,28 @@ +### ArkTS1.2访问js属性 + +**规则:** arkts-interop-js2s-access-js-prop + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { name: '123' }; +// file2.ets +import { foo } from './file1'; +foo.name; +foo.name = '456'; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = {name: "123"} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1') +let foo = mod.getProperty('foo') +foo.getProperty('name') +foo.setProperty('name', ESValue.wrap("456")) +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe333.md b/ets2panda/linter/docs/rules-cn/recipe333.md new file mode 100644 index 0000000000000000000000000000000000000000..9b1da1e7467d65ff3fdbcb0a7cc792ca5b31658d --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe333.md @@ -0,0 +1,49 @@ +### ArkTS1.2转换js对象类型 + +**规则:** arkts-interop-js2s-convert-js-type + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo1 = { num: 123 }; +export let foo2 = { bool: true }; +export let foo3 = { str: '123' }; +export let foo4 = { big: 123n }; + +// file2.ets +import { foo } from './file1'; +let a: number = foo1.num as number; +let b: boolean = foo2.bool as boolean; +let c: string = foo3.str as string; +let d: bigint = foo4.big as bigint; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo1 = { num: 123 }; +export let foo2 = { bool: true }; +export let foo3 = { str: '123' }; +export let foo4 = { big: 123n }; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo1 = mod.getProperty('foo1'); +let num = foo1.getProperty('num'); +let a1: number = num.toNumber(); + +let foo2 = mod.getProperty('foo2'); +let bool = foo2.getProperty('bool'); +let a2: boolean = bool.toBoolean(); + +let foo3 = mod.getProperty('foo3'); +let str = foo3.getProperty('str'); +let a3: string = str.toString(); + +let foo4 = mod.getProperty('foo4'); +let big = foo4.getProperty('big'); +let a4: bigint = big.toBigInt(); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe334.md b/ets2panda/linter/docs/rules-cn/recipe334.md new file mode 100644 index 0000000000000000000000000000000000000000..e713d8e4d5bd778e9ee9341bcbdd5b5feb52f666 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe334.md @@ -0,0 +1,29 @@ +### ArkTS1.2获取js对象类型 + +**规则:** arkts-interop-js2s-typeof-js-type + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { num: 123 }; + +// file2.ets +import { foo } from './file1'; +typeof foo.num; // 'number' +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = 123; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let num = foo.getProperty('num'); + +num.typeOf(); // 'number' +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe335.md b/ets2panda/linter/docs/rules-cn/recipe335.md new file mode 100644 index 0000000000000000000000000000000000000000..546ecc685bf33ecdd589cb1f4e55ec7ae5849ab8 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe335.md @@ -0,0 +1,37 @@ +### ArkTS1.2对js对象进行一元运算 + +**规则:** arkts-interop-js2s-unary-op + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { num: 0 }; +// file2.ets +import { foo } from './file1'; ++foo.num; +-foo.num; +!foo.num; +~foo.num; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = { num: 0 }; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let num = foo.getProperty('num'); +// +foo.num ++num.toNumber(); +// -foo.num +-num.toNumber(); +// !foo.num +!num.toNumber(); +// ~foo.num +~num.toNumber(); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe336.md b/ets2panda/linter/docs/rules-cn/recipe336.md new file mode 100644 index 0000000000000000000000000000000000000000..c81548e27f860046072efb8eb30545984235ce43 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe336.md @@ -0,0 +1,41 @@ +### ArkTS1.2对js对象进行二元运算 + +**规则:** arkts-interop-js2s-binary-op + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { a: 1, b: 2 }; + +// file2.ets +import { foo } from './file1'; +let a = foo.a; +let b = foo.b; +a + b; +a - b; +a * b; +a / b; +a % b; +a ** b; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = { a: 1, b: 2 }; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let a = foo.getProperty('a').toNumber(); +let b = foo.getProperty('b').toNumber(); +a + b; +a - b; +a * b; +a / b; +a % b; +a ** b; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe337.md b/ets2panda/linter/docs/rules-cn/recipe337.md new file mode 100644 index 0000000000000000000000000000000000000000..125ac990e95cc73b35700949daab010a87c645bd --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe337.md @@ -0,0 +1,39 @@ +### ArkTS1.2对js数据进行比较 + +**规则:** arkts-interop-js2s-compare-js-data + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { a: 1, b: 2 }; + +// file2.ets +import { foo } from './file1'; +let a = foo.a; +let b = foo.b; +a > b; +a < b; +a >= b; +a <= b; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let a = 1; +export let b = 2; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let a = foo.getProperty('a').toNumber(); +let b = foo.getProperty('b').toNumber(); + +a > b; +a < b; +a >= b; +a <= b; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe338.md b/ets2panda/linter/docs/rules-cn/recipe338.md new file mode 100644 index 0000000000000000000000000000000000000000..7db945140c6d5d167b183229f6c2ff44008be2ac --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe338.md @@ -0,0 +1,39 @@ +### ArkTS1.2对js数据进行相等判断 + +**规则:** arkts-interop-js2s-equality-judgment + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +class A {} +export let a = new A(); +export let b = new A(); + +// file2.ets +import { a, b } from './file1'; +a == b; +a != b; +a === b; +a !== b; +``` + +**ArkTS1.2** +```typescript +// file1.js +class A {} +export let a = new A(); +export let b = new A(); + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let a = mod.getProperty('a'); +let b = mod.getProperty('b'); + +a.isEqualTo(b); +!a.isEqualTo(b); +a.isStrictlyEqualTo(b); +!a.isStrictlyEqualTo(b); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe339.md b/ets2panda/linter/docs/rules-cn/recipe339.md new file mode 100644 index 0000000000000000000000000000000000000000..929aadf9c2a260791f69f772730e1c5a25997451 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe339.md @@ -0,0 +1,30 @@ +### ArkTS1.2访问js索引 + +**规则:** arkts-interop-js2s-access-js-index + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { arr: [1, 2, 3] }; +// file2.ets +import { foo } from './file1'; +let arr = foo.arr; +arr[1]; +arr[3] = 4; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = [1, 2, 3]; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let arr = foo.getProperty('arr'); +arr.getProperty(1); +arr.setProperty(3, ESValue.wrap(4)); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe34.md b/ets2panda/linter/docs/rules-cn/recipe34.md new file mode 100644 index 0000000000000000000000000000000000000000..85ff8aa03dcd353d140ccf72949ad79536cdb36c --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe34.md @@ -0,0 +1,34 @@ +## 创建泛型实例需要类型实参 + +**规则:**`arkts-no-inferred-generic-params` + +**级别:error** + +ArkTS1.2中,创建泛型实例时需要类型实参。 + +**ArkTS1.1** + +```typescript +new Array() // 违反规则 + +new Map(); // 违反规则 + +class Box { + value: T; + constructor(value: T) { + this.value = value; + } +} + +let box = new Box(42); // 违反规则 +``` + +**ArkTS1.2** + +```typescript +new Array() // 指定类型 + +new Map(); // 显式指定键值类型 + +let box = new Box(42); // 明确指定类型 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe340.md b/ets2panda/linter/docs/rules-cn/recipe340.md new file mode 100644 index 0000000000000000000000000000000000000000..4aed1d919801b9b6ce1680c09f2de663eb8d7978 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe340.md @@ -0,0 +1,34 @@ +### ArkTS1.2 await js Promise对象 + +**规则:** arkts-interop-js2s-await-js-promise + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +async function foo(){} +export let p = foo() + +// file2.ets +import {p} from "./file1" +async function bar() { + await p.toPromise(); +} +``` + +**ArkTS1.2** +```typescript +// file1.js +async function foo(){} +export let p = foo() + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1') +let p = mod.getProperty('p') + +async function bar() { + await p.toPromise(); +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe341.md b/ets2panda/linter/docs/rules-cn/recipe341.md new file mode 100644 index 0000000000000000000000000000000000000000..15ba9c732fd1696b5590b5fd9b58882f3779459c --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe341.md @@ -0,0 +1,30 @@ +### ArkTS1.2实例化js对象 + +**规则:** arkts-interop-js2s-create-js-instance + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +class foo { + constructor(a) {} +} +// file2.ets +import { foo } from './file1'; +new foo(123); +``` + +**ArkTS1.2** +```typescript +// file1.js +class foo { + constructor(a) {} +} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +foo.instantiate(ESValue.wrap(123)); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe342.md b/ets2panda/linter/docs/rules-cn/recipe342.md new file mode 100644 index 0000000000000000000000000000000000000000..8c0b819f4e1f5250c8a8a766d10894f2b9ae295a --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe342.md @@ -0,0 +1,31 @@ +### ArkTS1.2调用js方法和传参 + +**规则:** arkts-interop-js2s-call-js-method + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +class Foo { + bar(a) {} +} +export let foo = new Foo(); +// file2.ets +import { foo } from './file1'; +foo.bar(123); +``` + +**ArkTS1.2** +```typescript +// file1.js +class Foo { + bar(a) {} +} + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +foo.invokeMethod('bar', ESValue.wrap(123)); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe343.md b/ets2panda/linter/docs/rules-cn/recipe343.md new file mode 100644 index 0000000000000000000000000000000000000000..513a10a46371df09a2de3ee792b547d03b179314 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe343.md @@ -0,0 +1,31 @@ +### ArkTS1.2判断js对象类型 + +**规则:** arkts-interop-js2s-instanceof-js-type + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export class Foo {} +export let foo = new Foo(); + +// file2.ets +import { Foo, foo } from './file1'; +foo instanceof Foo; +``` + +**ArkTS1.2** +```typescript +// file1.js +export class Foo {} +export let foo = new Foo(); + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let Foo = mod.getProperty('Foo'); +let foo = mod.getProperty('foo'); + +foo.isInstanceOf(Foo); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe344.md b/ets2panda/linter/docs/rules-cn/recipe344.md new file mode 100644 index 0000000000000000000000000000000000000000..1797cfc140be9267235b1de395404fc8a2f1349f --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe344.md @@ -0,0 +1,46 @@ +### ArkTS1.2对js对象自增自减 + +**规则:** arkts-interop-js2s-self-addtion-reduction + +**级别:** error + +**ArkTS1.1** +```typescript +// file1.js +export let foo = { num: 0 }; + +// file2.ets +import { foo } from './file1'; +let a: number = 0; +a = foo.num++; +a = ++foo.num; +a = foo.num--; +a = --foo.num; +``` + +**ArkTS1.2** +```typescript +// file1.js +export let foo = { num: 0 }; + +// file2.ets // ArkTS1.2 +'use static' +let mod = ESValue.load('./file1'); +let foo = mod.getProperty('foo'); +let a: number = 0; + +// a = foo.num++ +let num = foo.getProperty('num'); +let tmp: number = num.toNumber(); +a = tmp; +foo.setProperty('num', ESValue(tmp + 1)); + +// a = ++foo.num + +num = foo.getProperty('num'); +tmp = num.toNumber() + 1; +foo.setProperty('num', ESValue(tmp)); +a = tmp; + +// the cases "foo.num--" and "--foo.num" are similar +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe349.md b/ets2panda/linter/docs/rules-cn/recipe349.md new file mode 100644 index 0000000000000000000000000000000000000000..792ea62fea9afbb43aebaf87a54c14ded688c66b --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe349.md @@ -0,0 +1,19 @@ +## 内存默认共享,不提供SharedArrayBuffer + +**规则:** arkts-no-need-stdlib-sharedArrayBuffer + +**级别:** error + +新增对象天然共享特性,ArrayBuffer默认共享,不需要SharedArrayBuffer。 + +**ArkTS1.1** +```typescript +let sab: SharedArrayBuffer = new SharedArrayBuffer(20); +let int32 = new Int32Array(sab); +``` + +**ArkTS1.2** +```typescript +let sab: ArrayBuffer = new ArrayBuffer(20); +let int32 = new Int32Array(sab); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe350.md b/ets2panda/linter/docs/rules-cn/recipe350.md new file mode 100644 index 0000000000000000000000000000000000000000..64a870d23a15172742f97cce8f67afe1a8af5852 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe350.md @@ -0,0 +1,55 @@ +## 移除taskpool setCloneList接口 + +**规则:** arkts-limited-stdlib-no-setCloneList + +**级别:** error + +内存默认共享,不需要提供setCloneList来拷贝传递对象。 + +**ArkTS1.1** +```typescript +import { taskpool } from '@kit.ArkTS'; + +@Sendable +class BaseClass { + public str: string = 'sendable: BaseClass'; +} + +@Concurrent +function testFunc(array: Array) { + let baseInstance = array[0]; + console.info('sendable: str1 is: ' + baseInstance.str); + return baseInstance.str; +} + +let baseInstance: BaseClass = new BaseClass(); +let array = new Array(); +array.push(baseInstance); +let task = new taskpool.Task(testFunc, array); +task.setCloneList(array); +taskpool.execute(task).then((res: Object):void => { + console.info('sendable: task res is: ' + res) +}); +``` + +**ArkTS1.2** +```typescript +class BaseClass { + public str: string = 'BaseClass'; +} + +function testFunc(array: Array) { + let baseInstance = array[0]; + console.info('str1 is: ' + baseInstance.str); + return baseInstance.str; +} + + +let baseInstance: BaseClass = new BaseClass(); +let array = new Array(); +array.push(baseInstance); +let task = new taskpool.Task(testFunc, array); +taskpool.execute(task).then((res: Any):void => { + console.info('task res is: ' + res) +}); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe351.md b/ets2panda/linter/docs/rules-cn/recipe351.md new file mode 100644 index 0000000000000000000000000000000000000000..469e1adc16a9622efd1147d6dc7e079449582d01 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe351.md @@ -0,0 +1,68 @@ +## 移除taskpool setTransferList接口 + +**规则:** arkts-limited-stdlib-no-setTransferList + +**级别:** error + +内存默认共享,不需要提供setTransferList来跨线程传递ArrayBuffer对象。 + +**ArkTS1.1** +```typescript +import { taskpool } from '@kit.ArkTS'; + +@Concurrent +function testTransfer(arg1: ArrayBuffer, arg2: ArrayBuffer): number { + console.info('testTransfer arg1 byteLength: ' + arg1.byteLength); + console.info('testTransfer arg2 byteLength: ' + arg2.byteLength); + return 100; +} + +let buffer: ArrayBuffer = new ArrayBuffer(8); +let view: Uint8Array = new Uint8Array(buffer); +let buffer1: ArrayBuffer = new ArrayBuffer(16); +let view1: Uint8Array = new Uint8Array(buffer1); + +console.info('testTransfer view byteLength: ' + view.byteLength); +console.info('testTransfer view1 byteLength: ' + view1.byteLength); +// 执行结果为: +// testTransfer view byteLength: 8 +// testTransfer view1 byteLength: 16 + +let task: taskpool.Task = new taskpool.Task(testTransfer, view, view1); +task.setTransferList([view.buffer, view1.buffer]); +taskpool.execute(task).then((res: Object) => { + console.info('test result: ' + res); +}).catch((e: string) => { + console.error('test catch: ' + e); +}) +console.info('testTransfer view2 byteLength: ' + view.byteLength); +console.info('testTransfer view3 byteLength: ' + view1.byteLength); +// 经过transfer转移之后值为0,执行结果为: +// testTransfer view2 byteLength: 0 +// testTransfer view3 byteLength: 0 +``` + +**ArkTS1.2** +```typescript +function testTransfer(arg1: Uint8Array, arg2: Uint8Array): number { + console.info('testTransfer arg1 byteLength: ' + arg1.byteLength); + console.info('testTransfer arg2 byteLength: ' + arg2.byteLength); + return 100.0; +} + +let buffer: ArrayBuffer = new ArrayBuffer(8); +let view: Uint8Array = new Uint8Array(buffer); +let buffer1: ArrayBuffer = new ArrayBuffer(16); +let view1: Uint8Array = new Uint8Array(buffer1); + +let task: taskpool.Task = new taskpool.Task(testTransfer, view, view1); +taskpool.execute(task).then((res: Any):void => { + console.info('test result: ' + res); +}).catch((e: Error): void => { + console.error('test catch: ' + e); +}) +// 内存共享,此处可直接访问view,view1的内容,不需要使用setTransferList +// 执行结果为: +// testTransfer arg1 byteLength: 8 +// testTransfer arg2 byteLength: 16 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe355.md b/ets2panda/linter/docs/rules-cn/recipe355.md new file mode 100644 index 0000000000000000000000000000000000000000..ae7a8b470b828f703eaf3084096e81cf65c89aa5 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe355.md @@ -0,0 +1,18 @@ +## 共享对象不添加装饰器@Sendable + +**规则:** arkts-limited-stdlib-no-sendable-decorator + +**级别:** error + +新增对象天然共享特性,不再依赖Sendable特性,无需添加@Sendable装饰器。 + +**ArkTS1.1** +```typescript +@Sendable +class A {} +``` + +**ArkTS1.2** +```typescript +class A {} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe356.md b/ets2panda/linter/docs/rules-cn/recipe356.md new file mode 100644 index 0000000000000000000000000000000000000000..453b81ec8d4c888300fbe863fedf4a429b8b9a28 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe356.md @@ -0,0 +1,18 @@ +## 共享函数不添加装饰器@Concurrent + +**规则:** arkts-limited-stdlib-no-concurrent-decorator + +**级别:** error + +新增对象天然共享特性,不再依赖Concurrent特性,无需添加@Concurrent装饰器。 + +**ArkTS1.1** +```typescript +@Concurrent +function func() {} +``` + +**ArkTS1.2** +```typescript +function func() {} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe357.md b/ets2panda/linter/docs/rules-cn/recipe357.md new file mode 100644 index 0000000000000000000000000000000000000000..ab498bbf0bb557831d552f405d30d20e87a30edc --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe357.md @@ -0,0 +1,24 @@ +## 不支持Worker + +**规则:** arkts-no-need-stdlib-worker + +**级别:** error + +内存天然共享,不需要基于Actor模型实现ThreadWorker。使用ArkTS1.2提供的新线程api-EAWorker。 + +**ArkTS1.1** +```typescript +import { worker } from '@kit.ArkTS'; + +const workerInstance: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/Worker.ets') +``` + +**ArkTS1.2** +```typescript +let eaw = new EAWorker(); +eaw.run(():void => { + console.info('hello, eaworker!'); +}); + +eaw.join(); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe37.md b/ets2panda/linter/docs/rules-cn/recipe37.md new file mode 100644 index 0000000000000000000000000000000000000000..24a573c8b6a4c1ff201bbdcf4276facc18789f31 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe37.md @@ -0,0 +1,40 @@ +## 不支持正则表达式 + +**规则:**`arkts-no-regexp-literals` + +**级别:error** + +ArkTS1.2不支持正则表达式字面量。 + +**ArkTS1.1** + +```typescript +let regex: RegExp = /bc*d/; +let regex = /\d{2,4}-\w+/g; // 违反规则 +function matchPattern(str: string) { + return str.match(/hello\s+world/i); // 违反规则 +} + +let text = "Hello world!"; +let result = text.replace(/world/, "ArkTS"); // 违反规则 + +let items = "apple,banana, cherry".split(/\s*,\s*/); // 违反规则 +``` + +**ArkTS1.2** + +```typescript +let regex: RegExp = new RegExp('bc*d'); +let regex = new RegExp('\\d{2,4}-\\w+', 'g'); // 使用 `RegExp` 类 +function matchPattern(str: string) { + let regex = new RegExp('hello\\s+world', 'i'); // 使用 `RegExp` + return str.match(regex); +} + +let text = "Hello world!"; +let regex = new RegExp('world'); // 使用 `RegExp` 类 +let result = text.replace(regex, "ArkTS"); + +let regex = new RegExp('\\s*,\\s*'); // 使用 `RegExp` +let items = "apple,banana, cherry".split(regex); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe370.md b/ets2panda/linter/docs/rules-cn/recipe370.md new file mode 100644 index 0000000000000000000000000000000000000000..1e974f94fafb759dd5e57250e5948d461f0b1bb0 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe370.md @@ -0,0 +1,26 @@ +## 不支持空数组/稀疏数组 + +**规则:**`arkts-no-sparse-array` + +**级别:error** + +1. ArkTS1.2遵循静态类型,空数组需要能根据上下文推导出数组元素的类型,否则会有编译错误。 + +2. ArkTS1.2的数组是连续存储的,空位(如 [1, , , 2])会浪费内存。‌ + +3. ArkTS1.2遵循空值安全,无法使用默认undefined表示空缺。 + +**ArkTS1.1** + +```typescript +let a = []; // ArkTS1.2,编译错误,需要从上下文中推导数组类型 +let b = [1, , , 2]; // 不支持数组中的空位 +b[1]; // undefined +``` + +**ArkTS1.2** + +```typescript +let a: number[] = []; // 支持,ArkTS1.2上可以从上下文推导出类型 +let b = [1, undefined, undefined, 2]; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe371.md b/ets2panda/linter/docs/rules-cn/recipe371.md new file mode 100644 index 0000000000000000000000000000000000000000..35094b1d9578581007d2075e7a22b4cfc5582d0f --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe371.md @@ -0,0 +1,25 @@ +## enum的元素不能作为类型 + +**规则:**`arkts-no-enum-prop-as-type` + +**级别:error** + +ArkTS1.1上的枚举是编译时概念,在运行时仍是普通对象。ArkTS1.2遵循静态类型,需要在运行时为enum提供类型。因此,ArkTS1.2上枚举的每个元素是枚举类的实例(在运行时才确定),无法成为编译时的静态类型信息。这与ArkTS1.2整体类型设计上不支持实例类型相违背。 + +**ArkTS1.1** + +```typescript +enum A { E = 'A' } +function foo(a: A.E) {} +``` + +**ArkTS1.2** + +```typescript +enum A { E = 'A' } +function foo(a: 'A') {} + +// ... +enum A { E = 'A' } +function foo(a: A) {} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe372.md b/ets2panda/linter/docs/rules-cn/recipe372.md new file mode 100644 index 0000000000000000000000000000000000000000..3e966558830bc3f948313cc9cbea64bc523a7000 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe372.md @@ -0,0 +1,41 @@ +## 不支持编译阶段根据PromiseSettledResult的status值确定其实际类型 + +**规则:** arkts-not-support-PromiseSettledResult-smartcast + +**级别:** error + +arkts1.2中不支持对类的成员变量进行智能转换(智能类型差异arkts-no-ts-like-smart-type)。 + +**智能转换:** 编译器会在某些场景下(如instanceof、null检查、上下文推导等)识别出对象的具体类型,自动将变量转换为相应类型,而无需手动转换。 + +**ArkTS1.1** +```typescript +let f1 = Promise.resolve('fulfilled 1'); +Promise.allSettled([f1]) + .then((results: PromiseSettledResult[]) => { + results.forEach((result: PromiseSettledResult) => { + if (result.status === 'fulfilled') { + console.log(`${result.value} `); + } else { + console.log(`${result.reason.message} `); + } + }); + }) +``` + +**ArkTS1.2** +```typescript +let f1 = Promise.resolve('fulfilled 1'); +Promise.allSettled([f1]) + .then((results: PromiseSettledResult[]) => { + results.forEach((result: PromiseSettledResult) => { + if (result.status === 'fulfilled') { + let result1 = result as PromiseFulfilledResult; + console.log(result1.value); + } else { + let result1 = result as PromiseRejectedResult; + console.log(result1.reason.message); + } + }); + }) +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe373.md b/ets2panda/linter/docs/rules-cn/recipe373.md new file mode 100644 index 0000000000000000000000000000000000000000..581e9430b1c4f002a84d8c676c47cf1cae3b1fad --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe373.md @@ -0,0 +1,39 @@ +## 数组/元组类型在继承关系中遵循不变性原则 + +**规则:**`arkts-array-type-immutable` + +**级别:error** + +ArkTS1.2上数组在继承关系中遵循不变性原则,可以通过编译时检查保证类型安全,将潜在的运行时错误提前到编译期,避免运行时失败,从而提高执行性能。 + +**ArkTS1.1** + +```typescript +class A { + a: number = 0; +} + +class B { + b: number = 0; +} + +// ArkTS1.1 +let arr1: A[] = [new A()]; +let arr2: (A | B)[] = arr1; // ArkTS1.2编译错误 +``` + +**ArkTS1.2** + +```typescript +class A { + a: number = 0; +} + +class B { + b: number = 0; +} + +// ArkTS1.2 +let arr1: [ A | B ] = [new A()]; +let arr2: [ A | B ] = arr1; // 需要相同类型的元组 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe374.md b/ets2panda/linter/docs/rules-cn/recipe374.md new file mode 100644 index 0000000000000000000000000000000000000000..32d237362a7193c2a06f6fc675cc6c3d821a0276 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe374.md @@ -0,0 +1,27 @@ +## new Number/Boolean/String不再是"object"类型 + +**规则:**`arkts-primitive-type-normalization` + +**级别:error** + +1. 在ArkTS1.2中primitive type和boxed type是相同的类型,这样可以提高语言一致性和性能。 + 比较Number/Boolean/String时比较的是值而不是对象。 + +2. 在ArkTS1.1上,boxed类型通过new创建。在获取其类型、比较boxed类型对象时会产生意外行为,这是因为对象比较时是通过引用进行比较,而不是值。通常直接使用primitive + type性能更高效,内存占用更少(相比之下对象会占用更多内存)。 + +**ArkTS1.1** + +```typescript +typeof new Number(1) // 结果: "object" +new Number(1) == new Number(1);  //结果: false +if (new Boolean(false)) {} // 在if语句中new Boolean(false)为true +``` + +**ArkTS1.2** + +```typescript +typeof new Number(1)// 结果: "number" +new Number(1) == new Number(1);  //结果: true +if (new Boolean(false)) {} // 在if语句中new Boolean(false)为false +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe375.md b/ets2panda/linter/docs/rules-cn/recipe375.md new file mode 100644 index 0000000000000000000000000000000000000000..f3453ed62789eb250942286056ae085e02be233f --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe375.md @@ -0,0 +1,31 @@ +## catch语句中是error类型 + +**规则:**`arkts-no-ts-like-catch-type` + +**级别:error** + +在ArkTS1.1上catch语句中的e是any类型。因此,编译器不会对catch语句中的异常进行编译时类型检查。当ArkTS1.1上限制throw时,只能抛出Error类型。 + +在ArkTS1.2的静态模式中,类型必须明确,同时需考虑与ArkTS1.1的兼容性。对于catch(e)的语法,默认e为Error类型。 + +**ArkTS1.1** + +```typescript +try { + throw new Error(); +} catch(e) { // e是any类型 + e.message; // ArkTS1.1编译通过,运行正常 + e.prop; // ArkTS1.1编译通过,输出undefined +} +``` + +**ArkTS1.2** + +```typescript +try { + throw new Error(); +} catch(e:Error) { // e是Error类型 + e.message; // ArkTS1.2编译通过,运行正常 + e.prop; // ArkTS1.2编译错误,需要将e转换成需要处理的异常类型,例如:(e as SomeError).prop +} +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe376.md b/ets2panda/linter/docs/rules-cn/recipe376.md new file mode 100644 index 0000000000000000000000000000000000000000..40ad96807f5efbd4b1f4ef3b6986b492c0cfe931 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe376.md @@ -0,0 +1,29 @@ +## 数值类型和bigint类型的比较 + +**规则:**`arkts-numeric-bigint-compare` + +**级别:error** + + 当前暂不支持数值类型和bigint类型的比较,迁移工具将提示开发者修改源码,不提供自动修复能力。 + +**ArkTS1.1** + +```typescript +let n1: number = 123; +let n2: bigint = 456n; + +n1 <= n2; // 编译通过 +n1 == n2; // 编译失败 +n1 >= n2; // 编译通过 +``` + +**ArkTS1.2** + +```typescript +let n1: number = 123; +let n2: bigint = 456n; + +BigInt(n1) <= n2; +BigInt(n1) == n2; +BigInt(n1) >= n2; +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe377.md b/ets2panda/linter/docs/rules-cn/recipe377.md new file mode 100644 index 0000000000000000000000000000000000000000..8e6437bb920f871a8a686701987c9c7385a07ad1 --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe377.md @@ -0,0 +1,23 @@ +## 非十进制bigint字面量 + +**规则:**`arkts-only-support-decimal-bigint-literal` + +**级别:error** + + 当前暂不支持非十进制bigint字面量,通过迁移工具提示开发者修改源码,不提供自动修复能力。 + +**ArkTS1.1** + +```typescript +let a1: bigint = 0xBAD3n; // 十六进制字面量,ArkTS1.2暂不支持 +let a2: bigint = 0o777n; // 八进制字面量,ArkTS1.2暂不支持 +let a3: bigint = 0b101n; // 二进制字面量,ArkTS1.2暂不支持 +``` + +**ArkTS1.2** + +```typescript +let a1: bigint = BigInt(0xBAD3); +let a2: bigint = BigInt(0o777); +let a3: bigint = BigInt(0b101); +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe378.md b/ets2panda/linter/docs/rules-cn/recipe378.md new file mode 100644 index 0000000000000000000000000000000000000000..529097ba0f970f10434b461071bffb93f39efd5b --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe378.md @@ -0,0 +1,25 @@ +## 不支持逻辑赋值运算 + +**规则:**`arkts-unsupport-operator` + +**级别:error** + +1. 当前暂不支持&&=, ||=, ??=逻辑赋值运算符,通过迁移工具提示开发者修改源码,不提供自动修复能力。 + +**ArkTS1.1** + +```typescript +let a = 1; +a &&= 2; // 结果: 2,ArkTS1.2暂不支持 +a ||= 3; // 结果: 2,ArkTS1.2暂不支持 +a ??= 4; // 结果: 2,ArkTS1.2暂不支持 +``` + +**ArkTS1.2** + +```typescript +let a = 1; +a = a && 2; // 结果: 2 +a = a || 3; // 结果: 2 +a = a ?? 4; // 结果: 2 +``` diff --git a/ets2panda/linter/docs/rules-cn/recipe382.md b/ets2panda/linter/docs/rules-cn/recipe382.md new file mode 100644 index 0000000000000000000000000000000000000000..f39e4f8c8ebde25d56e98a336026d23088cd37aa --- /dev/null +++ b/ets2panda/linter/docs/rules-cn/recipe382.md @@ -0,0 +1,25 @@ +## Promise\构造器中只支持使用resolve(undefined) + +**规则:** arkts-promise-with-void-type-need-undefined-as-resolve-arg + +**级别:** error + +ArkTS1.2中void不能作为变量类型声明;作为泛型时,在类实例化时会自动转换为undefined。 +**ArkTS1.1** +```typescript +let p1 = new Promise((resolve, reject) => { + resolve(); +}) +let p2 = new Promise((resolve, reject) => { + setTimeout(resolve, 10); +}) +``` + +**ArkTS1.2** +```typescript +let p1 = new Promise((resolve, reject) => { + resolve(); +}) +let p2 = new Promise((resolve, reject) => { + setTimeout(() => {resolve(undefined)}, 10); +}) \ No newline at end of file diff --git a/ets2panda/linter/homecheck/README.md b/ets2panda/linter/homecheck/README.md index 63099bd3a431ab77211159873c9ef6922254e57f..b485697ce3c71d0af070fac7fcacaf33116f47d0 100644 --- a/ets2panda/linter/homecheck/README.md +++ b/ets2panda/linter/homecheck/README.md @@ -81,8 +81,8 @@ npm install projectName:需要检测工程的名字 projectPath:需要检测工程的路径 logPath:日志输出路径 -ohosSdkPath:ohossdk路径,比如DevEco Studio安装目录下的sdk\default\openharmony\ets -hmsSdkPath:hmssdk路径,比如DevEco Studio安装目录下的sdk\default\hms\ets +ohosSdkPath:ohossdk路径,比如DevEco Studio安装目录下的sdk\default\openharmony\ets,请使用绝对路径 +hmsSdkPath:hmssdk路径,比如DevEco Studio安装目录下的sdk\default\hms\ets,请使用绝对路径 checkPath:解析指定的文件 sdkVersion:sdk版本 fix:是否修复 @@ -121,6 +121,7 @@ sdksThirdParty:sdk三方库,name:库名称,path:库路径,moduleName 字段说明: +参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/ide-code-linter-V14#section1782903483817 ``` files:待检测文件类型 ignore:过滤文件 diff --git a/ets2panda/linter/homecheck/package.json b/ets2panda/linter/homecheck/package.json index ae47a9e950e04f2fffdffb639519b65f7ac3138f..d6345b08fc34e4bd4c98f2502359099292656eab 100644 --- a/ets2panda/linter/homecheck/package.json +++ b/ets2panda/linter/homecheck/package.json @@ -1,6 +1,5 @@ { "scripts": { - "installArkAnalyzer": "bash ./scripts/install_arkanalyzer.sh", "compile": "tsc -p ./tsconfig.prod.json", "test": "vitest --no-color run", "coverage": "vitest run --coverage", diff --git a/ets2panda/linter/homecheck/ruleSet.json b/ets2panda/linter/homecheck/ruleSet.json index adfc2898b56f1dc1b440bbe682d6abdf1d9c2fa0..0bd8f48742b977b71d144c3942d150d51e4969c8 100644 --- a/ets2panda/linter/homecheck/ruleSet.json +++ b/ets2panda/linter/homecheck/ruleSet.json @@ -1,200 +1,4 @@ { - "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, @@ -208,6 +12,9 @@ "@migration/interop-dynamic-object-literals": 1, "@migration/interop-assign": 1, "@migration/interop-boxed-type-check": 1, - "@migration/interop-js-modify-property": 1 + "@migration/interop-js-modify-property": 1, + "@migration/arkts-interop-s2d-object-literal": 1, + "@migration/arkts-interop-s2d-dynamic-call-builtin-api-not-in-static": 1, + "@migration/arkts-numeric-semantic": 1 } -} +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/scripts/run_ci_ut.sh b/ets2panda/linter/homecheck/scripts/run_ci_ut.sh deleted file mode 100644 index 56f455f87bfec03844eb6ea991bb9669ff4b7d15..0000000000000000000000000000000000000000 --- a/ets2panda/linter/homecheck/scripts/run_ci_ut.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/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 index 6ad78b6bfe25006f6ab5f366effe38a2e7136803..b3228e9bd598c32c541a12874d949bdf8559b560 100644 --- a/ets2panda/linter/homecheck/src/Index.ts +++ b/ets2panda/linter/homecheck/src/Index.ts @@ -42,4 +42,4 @@ export { Utils } from './utils/common/Utils'; // tools export { runTool, Tools } from './tools/toolEntry'; -export { MigrationTool } from './tools/migrationTool/MigrationTool'; +export { MigrationTool } from './tools/migrationTool/MigrationTool'; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts index 693f8914126a9a7d9a5da0d9e697963b77e5e460..8e1ef29f16e35b25605f8c61be37708dc72dd945 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts @@ -139,7 +139,7 @@ export class AppStorageGetCheck implements BaseChecker { } private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { const originPath = arkFile.getFilePath(); diff --git a/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts index b8dcb06db7d2c47226110a65dfc9298937fdc42c..07ab293ad11c4b8aa8e964e4911ef8029bec96e2 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts @@ -23,19 +23,15 @@ import { AliasType, AbstractInvokeExpr, Value, - ArkFile, AstTreeUtils, ts, - FunctionType, - ArkClass, - ANONYMOUS_METHOD_PREFIX, - ArkInvokeStmt, + UnionType, } 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 { RuleFix } from '../../model/Fix'; import { FixPosition, FixUtils } from '../../utils/common/FixUtils'; import { WarnInfo } from '../../utils/common/Utils'; @@ -79,52 +75,9 @@ export class CustomBuilderCheck implements BaseChecker { 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; @@ -144,20 +97,26 @@ export class CustomBuilderCheck implements BaseChecker { return undefined; } - private isCustomBuilderTy(ty: Type): boolean { - return ty instanceof AliasType && ty.getName() === 'CustomBuilder'; + private isCustomBuilderTy(type: Type): boolean { + const isRawCustomBuilderTy = (ty: Type): boolean => { + return ty instanceof AliasType && ty.getName() === 'CustomBuilder'; + }; + return isRawCustomBuilderTy(type) || (type instanceof UnionType && type.getTypes().some(ty => isRawCustomBuilderTy(ty))); } private isPassToCustomBuilder(stmt: Stmt, locals: Set): Local | undefined { + let res: Local | undefined = 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; + if (this.isCustomBuilderTy(stmt.getLeftOp().getType())) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && locals.has(rightOp)) { + res = rightOp; + } } } + if (res !== undefined) { + return res; + } const invokeExpr = stmt.getInvokeExpr(); if (invokeExpr) { const paramTys = invokeExpr.getMethodSignature().getMethodSubSignature().getParameterTypes(); @@ -208,7 +167,7 @@ export class CustomBuilderCheck implements BaseChecker { } private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { const originPath = arkFile.getFilePath(); @@ -229,9 +188,12 @@ export class CustomBuilderCheck implements BaseChecker { fixPosition.endLine = endPosition.line; fixPosition.endCol = endPosition.col; } - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); const range = FixUtils.getRangeWithAst(sourceFile, fixPosition); + if (range === null) { + return null; + } ruleFix.range = range; const originalText = FixUtils.getSourceWithRange(sourceFile, range); if (originalText !== null) { diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts index e1645a7e6a8e410f199133a8e33f148be69d3ea5..140b4e81e349c9258aa046ba8f27d1e58e1d3788 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts @@ -27,6 +27,12 @@ import { FunctionType, ClassType, ArkNamespace, + PrimitiveType, + UnclearReferenceType, + AnyType, + UnionType, + NullType, + UndefinedType, } from 'arkanalyzer/lib'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { BaseChecker, BaseMetaData } from '../BaseChecker'; @@ -44,7 +50,7 @@ const gMetaData: BaseMetaData = { }; 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; @@ -91,49 +97,76 @@ export class InteropAssignCheck implements BaseChecker { } } - private checkPassToFunction(target: ArkMethod, scene: Scene) { + private checkPassToFunction(target: ArkMethod, scene: Scene): void { 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(); - const argTyLang = this.getTypeDefinedLang(argTy, scene) ?? csMethod?.getLanguage() ?? Language.UNKNOWN; - if (argTyLang === Language.ARKTS1_1) { - hasTargetArg = true; + callsites + .filter(cs => cs.getCfg().getDeclaringMethod().getLanguage() === Language.ARKTS1_1) + .forEach(cs => { + let hasTargetArg = false; + const invoke = cs.getInvokeExpr()!; + const csMethod = cs.getCfg().getDeclaringMethod(); + invoke.getArgs().forEach((arg, argIdx) => { + const argTy = arg.getType(); + if (argTy instanceof PrimitiveType || this.isBoxedType(argTy)) { + return; + } + const paramTy = invoke.getMethodSignature().getMethodSubSignature().getParameterTypes()[argIdx]; + if (this.isAnyType(paramTy) || this.isESObjectType(paramTy)) { + 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)); }); - 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 checkAssignToField(target: ArkMethod, scene: Scene) { + private isAnyType(ty: Type): boolean { + return ty instanceof AnyType || (ty instanceof UnclearReferenceType && ty.getName() === 'Any'); + } + + private isESObjectType(ty: Type): boolean { + if (!(ty instanceof UnionType)) { + return false; + } + const types = ty.getTypes(); + if (types.length !== 3) { + return false; + } + const isObjectTy = (type: Type): boolean => { + return type instanceof ClassType && type.getClassSignature().getClassName() === 'Object'; + }; + return ( + types.find(ty => ty instanceof NullType) !== undefined && + types.find(ty => ty instanceof UndefinedType) !== undefined && + types.find(ty => isObjectTy(ty)) !== 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): void { 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(); @@ -148,21 +181,8 @@ export class InteropAssignCheck implements BaseChecker { 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 - ); + 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)); }); } @@ -185,11 +205,7 @@ export class InteropAssignCheck implements BaseChecker { 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()}` - ); + 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); } @@ -232,16 +248,12 @@ export class InteropAssignCheck implements BaseChecker { const paramRef = this.isFromParameter(currentStmt); if (paramRef) { const paramIdx = paramRef.getIndex(); - const callsites = this.cg.getInvokeStmtByMethod( - currentStmt.getCfg().getDeclaringMethod().getSignature() - ); + 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) - ); + 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)); } @@ -285,8 +297,6 @@ export class InteropAssignCheck implements BaseChecker { } 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 index d80cc3aeb509dfdb6e3bbee43a4acd7515a553f5..d6f08df82416c10d75ea6fef50e25a4df5d46cb6 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts @@ -33,6 +33,10 @@ import { UnknownType, Local, ArkClass, + ArkInvokeStmt, + ArkReturnStmt, + ArkThrowStmt, + PrimitiveType, } from 'arkanalyzer/lib'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { BaseChecker, BaseMetaData } from '../BaseChecker'; @@ -70,6 +74,7 @@ const OBJECT_API: Map = new Map([ ['getOwnPropertyDescriptor', 0], ['getOwnPropertyDescriptors', 0], ['getOwnPropertyNames', 0], + ['hasOwn', 0], ['isExtensible', 0], ['isFrozen', 0], ['isSealed', 0], @@ -118,7 +123,7 @@ export class InteropBackwardDFACheck implements BaseChecker { } }; - private collectImportedVar(importVarMap: Map, file: ArkFile, scene: Scene) { + private collectImportedVar(importVarMap: Map, file: ArkFile, scene: Scene): void { file.getImportInfos().forEach(importInfo => { const exportInfo = importInfo.getLazyExportInfo(); if (exportInfo === null) { @@ -137,7 +142,7 @@ export class InteropBackwardDFACheck implements BaseChecker { }); } - private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { + private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene): void { const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); if (defaultMethod) { DVFGHelper.buildSingleDVFG(defaultMethod, scene); @@ -175,11 +180,14 @@ export class InteropBackwardDFACheck implements BaseChecker { const invoke = stmt.getInvokeExpr(); let isReflect = false; let paramIdx = -1; - if (invoke && invoke instanceof ArkInstanceInvokeExpr) { - if (invoke.getBase().getName() === 'Reflect') { + if (invoke && invoke instanceof ArkStaticInvokeExpr) { + const classSig = invoke.getMethodSignature().getDeclaringClassSignature(); + if ( + classSig.getDeclaringFileSignature().getProjectName() === 'built-in' && + classSig.getDeclaringNamespaceSignature()?.getNamespaceName() === 'Reflect' + ) { isReflect = true; - paramIdx = - REFLECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; + paramIdx = REFLECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; } } if (invoke && invoke instanceof ArkStaticInvokeExpr) { @@ -211,9 +219,9 @@ export class InteropBackwardDFACheck implements BaseChecker { } } - private reportIssue(objDefInfo: ObjDefInfo, apiLang: Language, isReflect: boolean) { + private reportIssue(objDefInfo: ObjDefInfo, apiLang: Language, isReflect: boolean): void { const problemStmt = objDefInfo.problemStmt; - const problemStmtMtd = problemStmt.getCfg()?.getDeclaringMethod(); + const problemStmtMtd = problemStmt.getCfg().getDeclaringMethod(); const problemStmtLang = problemStmtMtd?.getLanguage(); const objLanguage = objDefInfo.objLanguage; if (objLanguage === Language.UNKNOWN || problemStmtLang === Language.UNKNOWN) { @@ -288,8 +296,8 @@ export class InteropBackwardDFACheck implements BaseChecker { } } const rightOpTy = rightOp.getType(); - if (!this.isIrrelevantType(rightOpTy)) { - const rightOpTyLang = this.getTypeDefinedLang(rightOpTy, scene); + if (!this.isIrrelevantType(rightOpTy) && !(rightOpTy instanceof PrimitiveType)) { + const rightOpTyLang = this.getTypeDefinedLang(rightOpTy, scene) ?? currentStmt.getCfg().getDeclaringMethod().getLanguage(); if (rightOpTyLang && rightOpTyLang !== apiLanguage) { res.push({ problemStmt: currentStmt, objLanguage: rightOpTyLang }); continue; @@ -327,42 +335,35 @@ export class InteropBackwardDFACheck implements BaseChecker { 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 - ); + 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 - ); + 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)); }); + } else { + current.getIncomingEdge().forEach(e => { + const srcNode = e.getSrcNode() as DVFGNode; + const srcStmt = srcNode.getStmt(); + if (srcStmt.getDef() === stmt.getRightOp()) { + worklist.push(srcNode); + } + }) } + } else if ((stmt instanceof ArkReturnStmt) || (stmt instanceof ArkThrowStmt)) { + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); } } } @@ -426,8 +427,8 @@ export class InteropBackwardDFACheck implements BaseChecker { } } const argTy = arg.getType(); - if (!this.isIrrelevantType(argTy)) { - const argTyLang = this.getTypeDefinedLang(argTy, scene); + if (!this.isIrrelevantType(argTy) && !(argTy instanceof PrimitiveType)) { + const argTyLang = this.getTypeDefinedLang(argTy, scene) ?? stmt.getCfg().getDeclaringMethod().getLanguage(); if (argTyLang && argTyLang !== apiLanguage) { return argTyLang; } diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts index 42b4dc0973a789fe6d96f7a86e20bb8323dbbdf0..d0a1c9b10fa1064e34fd46de5cbbdbb79c1e2859 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts @@ -40,7 +40,7 @@ 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 logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropBoxedTypeCheck'); const gMetaData: BaseMetaData = { severity: 1, ruleDocPath: '', diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropDeprecatedBuiltInAPICheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropDeprecatedBuiltInAPICheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..02b2b9170d73ce7c3f2d229094381ffd9c9317b7 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropDeprecatedBuiltInAPICheck.ts @@ -0,0 +1,989 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ArkNamespace, + Local, + ClassType, + ClassSignature, + Type, + BooleanType, + FunctionType, + AnyType, + MethodSignature, + UnknownType, + GenericType, + NumberType, + ArrayType, + MethodSubSignature, + ArkInvokeStmt, + AbstractInvokeExpr, + ArkInstanceInvokeExpr, + ArkPtrInvokeExpr, + ImportInfo, + UnionType, + FileSignature, + ArkStaticInvokeExpr, + UndefinedType, + VoidType, +} 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 { ArkClass } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { MethodParameter } from 'arkanalyzer/lib/core/model/builder/ArkMethodBuilder'; +import { AbstractFieldRef, ArkReturnStmt } from 'arkanalyzer'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'DeprecatedBuiltInAPICheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +enum APIBaseCategory { + Array = 'Array', + Set = 'Set', + Map = 'Map', +} + +class DeprecatedAPIInfo { + constructor( + public base: APIBaseCategory, + public name: string, + public isStatic: boolean, + public returnType?: Type, // return Type为undefined时表示不关心API的返回值 + public params?: Type[], // return Type为undefined时表示不关心API的形参,应该是整个API都被废弃,而非某一重载形态 + public targetParamIndex?: number // 若isStatic为tue,说明是静态接口,需要提供查找接口的第几个param是否来源arkts1.2,编号从0开始,不提供则查找base的来源 + ) {} +} + +class APIBasicType { + static readonly genericTypeT = new GenericType('T'); + static readonly genericTypeU = new GenericType('U'); + static readonly genericTypeV = new GenericType('V'); + static readonly genericTypeK = new GenericType('K'); + static readonly genericTypeS = new GenericType('S'); + static readonly arrayT = new ArrayType(this.genericTypeT, 1); + static readonly arrayU = new ArrayType(this.genericTypeU, 1); + static readonly unknownType = UnknownType.getInstance(); + static readonly numberType = NumberType.getInstance(); + static readonly booleanType = BooleanType.getInstance(); + static readonly anyType = AnyType.getInstance(); + static readonly undefinedType = UndefinedType.getInstance(); + static readonly voidType = VoidType.getInstance(); +} + +class APIComplicatedType { + static readonly anonyMethodName = 'anonymous'; + static readonly predicateFunctionType = this.createPredicateFunctionType(); + static readonly predicateFunction1Type = this.createPredicateFunction1Type(); + static readonly concatItemType = this.createConcatItemType(); + static readonly mapfnFunctionType = this.createMapfnFunctionType(); + static readonly ArrayLikeType = new ClassType(new ClassSignature('ArrayLike', FileSignature.DEFAULT)); + static readonly IterableType = new ClassType(new ClassSignature('Iterable', FileSignature.DEFAULT)); + static readonly SetType = new ClassType(new ClassSignature('Set', FileSignature.DEFAULT)); + static readonly MapType = new ClassType(new ClassSignature('Map', FileSignature.DEFAULT)); + static readonly setCallbackFnFunctionType = this.createSetCallbackFnFunctionType(); + static readonly mapCallbackFnFunctionType = this.createMapCallbackFnFunctionType(); + + // 对于参数类型一致,但是参数名称不同、返回值类型不同的FunctionType,视为同一个,不重新创建。因为FunctionType类型匹配的时候仅匹配参数类型 + // 不同的API,仅形参为lambda函数且该lambda函数的返回值不同,例如unknown和value is S类型谓词形式,视为同一个API + private static createPredicateFunctionType(): FunctionType { + const predicateValueParam = new MethodParameter(); + predicateValueParam.setName('value'); + predicateValueParam.setType(APIBasicType.genericTypeT); + const predicateIndexParam = new MethodParameter(); + predicateIndexParam.setName('index'); + predicateIndexParam.setType(APIBasicType.numberType); + const predicateArrayParam = new MethodParameter(); + predicateArrayParam.setName('array'); + predicateArrayParam.setType(APIBasicType.arrayT); + const predicateMethodSubSignature = new MethodSubSignature( + this.anonyMethodName, + [predicateValueParam, predicateIndexParam, predicateArrayParam], + APIBasicType.unknownType + ); + return new FunctionType(new MethodSignature(ClassSignature.DEFAULT, predicateMethodSubSignature)); + } + + private static createPredicateFunction1Type(): FunctionType { + const predicateThisParam = new MethodParameter(); + predicateThisParam.setName('this'); + predicateThisParam.setType(APIBasicType.voidType); + const predicateValueParam = new MethodParameter(); + predicateValueParam.setName('value'); + predicateValueParam.setType(APIBasicType.genericTypeT); + const predicateIndexParam = new MethodParameter(); + predicateIndexParam.setName('index'); + predicateIndexParam.setType(APIBasicType.numberType); + const predicateObjParam = new MethodParameter(); + predicateObjParam.setName('obj'); + predicateObjParam.setType(APIBasicType.arrayT); + const predicateMethodSubSignature = new MethodSubSignature( + this.anonyMethodName, + [predicateThisParam, predicateValueParam, predicateIndexParam, predicateObjParam], + APIBasicType.booleanType + ); + return new FunctionType(new MethodSignature(ClassSignature.DEFAULT, predicateMethodSubSignature)); + } + + private static createConcatItemType(): UnionType { + return new UnionType([APIBasicType.genericTypeT, new ClassType(new ClassSignature('ConcatArray', FileSignature.DEFAULT))]); + } + + private static createMapfnFunctionType(): FunctionType { + const mapfnParamV = new MethodParameter(); + mapfnParamV.setName('v'); + mapfnParamV.setType(APIBasicType.genericTypeT); + const mapfnParamK = new MethodParameter(); + mapfnParamK.setName('k'); + mapfnParamK.setType(APIBasicType.numberType); + const mapfnMethodSubSignature = new MethodSubSignature(this.anonyMethodName, [mapfnParamV, mapfnParamK], APIBasicType.genericTypeU); + return new FunctionType(new MethodSignature(ClassSignature.DEFAULT, mapfnMethodSubSignature)); + } + + private static createSetCallbackFnFunctionType(): FunctionType { + const callbackFnValueParam = new MethodParameter(); + callbackFnValueParam.setName('value'); + callbackFnValueParam.setType(APIBasicType.genericTypeT); + const callbackFnValue2Param = new MethodParameter(); + callbackFnValue2Param.setName('value2'); + callbackFnValue2Param.setType(APIBasicType.genericTypeT); + const callbackFnSetParam = new MethodParameter(); + callbackFnSetParam.setName('set'); + callbackFnSetParam.setType(this.SetType); + const predicateMethodSubSignature = new MethodSubSignature( + this.anonyMethodName, + [callbackFnValueParam, callbackFnValue2Param, callbackFnSetParam], + APIBasicType.voidType + ); + return new FunctionType(new MethodSignature(ClassSignature.DEFAULT, predicateMethodSubSignature)); + } + + private static createMapCallbackFnFunctionType(): FunctionType { + const callbackFnValueParam = new MethodParameter(); + callbackFnValueParam.setName('value'); + callbackFnValueParam.setType(APIBasicType.genericTypeV); + const callbackFnKeyParam = new MethodParameter(); + callbackFnKeyParam.setName('key'); + callbackFnKeyParam.setType(APIBasicType.genericTypeK); + const callbackFnMapParam = new MethodParameter(); + callbackFnMapParam.setName('map'); + callbackFnMapParam.setType(this.MapType); + const predicateMethodSubSignature = new MethodSubSignature( + this.anonyMethodName, + [callbackFnValueParam, callbackFnKeyParam, callbackFnMapParam], + APIBasicType.voidType + ); + return new FunctionType(new MethodSignature(ClassSignature.DEFAULT, predicateMethodSubSignature)); + } +} + +class DeprecatedAPIList { + static readonly DeprecatedAPIs: DeprecatedAPIInfo[] = [ + this.createArrayEveryAPI1(), + this.createArrayFilterAPI1(), + this.createArrayFindAPI1(), + this.createArrayFindAPI2(), + this.createArrayFindIndexAPI(), + this.createArrayForEachAPI(), + this.createArrayMapAPI(), + this.createArraySomeAPI(), + this.createArrayConcatAPI(), + this.createArrayFlatAPI(), + this.createArrayFlatMapAPI(), + this.createArrayFromArrayLikeAPI(), + this.createArrayFromIterableAndArrayLikeAPI(), + this.createSetForEachAPI(), + this.createMapForEachAPI(), + this.createArraySymbolIteratorAPI(), + this.createSetSymbolIteratorAPI(), + this.createMapSymbolIteratorAPI(), + ]; + + private static createArrayEveryAPI1(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'every', false, APIBasicType.booleanType, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayFilterAPI1(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'filter', false, APIBasicType.arrayT, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayFindAPI1(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'find', false, new UnionType([APIBasicType.genericTypeT, APIBasicType.undefinedType]), [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayFindAPI2(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'find', false, new UnionType([APIBasicType.genericTypeS, APIBasicType.undefinedType]), [ + APIComplicatedType.predicateFunction1Type, + APIBasicType.anyType, + ]); + } + + private static createArrayFindIndexAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'findIndex', false, APIBasicType.numberType, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayForEachAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'forEach', false, APIBasicType.voidType, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayMapAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'map', false, APIBasicType.arrayU, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArraySomeAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'some', false, APIBasicType.booleanType, [ + APIComplicatedType.predicateFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArrayConcatAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'concat', false, APIBasicType.arrayT, [new ArrayType(APIComplicatedType.concatItemType, 1)]); + } + + private static createArrayFlatAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'flat', false); + } + + private static createArrayFlatMapAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'flatMap', false); + } + + private static createArrayFromArrayLikeAPI(): DeprecatedAPIInfo { + const fromParams = [APIComplicatedType.ArrayLikeType, APIComplicatedType.mapfnFunctionType, APIBasicType.anyType]; + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'from', true, APIBasicType.arrayU, fromParams, 0); + } + + private static createArrayFromIterableAndArrayLikeAPI(): DeprecatedAPIInfo { + const fromParams = [ + new UnionType([APIComplicatedType.ArrayLikeType, APIComplicatedType.IterableType]), + APIComplicatedType.mapfnFunctionType, + APIBasicType.anyType, + ]; + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'from', true, APIBasicType.arrayU, fromParams, 0); + } + + private static createSetForEachAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Set, 'forEach', false, APIBasicType.voidType, [ + APIComplicatedType.setCallbackFnFunctionType, + APIBasicType.anyType, + ]); + } + + private static createMapForEachAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Map, 'forEach', false, APIBasicType.voidType, [ + APIComplicatedType.mapCallbackFnFunctionType, + APIBasicType.anyType, + ]); + } + + private static createArraySymbolIteratorAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Array, 'Symbol.iterator', false); + } + + private static createSetSymbolIteratorAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Set, 'Symbol.iterator', false); + } + + private static createMapSymbolIteratorAPI(): DeprecatedAPIInfo { + return new DeprecatedAPIInfo(APIBaseCategory.Map, 'Symbol.iterator', false); + } +} + +export class InteropDeprecatedBuiltInAPICheck 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 scene: Scene; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.scene = scene; + 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进行检查 + if (!(arkFile.getLanguage() === Language.ARKTS1_1)) { + continue; + } + const defaultMethod = arkFile.getDefaultClass().getDefaultArkMethod(); + let globalVarMap: Map = new Map(); + if (defaultMethod) { + this.dvfgBuilder.buildForSingleMethod(defaultMethod); + globalVarMap = getGlobalsDefineInDefaultMethod(defaultMethod); + } + for (let arkClass of arkFile.getClasses()) { + this.processArkClass(arkClass, globalVarMap); + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, globalVarMap); + } + } + }; + + public processArkClass(arkClass: ArkClass, globalVarMap: Map): void { + this.processArkMethod(arkClass.getInstanceInitMethod(), globalVarMap); + this.processArkMethod(arkClass.getStaticInitMethod(), globalVarMap); + for (let mtd of arkClass.getMethods()) { + this.processArkMethod(mtd, globalVarMap); + } + } + + public processNameSpace(namespace: ArkNamespace, globalVarMap: Map): void { + for (let ns of namespace.getNamespaces()) { + this.processNameSpace(ns, globalVarMap); + } + for (let arkClass of namespace.getClasses()) { + this.processArkClass(arkClass, globalVarMap); + } + } + + public processArkMethod(target: ArkMethod, globalVarMap: Map): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + // 查找到DeprecatedAPIs中的builtIn的API调用语句为sink点,从该点开始进行逆向数据流分析,分析base是否为arkts1.2中声明的对象实例或其引用 + const targetLocal = this.getTargetLocalOfDeprecatedAPICall(stmt); + if (targetLocal === null) { + continue; + } + + // 从base的最近一次赋值语句开始,使用逆向数据流进行查找 + let checkStmt = this.getLastAssignStmt(targetLocal, stmt); + if (checkStmt === null) { + checkStmt = this.checkTargetLocalAsGlobal(target, stmt, targetLocal, globalVarMap); + } + if (checkStmt === null) { + continue; + } + + if (!this.visited.has(target)) { + this.dvfgBuilder.buildForSingleMethod(target); + this.visited.add(target); + } + + let checkAll = { value: true }; + let visited: Set = new Set(); + if (this.checkFromStmt(checkStmt, globalVarMap, checkAll, visited)) { + this.addIssueReport(stmt, targetLocal, checkAll.value); + } + } + } + + private checkTargetLocalAsGlobal(targetMethod: ArkMethod, stmt: Stmt, targetLocal: Local, globalVarMap: Map): Stmt | null { + const globalDefs = globalVarMap.get(targetLocal.getName()); + if (globalDefs === undefined) { + const importInfos = targetMethod.getDeclaringArkClass().getDeclaringArkFile().getImportInfos(); + const importValue = this.isLocalFromImport(targetLocal, importInfos); + if (importValue && importValue.getDeclaringStmt() !== null) { + return importValue.getDeclaringStmt()!; + } + return null; + } + let lastLegalStmtLine = -1; + let lastIllegalStmtLine = -1; + for (const defStmt of globalDefs) { + if (!this.visited.has(targetMethod)) { + this.dvfgBuilder.buildForSingleMethod(targetMethod); + this.visited.add(targetMethod); + } + + let checkAll = { value: true }; + let visited: Set = new Set(); + + const currStmtLine = defStmt.getOriginPositionInfo().getLineNo(); + if (this.checkFromStmt(defStmt, globalVarMap, checkAll, visited)) { + if (currStmtLine > lastIllegalStmtLine) { + lastIllegalStmtLine = currStmtLine; + } + } else { + if (currStmtLine > lastLegalStmtLine) { + lastLegalStmtLine = currStmtLine; + } + } + } + if (lastIllegalStmtLine > lastLegalStmtLine) { + this.addIssueReport(stmt, targetLocal); + } + return null; + } + + private getLastAssignStmt(local: Local, currStmt: Stmt): Stmt | null { + // 获取local变量在currStmt使用语句之前的最近一次赋值/声明语句,未找到表示直接来自于全局变量或import信息,则返回null + const usedStmts = local.getUsedStmts(); + let currLine = currStmt.getOriginPositionInfo().getLineNo(); + let lastAssignStmt = local.getDeclaringStmt(); + for (const stmt of usedStmts) { + if (stmt === currStmt || !(stmt instanceof ArkAssignStmt) || stmt.getLeftOp() !== local) { + continue; + } + const line = stmt.getOriginPositionInfo().getLineNo(); + if (line < currLine) { + lastAssignStmt = stmt; + currLine = line; + } + } + return lastAssignStmt; + } + + private isLocalDefinedInStaticArkTS(local: Local): boolean { + return local.getDeclaringStmt()?.getCfg().getDeclaringMethod().getLanguage() === Language.ARKTS1_2; + } + + // 判断语句是否为废弃API接口的调用语句,若废弃接口仅为一系列重载中的某一种,需要判断这一具体重载形态,若是返回对应需要查找的Local对象,否则返回null + private getTargetLocalOfDeprecatedAPICall(stmt: Stmt): Local | null { + const invokeExpr = this.getInvokeExpr(stmt); + if (invokeExpr === null) { + return null; + } + if (invokeExpr instanceof ArkInstanceInvokeExpr) { + const base = invokeExpr.getBase(); + if (this.isInstanceCallMethodInDeprecatedAPIs(base, stmt, invokeExpr.getMethodSignature(), invokeExpr.getArgs())) { + return base; + } + // Array.from的API调用ArkAnalyzer也表示为ArkInstanceInvokeExpr,因为API定义里没有明确的static标识 + return this.getTargetLocalInArrayFrom(invokeExpr); + } else if (invokeExpr instanceof ArkPtrInvokeExpr) { + // TODO:可能存在ptr invoke的场景吗? + return null; + } else if (invokeExpr instanceof ArkStaticInvokeExpr) { + // Symbol.iterator API 检测的Reflect.get场景,是static invoke + return this.getTargetLocalInReflectGet(invokeExpr); + } + return null; + } + + private getInvokeExpr(stmt: Stmt): AbstractInvokeExpr | null { + if (!(stmt instanceof ArkAssignStmt) && !(stmt instanceof ArkInvokeStmt)) { + return null; + } + + if (stmt instanceof ArkInvokeStmt) { + return stmt.getInvokeExpr(); + } + + const rightOp = stmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr) { + return rightOp; + } + return null; + } + + private compareParamTypes(apiParams: Type[], callApiParams: MethodParameter[]): boolean { + if (apiParams.length !== callApiParams.length) { + return false; + } + for (let i = 0; i < apiParams.length; i++) { + if (!this.isTypeMatch(apiParams[i], callApiParams[i].getType())) { + return false; + } + } + return true; + } + + // 此函数仅用作Symbol.iterator API 检测的Reflect.get场景 + private getTargetLocalInReflectGet(staticInvokeExpr: ArkStaticInvokeExpr): Local | null { + const method = staticInvokeExpr.getMethodSignature(); + const methodName = method.getMethodSubSignature().getMethodName(); + const namespaceName = method.getDeclaringClassSignature().getDeclaringNamespaceSignature()?.getNamespaceName(); + if (namespaceName !== 'Reflect' || methodName !== 'get') { + return null; + } + + const args = staticInvokeExpr.getArgs(); + if (args.length < 2) { + return null; + } + const targetLocal = args[0]; + const apiCall = args[1]; + if (!(targetLocal instanceof Local) || !(apiCall instanceof Local)) { + return null; + } + + const declaringStmt = apiCall.getDeclaringStmt(); + if (declaringStmt === null || !(declaringStmt instanceof ArkAssignStmt)) { + return null; + } + const rightOp = declaringStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceFieldRef)) { + return null; + } + const fieldBaseName = rightOp.getBase().getName(); + const fieldName = rightOp.getFieldName(); + if (fieldBaseName !== 'Symbol' || fieldName !== 'iterator') { + return null; + } + + for (const api of DeprecatedAPIList.DeprecatedAPIs) { + if (api.name !== 'Symbol.iterator') { + continue; + } + if (api.base === APIBaseCategory.Array && targetLocal.getType() instanceof ArrayType) { + return targetLocal; + } + if (api.base === APIBaseCategory.Set) { + const localType = targetLocal.getType(); + if (localType instanceof ClassType && localType.getClassSignature().getClassName() === 'Set') { + return targetLocal; + } + } + if (api.base === APIBaseCategory.Map) { + const localType = targetLocal.getType(); + if (localType instanceof ClassType && localType.getClassSignature().getClassName() === 'Map') { + return targetLocal; + } + } + } + return null; + } + + private getTargetLocalInArrayFrom(invokeExpr: ArkInstanceInvokeExpr): Local | null { + const callApiMethod = invokeExpr.getMethodSignature(); + const callApiClass = callApiMethod.getDeclaringClassSignature(); + for (const api of DeprecatedAPIList.DeprecatedAPIs) { + if (!api.isStatic) { + continue; + } + if (api.name !== callApiMethod.getMethodSubSignature().getMethodName()) { + continue; + } + // Array.from 形式的调用,from方法实际的class为ArrayConstructor + if (api.base !== callApiClass.getClassName() && `${api.base}Constructor` !== callApiClass.getClassName()) { + continue; + } + // 在本条规则检查范围内的static API的调用一定是带参数的,并且其中某个参数即为需要进行进一步查找的value + if (api.params === undefined) { + continue; + } + if (this.compareParamTypes(api.params, callApiMethod.getMethodSubSignature().getParameters())) { + const args = invokeExpr.getArgs(); + // 形参匹配的情况下,进一步比较传入的实参,因为当前废弃接口大多数为去掉any类型的第二个可选参数 + // TODO:这里需要考虑如何做的更通用 + if (args.length !== api.params.length) { + continue; + } + const index = api.targetParamIndex; + // 成功匹配到指定的API后,如果未提供下一步需要查找的目标param的index,则返回null。理论上不应该走到这个分支。 + if (index === undefined) { + logger.error(`Missing targetParamIndex, api: ${api.name}, category ${api.base}`); + return null; + } + + if (args.length <= index) { + logger.error(`Invalid targetParamIndex ${index}, totally invoke args size ${args.length}, api: ${api.name}, category ${api.base}`); + return null; + } + const target = args[index]; + if (target instanceof Local) { + return target; + } + logger.error(`Need to handle non-local target ${target.getType().getTypeString()}`); + return null; + } + } + return null; + } + + private isInstanceCallMethodInDeprecatedAPIs(callBase: Local, stmt: Stmt, callMethod: MethodSignature, args: Value[]): boolean { + const callApiName = callMethod.getMethodSubSignature().getMethodName(); + const callApiParams = callMethod.getMethodSubSignature().getParameters(); + for (const api of DeprecatedAPIList.DeprecatedAPIs) { + // 对于map[Symbol.iterator]这样的API调用,callApiName是临时变量,需要进一步匹配 + if (api.name !== callApiName) { + continue; + } + // 对于for...of的语句,ArkAnalyzer会为其生成Symbol.iterator的调用语句,此处从源码中查找关键字以区分是源码中有还是自动生成的 + if (api.name === 'Symbol.iterator' && !stmt.getOriginalText()?.includes('Symbol.iterator')) { + continue; + } + if (api.isStatic) { + continue; + } + if (!this.isBaseTypeMatchAPIBase(api.base, callBase)) { + continue; + } + + // Array concat API ArkAnalyzer当前无法很好处理...items形式的入参,此处作为特例处理 + if (api.name === 'concat' && api.base === APIBaseCategory.Array) { + return this.isMatchArrayConcatAPI(args); + } + + const apiParams = api.params; + if (apiParams === undefined) { + return true; + } + let allParamTypeMatch = this.compareParamTypes(apiParams, callApiParams); + if (allParamTypeMatch) { + // 形参匹配的情况下,进一步比较传入的实参,因为当前废弃接口大多数为去掉any类型的第二个可选参数 + // TODO:这里需要考虑如何做的更通用 + if (args.length !== apiParams.length) { + continue; + } + return true; + } + // 形参类型不匹配的情形,可能是由于ArkAnalyzer的类型推导未能找到正确的API,需要根据实参类型进行二次匹配 + if (apiParams.length !== args.length) { + continue; + } + allParamTypeMatch = true; + for (let i = 0; i < apiParams.length; i++) { + // 对于lambda函数作为参数类型,此处不严格校验lambda的参数类型,仅判断是否为FunctionType + if (apiParams[i] instanceof FunctionType && args[i].getType() instanceof FunctionType) { + continue; + } + if (!this.isTypeMatch(apiParams[i], args[i].getType())) { + allParamTypeMatch = false; + break; + } + } + if (allParamTypeMatch) { + return true; + } + } + return false; + } + + // 判断入参是否都为数组,不允许有单个元素 + private isMatchArrayConcatAPI(args: Value[]): boolean { + for (const arg of args) { + if (!(arg.getType() instanceof ArrayType)) { + return true; + } + } + return false; + } + + private isTypeMatch(apiType: Type, callApiType: Type): boolean { + const apiTypeStr = apiType.getTypeString(); + const callApiTypeStr = callApiType.getTypeString(); + if (callApiType instanceof FunctionType && apiType instanceof FunctionType) { + // 若类型为FunctionType,仅需匹配string中的形参部分 + const regex = /\(([^()]*)\)/; + const apiMatch = apiTypeStr.match(regex); + const callApiMatch = callApiTypeStr.match(regex); + if (apiMatch === null || callApiMatch === null) { + return false; + } + // 移除字符串中的类型的文件签名、类签名、泛型等信息后进行比较 + let apiParamsStr = apiMatch[0].replace(/@[^:]+:/, '').replace(/<[^>]+>/, ''); + let callApiParamsStr = callApiMatch[0].replace(/@[^:]+:/, '').replace(/<[^>]+>/, ''); + return apiParamsStr === callApiParamsStr; + } else if (callApiType instanceof ClassType && apiType instanceof ClassType) { + // 若类型为FunctionType,仅需匹配class name,因为apiTypeStr类型推导后有可能为@%unk/%unk: ArrayLike,而callApiTypeStr有明确的declaring file + return callApiType.getClassSignature().getClassName() === apiType.getClassSignature().getClassName(); + } else if (apiType instanceof AnyType) { + return true; + } else { + // 其他场景需严格判断字符串相等 + return apiTypeStr === callApiTypeStr; + } + } + + private isBaseTypeMatchAPIBase(apiBase: APIBaseCategory, callBase: Local): boolean { + if (apiBase === APIBaseCategory.Array && callBase.getType() instanceof ArrayType) { + return true; + } + if (apiBase === APIBaseCategory.Map) { + const callBaseType = callBase.getType(); + return callBaseType instanceof ClassType && callBaseType.getClassSignature().getClassName() === 'Map'; + } + if (apiBase === APIBaseCategory.Set) { + const callBaseType = callBase.getType(); + return callBaseType instanceof ClassType && callBaseType.getClassSignature().getClassName() === 'Set'; + } + return false; + } + + private checkFromStmt(stmt: Stmt, globalVarMap: Map, checkAll: { value: boolean }, visited: Set, depth: number = 0): boolean { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return true; + } + 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.isLeftOpOrReturnOpDefinedInStaticArkTS(currentStmt)) { + return true; + } + + // 当前语句的右值是全局变量,查找全局变量的定义语句 + const gv = this.isRightOpGlobalVar(currentStmt); + if (gv) { + const globalDefs = globalVarMap.get(gv.getName()); + if (globalDefs === undefined) { + const importInfos = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getImportInfos(); + const importValue = this.isLocalFromImport(gv, importInfos); + if (importValue && importValue.getDeclaringStmt() !== null) { + worklist.push(this.dvfg.getOrNewDVFGNode(importValue.getDeclaringStmt()!)); + } + } else { + globalDefs.forEach(d => worklist.push(this.dvfg.getOrNewDVFGNode(d))); + } + continue; + } + + // 当前语句的右值是函数返回值,查找调用函数的所有return语句 + 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, globalVarMap, checkAll, visited, depth + 1); + if (res) { + return true; + } + } + } + + // 当前语句的右值是函数参数赋值语句,查找所有调用处的入参情况 + 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, globalVarMap, checkAll, visited, depth + 1); + if (res) { + return true; + } + } + } + + // 当前语句的右值是属性赋值语句,查找该属性的初始化语句 + if (currentStmt instanceof ArkAssignStmt && currentStmt.getRightOp() instanceof AbstractFieldRef) { + const fieldSignature = (currentStmt.getRightOp() as AbstractFieldRef).getFieldSignature(); + const classSignature = fieldSignature.getDeclaringSignature(); + if (classSignature instanceof ClassSignature) { + const field = this.scene.getClass(classSignature)?.getField(fieldSignature); + if (field) { + field.getInitializer().forEach(s => worklist.push(this.dvfg.getOrNewDVFGNode(s))); + } + } + } + + // 当前语句是return语句,查找return操作数的相关语句 + if (currentStmt instanceof ArkReturnStmt) { + const returnOp = currentStmt.getOp(); + if (returnOp instanceof Local) { + let checkStmt = + this.getLastAssignStmt(returnOp, stmt) ?? + this.checkTargetLocalAsGlobal(currentStmt.getCfg().getDeclaringMethod(), stmt, returnOp, globalVarMap); + if (checkStmt !== null) { + worklist.push(this.dvfg.getOrNewDVFGNode(checkStmt)); + } + } + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + return false; + } + + private isRightOpGlobalVar(stmt: Stmt): Local | undefined { + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + return rightOp; + } + } + return undefined; + } + + private isLocalFromImport(local: Local, importInfos: ImportInfo[]): Local | undefined { + for (const importInfo of importInfos) { + if (importInfo.getImportClauseName() === local.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); + } + }); + } + + // 判断语句是否为赋值语句,且左值的定义来自于ArkTS1.2 + private isLeftOpOrReturnOpDefinedInStaticArkTS(stmt: Stmt): boolean { + if (!(stmt instanceof ArkAssignStmt) && !(stmt instanceof ArkReturnStmt)) { + return false; + } + let operand: Value; + if (stmt instanceof ArkAssignStmt) { + operand = stmt.getLeftOp(); + } else { + operand = stmt.getOp(); + } + if (!(operand instanceof Local)) { + return false; + } + return this.isLocalDefinedInStaticArkTS(operand); + } + + 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)); + let refs = Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + // 以上步骤未找到defs语句,说明入参变量来源自import信息 + if (refs.length === 0 && target instanceof Local) { + const importInfos = callsite.getCfg().getDeclaringMethod().getDeclaringArkFile().getImportInfos(); + const importValue = this.isLocalFromImport(target, importInfos); + if (importValue && importValue.getDeclaringStmt() !== null) { + return importValue.getDeclaringStmt()!; + } + } + return refs; + }); + } + + private addIssueReport(stmt: Stmt, operand: Value, checkAll: boolean = true): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'builtin-api'; + let desc = `Builtin API is not support in ArkTS1.2 (${this.rule.ruleId.replace('@migration/', '')})`; + if (!checkAll) { + desc = `Can not check when function call chain depth exceeds ${CALL_DEPTH_LIMIT}, please check it manually (${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/InteropDynamicObjectLiteralsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts index 3b59046d94a0f620aa22c6d27ffd8ef02c2addc3..9d93f7f9c648f6d3a3efd794d7f3eca38d49080b 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts @@ -110,12 +110,11 @@ export class InteropObjectLiteralCheck implements BaseChecker { 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) { + if (this.checkFromStmt(stmt, scene, checkAll, visited)) { const opType = rightOp.getOp().getType(); if (!(opType instanceof ClassType)) { continue; @@ -124,27 +123,17 @@ export class InteropObjectLiteralCheck implements BaseChecker { 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()); + if (opTypeClass.getLanguage() === Language.TYPESCRIPT || opTypeClass.getLanguage() === Language.ARKTS1_1) { + this.addIssueReport(stmt, rightOp, opTypeClass.getLanguage(), checkAll.value); } } } } - private checkFromStmt( - stmt: Stmt, - scene: Scene, - res: Stmt[], - checkAll: { value: boolean }, - visited: Set, - depth: number = 0 - ): void { + private checkFromStmt(stmt: Stmt, scene: Scene, checkAll: { value: boolean }, visited: Set, depth: number = 0): boolean { if (depth > CALL_DEPTH_LIMIT) { checkAll.value = false; - return; + return true; } const node = this.dvfg.getOrNewDVFGNode(stmt); let worklist: DVFGNode[] = [node]; @@ -156,36 +145,42 @@ export class InteropObjectLiteralCheck implements BaseChecker { } visited.add(currentStmt); if (this.isObjectLiteral(currentStmt, scene)) { - res.push(currentStmt); - continue; + return true; } const callsite = this.cg.getCallSiteByStmt(currentStmt); - callsite.forEach(cs => { + for (const cs of callsite) { const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); if (!declaringMtd || !declaringMtd.getCfg()) { - return; + return false; } 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 returnStmts = declaringMtd.getReturnStmt(); + for (const stmt of returnStmts) { + const res = this.checkFromStmt(stmt, scene, checkAll, visited, depth + 1); + if (res) { + return true; + } + } + } const paramRef = this.isFromParameter(currentStmt); if (paramRef) { const paramIdx = paramRef.getIndex(); - const callsites = this.cg.getInvokeStmtByMethod( - currentStmt.getCfg().getDeclaringMethod().getSignature() - ); + 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) - ); + const argDefs = this.collectArgDefs(paramIdx, callsites); + for (const def of argDefs) { + const res = this.checkFromStmt(def, scene, checkAll, visited, depth + 1); + if (res) { + return true; + } + } } current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); } + return false; } private processCallsites(callsites: Stmt[]): void { @@ -235,7 +230,7 @@ export class InteropObjectLiteralCheck implements BaseChecker { }); } - private addIssueReport(stmt: Stmt, operand: Value, result: Stmt[], targetLanguage: Language): void { + private addIssueReport(stmt: Stmt, operand: Value, targetLanguage: Language, checkAll: boolean = true): void { const interopRuleId = this.getInteropRule(targetLanguage); if (interopRuleId === null) { return; @@ -244,10 +239,11 @@ export class InteropObjectLiteralCheck implements BaseChecker { 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 desc = `instanceof including object literal with class type from ${targetLan} (${interopRuleId})`; + if (!checkAll) { + desc = `Can not check when function call chain depth exceeds ${CALL_DEPTH_LIMIT}, please check it manually (${interopRuleId})`; + } let defects = new Defects( warnInfo.line, warnInfo.startCol, diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts index 3b912361f2bb7896b526e8a434388ddb7de83703..0be4d71d8c7b373e28a44314ac4610866633da75 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts @@ -276,20 +276,18 @@ export class InteropJSModifyPropertyCheck implements BaseChecker { } if (file) { return file.getLanguage(); - } else { - logger.error(`fail to identify which file the type definition ${type.toString()} is in.`); - return Language.UNKNOWN; } + return Language.UNKNOWN; } - private reportIssue(problemStmt: Stmt) { + private reportIssue(problemStmt: Stmt): void { 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 filePath = problemStmt.getCfg().getDeclaringMethod().getDeclaringArkFile()?.getFilePath() ?? ''; const defeats = new Defects( line, column, diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts index 15269d7208e461c9b04075d8aa33f4c96eb3e7cd..27be4df0a6edd2a1213a8c359eda4b1c4eab0d3c 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts @@ -120,7 +120,7 @@ export function findInteropRule( // 包含 object API 的 1.2 函数被导出到 1.1 文件使用 return isReflect ? S2D_STATIC_REFLECT : S2D_STATIC_OBJECT; } else { - return isReflect ? D2S_STATIC_REFLECT : D2S_STATIC_OBJECT; + return undefined; } } if (methodLang === Language.ARKTS1_1 && typeDefLang === Language.ARKTS1_2) { diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropS2DObjectLiteralsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropS2DObjectLiteralsCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e316294f2c9765356eba8f59fe79757c6673036 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropS2DObjectLiteralsCheck.ts @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + Stmt, + Scene, + Value, + ArkInstanceFieldRef, + ClassType, + ArkInvokeStmt, + AbstractInvokeExpr, + ArkField, + ArkReturnStmt, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback, MatcherTypes, MethodMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { ArkClass, ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { getLanguageStr, getLineAndColumn } from './Utils'; +import { ArkThisRef } from 'arkanalyzer'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropS2DObjectLiteralCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const s2dRuleId: string = 'arkts-interop-s2d-object-literal'; + +type IssueData = { + stmt: Stmt; + value: Value; +}; + +export class InteropS2DObjectLiteralCheck implements BaseChecker { + private scene: Scene; + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private methodMatcher: MethodMatcher = { + matcherType: MatcherTypes.METHOD, + }; + + public registerMatchers(): MatcherCallback[] { + const methodMatcher: MatcherCallback = { + matcher: this.methodMatcher, + callback: this.check, + }; + return [methodMatcher]; + } + + public check = (arkMethod: ArkMethod): void => { + this.scene = arkMethod.getDeclaringArkFile().getScene(); + + if (arkMethod.getLanguage() !== Language.ARKTS1_1) { + return; + } + // 检测的sink点为赋值语句,且左值的类型注解明确为1.2的class或者包含1.2的class的更复杂数据结构 + const stmts = arkMethod.getBody()?.getCfg().getStmts() ?? []; + // 检查所有语句 + // 1. 对于赋值语句,检查左边是否为arkts1.2的class类型或某个field为arkts1.2的class类型,右边对象或对应属性是否用arkts1.1的object litral赋值 + // 2. 对于函数调用,可能为invoke语句或赋值语句的右值为invoke表达式,检查入参是否存在如上的情况 + for (const stmt of stmts) { + if (stmt instanceof ArkAssignStmt) { + this.checkAssignWithObjectLiteral(stmt, arkMethod); + if (stmt.getRightOp() instanceof AbstractInvokeExpr) { + this.checkInvokeWithObjectLiteral(stmt, arkMethod); + } + } else if (stmt instanceof ArkInvokeStmt) { + this.checkInvokeWithObjectLiteral(stmt, arkMethod); + } + } + // 检查函数的返回值,若函数签名中返回类型声明是否为arkts1.2的class类型或某个field为arkts1.2的class类型,且实际返回对象或对应属性是否为arkts1.1的object litral + this.checkReturnWithObjectLiteral(arkMethod); + }; + + private getClassWithType(checkType: ClassType): ArkClass | null { + return this.scene.getClass(checkType.getClassSignature()); + } + + private isClassFromEtsStatic(clazz: ArkClass): boolean { + return clazz.getLanguage() === Language.ARKTS1_2 && clazz.getCategory() !== ClassCategory.OBJECT; + } + + private isObjectLiteralFromEtsDynamic(clazz: ArkClass): boolean { + return clazz.getLanguage() === Language.ARKTS1_1 && clazz.getCategory() === ClassCategory.OBJECT; + } + + private checkAssignWithObjectLiteral(stmt: ArkAssignStmt, target: ArkMethod): void { + // this = thisRef 赋值语句需要跳过,否则该class一定会被扫描一遍,此次扫描多余,且可能会产生行号为-1的错误issue + // 若此class有问题,会在真正使用到此class的源码处进行告警,无需查找this ref语句 + if (stmt.getRightOp() instanceof ArkThisRef) { + return; + } + const leftOpType = stmt.getLeftOp().getType(); + if (!(leftOpType instanceof ClassType)) { + return; + } + const leftTypeClass = this.getClassWithType(leftOpType); + if (leftTypeClass === null) { + logger.debug(`Failed to find class of type ${leftOpType.toString()}`); + return; + } + if (this.isClassFromEtsStatic(leftTypeClass)) { + const rightOpType = stmt.getRightOp().getType(); + if (!(rightOpType instanceof ClassType)) { + return; + } + const rightTypeClass = this.getClassWithType(rightOpType); + if (rightTypeClass === null) { + logger.debug(`Failed to find class of type ${rightOpType.toString()}`); + return; + } + if (this.isObjectLiteralFromEtsDynamic(rightTypeClass)) { + this.addIssueReport(stmt, stmt.getRightOp()); + return; + } + } + let results: IssueData[] = []; + this.checkAllClassFieldWithValue(stmt, stmt.getRightOp(), leftTypeClass, results); + for (const result of results) { + this.addIssueReport(result.stmt, result.value); + } + } + + private checkInvokeWithObjectLiteral(stmt: ArkInvokeStmt | ArkAssignStmt, target: ArkMethod): void { + let invokeExpr: AbstractInvokeExpr; + if (stmt instanceof ArkInvokeStmt) { + invokeExpr = stmt.getInvokeExpr(); + } else { + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractInvokeExpr)) { + return; + } + invokeExpr = rightOp; + } + const method = this.scene.getMethod(invokeExpr.getMethodSignature()); + if (method === null) { + logger.debug(`Failed to find method in invoke expr, method: ${invokeExpr.getMethodSignature().toString()}`); + return; + } + for (const [index, param] of method.getParameters().entries()) { + const paramType = param.getType(); + if (!(paramType instanceof ClassType)) { + continue; + } + const paramTypeClass = this.getClassWithType(paramType); + if (paramTypeClass === null) { + logger.debug(`Failed to find class of method param type ${paramType.toString()}, method: ${method.getSignature().toString()}`); + continue; + } + if (index >= invokeExpr.getArgs().length) { + logger.debug(`Failed to find param with index ${index} of method: ${method.getSignature().toString()}`); + continue; + } + const arg = invokeExpr.getArg(index); + if (this.isClassFromEtsStatic(paramTypeClass)) { + const argType = arg.getType(); + if (!(argType instanceof ClassType)) { + continue; + } + const argTypeClass = this.getClassWithType(argType); + if (argTypeClass === null) { + logger.debug(`Failed to find class of invoke arg type ${argType.toString()}, method: ${method.getSignature().toString()}`); + continue; + } + if (this.isObjectLiteralFromEtsDynamic(argTypeClass)) { + this.addIssueReport(stmt, arg); + return; + } + } + let results: IssueData[] = []; + this.checkAllClassFieldWithValue(stmt, arg, paramTypeClass, results); + for (const result of results) { + this.addIssueReport(result.stmt, result.value); + } + } + } + + private checkReturnWithObjectLiteral(target: ArkMethod): void { + // 构造函数的返回值一定是当前class本身,其各field和method已在其他地方进行检查,这里无需检查构造函数的返回值 + if (target.getName() === 'constructor') { + return; + } + const returnType = target.getReturnType(); + if (!(returnType instanceof ClassType)) { + return; + } + const returnTypeClass = this.getClassWithType(returnType); + if (returnTypeClass === null) { + logger.debug(`Failed to find method of return type ${returnType.toString()}, method ${target.getSignature().toString()}`); + return; + } + const returnStmts = target.getReturnStmt(); + if (this.isClassFromEtsStatic(returnTypeClass)) { + for (const returnStmt of returnStmts) { + if (!(returnStmt instanceof ArkReturnStmt)) { + continue; + } + const valueType = returnStmt.getOp().getType(); + if (!(valueType instanceof ClassType)) { + continue; + } + const valueTypeClass = this.getClassWithType(valueType); + if (valueTypeClass === null) { + logger.debug(`Failed to find method of return value type ${valueType.toString()}, method ${target.getSignature().toString()}`); + continue; + } + if (this.isObjectLiteralFromEtsDynamic(valueTypeClass)) { + this.addIssueReport(returnStmt, returnStmt.getOp()); + } + } + return; + } + + for (const returnStmt of returnStmts) { + if (!(returnStmt instanceof ArkReturnStmt)) { + continue; + } + let results: IssueData[] = []; + this.checkAllClassFieldWithValue(returnStmt, returnStmt.getOp(), returnTypeClass, results); + if (results.length > 0) { + this.addIssueReport(returnStmt, returnStmt.getOp()); + } + } + } + + private checkAllClassFieldWithValue(sinkStmt: Stmt, val: Value, needCheckClass: ArkClass, result: IssueData[], checkedTypes?: Set): void { + let visited: Set = checkedTypes ?? new Set(); + if (visited.has(needCheckClass.getSignature().toString())) { + return; + } + visited.add(needCheckClass.getSignature().toString()); + for (const field of needCheckClass.getFields()) { + const fieldType = field.getType(); + if (!(fieldType instanceof ClassType)) { + continue; + } + const fieldTypeClass = this.getClassWithType(fieldType); + if (fieldTypeClass === null) { + logger.debug( + `Failed to find class of type ${fieldType.toString()} of field: ${field.getName()}, class ${needCheckClass.getSignature().toString()}}` + ); + continue; + } + const fieldInitializers = this.getFieldInitializersWithValue(field, val); + const fieldAssignStmt = this.getFieldAssignStmtInInitializers(field, fieldInitializers); + if (fieldAssignStmt === null) { + continue; + } + if (this.isClassFromEtsStatic(fieldTypeClass)) { + const rightOpType = fieldAssignStmt.getRightOp().getType(); + if (!(rightOpType instanceof ClassType)) { + continue; + } + const rightOpTypeClass = this.getClassWithType(rightOpType); + if (rightOpTypeClass === null) { + logger.debug( + `Failed to find class of type ${rightOpType.toString()} of field initializer, field: ${field.getName()}, class ${needCheckClass.getSignature().toString()}}` + ); + continue; + } + if (this.isObjectLiteralFromEtsDynamic(rightOpTypeClass)) { + result.push({ stmt: sinkStmt, value: val }); + continue; + } + continue; + } + this.checkAllClassFieldWithValue(fieldAssignStmt, fieldAssignStmt.getRightOp(), fieldTypeClass, result, visited); + } + } + + private getFieldAssignStmtInInitializers(field: ArkField, fieldInitializers: Stmt[]): ArkAssignStmt | null { + for (const stmt of fieldInitializers) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof ArkInstanceFieldRef)) { + continue; + } + if (leftOp.getFieldName() === field.getName()) { + return stmt; + } + } + return null; + } + + // 对于object literal(主要是多层嵌套场景),根据需要查找的field的名字,获取其对应的内部嵌套class的初始化语句 + private getFieldInitializersWithValue(leftField: ArkField, val: Value): Stmt[] { + const res: Stmt[] = []; + const rightOpType = val.getType(); + if (!(rightOpType instanceof ClassType)) { + return res; + } + const rightOpTypeClass = this.getClassWithType(rightOpType); + if (rightOpTypeClass === null) { + logger.debug(`Failed to find class of type ${rightOpType.toString()} of field: ${leftField.getSignature().toString()}`); + return res; + } + for (const field of rightOpTypeClass.getFields()) { + if (field.getName() === leftField.getName()) { + return field.getInitializer(); + } + } + return res; + } + + private addIssueReport(stmt: Stmt, operand: Value): void { + const severity = this.metaData.severity; + let warnInfo = getLineAndColumn(stmt, operand); + let targetLan1 = getLanguageStr(Language.ARKTS1_1); + let targetLan2 = getLanguageStr(Language.ARKTS1_2); + + const problem = 'Interop'; + const desc = `In ${targetLan1}, it is not allowed to create object literal of type from ${targetLan2} (${s2dRuleId})`; + + 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)); + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts index c25cc59611ec6e7b8182054beace616da724ba7a..eb84f6fc2f8e7ef2ac0162c222cba07576104afc 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts @@ -124,8 +124,6 @@ export class ModifyStateVarCheck implements BaseChecker { 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; } @@ -171,7 +169,7 @@ export class ModifyStateVarCheck implements BaseChecker { } private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { const originPath = arkFile.getFilePath(); diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts index f45c63723cfb7b492c0972d4079cd9d6ef5d6740..bd36723fa88da1c411771da95c4b14c6b491e7d0 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts @@ -15,38 +15,46 @@ import path from 'path'; import { - ArkMethod, + AbstractFieldRef, ArkAssignStmt, - FieldSignature, - Stmt, - Scene, - Value, - DVFGBuilder, - ArkInstanceOfExpr, - CallGraph, - ArkParameterRef, - ArkInstanceFieldRef, - ArkNamespace, - Local, ArkCastExpr, - ClassType, - classSignatureCompare, ArkField, - fileSignatureCompare, - Cfg, - BasicBlock, ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceOfExpr, + ArkMethod, + ArkNamespace, + ArkNormalBinopExpr, + ArkParameterRef, ArkUnopExpr, + BasicBlock, + CallGraph, + Cfg, + ClassSignature, + classSignatureCompare, + ClassType, + DVFGBuilder, + FieldSignature, + fileSignatureCompare, + LineColPosition, + Local, + NormalBinaryOperator, + RelationalBinaryOperator, + Scene, + Stmt, + UnaryOperator, + Value, } 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 { Defects, MatcherCallback, Rule } 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 { CALL_DEPTH_LIMIT, getGlobalsDefineInDefaultMethod, getLineAndColumn, GlobalCallGraphHelper } from './Utils'; import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { BooleanConstant, NumberConstant } from 'arkanalyzer/lib/core/base/Constant'; +import { ArkClass, NumberType } from 'arkanalyzer'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoTSLikeAsCheck'); const gMetaData: BaseMetaData = { @@ -55,11 +63,19 @@ const gMetaData: BaseMetaData = { description: '', }; +enum TypeAssuranceCondition { + Positive, + Negative, + NotExist, +} + export class NoTSLikeAsCheck implements BaseChecker { readonly metaData: BaseMetaData = gMetaData; + readonly checkedBinaryOperator: string[] = ['+', '-', '*', '/', '%', '**']; public rule: Rule; public defects: Defects[] = []; public issues: IssueReport[] = []; + private scene: Scene; private cg: CallGraph; private dvfg: DVFG; private dvfgBuilder: DVFGBuilder; @@ -74,6 +90,7 @@ export class NoTSLikeAsCheck implements BaseChecker { } public check = (scene: Scene): void => { + this.scene = scene; this.cg = GlobalCallGraphHelper.getCGInstance(scene); this.dvfg = new DVFG(this.cg); @@ -91,58 +108,38 @@ export class NoTSLikeAsCheck implements BaseChecker { 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); - } + this.processClass(clazz, globalVarMap); } for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { - this.processNameSpace(namespace, globalVarMap, scene); + this.processNameSpace(namespace, globalVarMap); } } }; - public processNameSpace(namespace: ArkNamespace, globalVarMap: Map, scene: Scene): void { + public processClass(arkClass: ArkClass, globalVarMap: Map): void { + for (let field of arkClass.getFields()) { + this.processClassField(field, globalVarMap); + } + for (let mtd of arkClass.getMethods()) { + this.processArkMethod(mtd, globalVarMap); + } + } + + public processNameSpace(namespace: ArkNamespace, globalVarMap: Map): void { for (let ns of namespace.getNamespaces()) { - this.processNameSpace(ns, globalVarMap, scene); + this.processNameSpace(ns, globalVarMap); } 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); - } + this.processClass(clazz, globalVarMap); } } - 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 processClassField(field: ArkField, globalVarMap: Map): void { + const instInit = field.getDeclaringArkClass().getInstanceInitMethod(); + this.processArkMethod(instInit, globalVarMap); } - public processArkMethod(target: ArkMethod, globalVarMap: Map, scene: Scene): void { + public processArkMethod(target: ArkMethod, globalVarMap: Map): void { const stmts = target.getBody()?.getCfg().getStmts() ?? []; for (const stmt of stmts) { // cast表达式所在语句为sink点,从该点开始进行逆向数据流分析 @@ -150,6 +147,13 @@ export class NoTSLikeAsCheck implements BaseChecker { if (castExpr === null) { continue; } + + // 判断是否为cast表达式的算数运算,属于告警场景之一 + if (this.isCastExprWithNumericOperation(stmt)) { + this.addIssueReport(stmt, castExpr, undefined, true); + continue; + } + // 判断cast类型断言的类型是否是class,非class的场景不在本规则检查范围内 if (!(castExpr.getType() instanceof ClassType)) { continue; @@ -164,7 +168,7 @@ export class NoTSLikeAsCheck implements BaseChecker { let checkAll = { value: true }; let visited: Set = new Set(); - const result = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited); + const result = this.checkFromStmt(stmt, globalVarMap, checkAll, visited); if (result !== null) { this.addIssueReport(stmt, castExpr, result); } else { @@ -175,27 +179,104 @@ export class NoTSLikeAsCheck implements BaseChecker { } } + private isCastExprWithNumericOperation(stmt: Stmt): boolean { + if (this.isCastExprWithIncrementDecrement(stmt)) { + return true; + } + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof ArkCastExpr)) { + return false; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNormalBinopExpr)) { + return false; + } + const op1 = rightOp.getOp1(); + if (leftOp !== op1) { + return false; + } + const operator = rightOp.getOperator(); + return this.checkedBinaryOperator.includes(operator); + } + + private isCastExprWithIncrementDecrement(stmt: Stmt): boolean { + if (!(stmt instanceof ArkAssignStmt) || !(stmt.getRightOp() instanceof ArkCastExpr)) { + return false; + } + const castLocal = stmt.getLeftOp(); + if (!(castLocal instanceof Local)) { + return false; + } + // 判断是否为自增或自减语句,需要判断used stmt是否至少包含%0 = %0 + 1 和 castExpr = %0两条语句,不新增临时变量 + // 非自增或自减语句,used stmt中仅包含%1 = %0 + 1 + const usedStmts = castLocal.getUsedStmts(); + if (usedStmts.length !== 2) { + return false; + } + let selfAssignFlag = false; + let assignBackFlag = false; + for (const usedStmt of usedStmts) { + if (!(usedStmt instanceof ArkAssignStmt)) { + return false; + } + const leftOp = usedStmt.getLeftOp(); + const rightOp = usedStmt.getRightOp(); + if (leftOp instanceof Local) { + if (leftOp !== castLocal) { + return false; + } + if (!(rightOp instanceof ArkNormalBinopExpr)) { + return false; + } + const op1 = rightOp.getOp1(); + const op2 = rightOp.getOp2(); + const operator = rightOp.getOperator(); + if (op1 !== castLocal) { + return false; + } + if (operator !== NormalBinaryOperator.Addition && operator !== NormalBinaryOperator.Subtraction) { + return false; + } + if (!(op2 instanceof NumberConstant) || !(op2.getType() instanceof NumberType) || op2.getValue() !== '1') { + return false; + } + selfAssignFlag = true; + } + if (leftOp instanceof ArkCastExpr) { + if (leftOp !== stmt.getRightOp()) { + return false; + } + if (rightOp !== castLocal) { + return false; + } + assignBackFlag = true; + } + } + return selfAssignFlag && assignBackFlag; + } + 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)) { + // 这里仅判断了cast op是否进行了instanceof判断,如果op是由op1赋值,op1进行了instanceof判断,此处不认为是做了有效检查,因为此赋值链可能很长且中途发生类型变化,极易判断错误 + const checkRes = this.checkTypeAssuranceInBasicBlock(block, castExpr); + if (checkRes === TypeAssuranceCondition.NotExist) { continue; } let checkedBB: Set = new Set(); let needCheckBB: number[] = []; checkedBB.add(block.getId()); const allSuccessors = block.getSuccessors(); - if (allSuccessors.length > 0 && positiveCheck) { + if (allSuccessors.length > 0 && checkRes === TypeAssuranceCondition.Positive) { needCheckBB.push(allSuccessors[0].getId()); } - if (allSuccessors.length > 1 && negativeCheck) { + if (allSuccessors.length > 1 && checkRes === TypeAssuranceCondition.Negative) { needCheckBB.push(allSuccessors[1].getId()); } while (needCheckBB.length > 0) { @@ -221,26 +302,7 @@ export class NoTSLikeAsCheck implements BaseChecker { 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 { + private checkTypeAssuranceInBasicBlock(bb: BasicBlock, castExpr: ArkCastExpr): TypeAssuranceCondition { for (const stmt of bb.getStmts()) { if (!(stmt instanceof ArkIfStmt)) { continue; @@ -248,108 +310,112 @@ export class NoTSLikeAsCheck implements BaseChecker { 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; - } + const operator = conditionExpr.getOperator(); + // 对于if (i instanceof A)这种条件语句,op1总是临时变量,op2总是false,操作符总是!= + if (!(op1 instanceof Local && op2 instanceof BooleanConstant && op2.getValue() === 'false' && operator === RelationalBinaryOperator.InEquality)) { + break; } + return this.checkTypeAssuranceWithLocal(op1, castExpr, stmt.getOriginPositionInfo(), true); } - return false; + return TypeAssuranceCondition.NotExist; } - private isCastExprWithTypeAssuranceNegative(bb: BasicBlock, castExpr: ArkCastExpr): boolean { - for (const stmt of bb.getStmts()) { - if (!(stmt instanceof ArkIfStmt)) { - continue; + private checkTypeAssuranceWithLocal(operand: Local, castExpr: ArkCastExpr, ifStmtPos: LineColPosition, shouldBe: boolean): TypeAssuranceCondition { + const declaringStmt = operand.getDeclaringStmt(); + if (declaringStmt === null) { + return TypeAssuranceCondition.NotExist; + } + // if语句中的所有条件遵从三地址码原则拆分成多个语句时,所有语句的位置信息是一致的,不一致时表示是条件语句之前的赋值或声明情况,不在本判断范围内 + const stmtPos = declaringStmt.getOriginPositionInfo(); + if (stmtPos.getLineNo() !== ifStmtPos.getLineNo() || stmtPos.getColNo() !== ifStmtPos.getColNo()) { + return TypeAssuranceCondition.NotExist; + } + if (!(declaringStmt instanceof ArkAssignStmt)) { + return TypeAssuranceCondition.NotExist; + } + const rightOp = declaringStmt.getRightOp(); + if (rightOp instanceof ArkInstanceOfExpr) { + if (this.isTypeAssuranceMatchCast(rightOp, castExpr)) { + if (shouldBe) { + return TypeAssuranceCondition.Positive; + } else { + return TypeAssuranceCondition.Negative; + } } - 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; + return TypeAssuranceCondition.NotExist; + } + if (rightOp instanceof ArkUnopExpr && rightOp.getOperator() === UnaryOperator.LogicalNot) { + const unaryOp = rightOp.getOp(); + if (unaryOp instanceof Local) { + return this.checkTypeAssuranceWithLocal(unaryOp, castExpr, ifStmtPos, !shouldBe); + } + return TypeAssuranceCondition.NotExist; + } + if (rightOp instanceof ArkNormalBinopExpr) { + const op1 = rightOp.getOp1(); + const op2 = rightOp.getOp2(); + const operator = rightOp.getOperator(); + // 这里仅判断&&和||两种逻辑运算符的场景,其他场景在包含类型守卫判断的条件语句中不常见,暂不考虑 + let res: TypeAssuranceCondition; + if (operator === NormalBinaryOperator.LogicalAnd) { + if (op1 instanceof Local) { + res = this.checkTypeAssuranceWithLocal(op1, castExpr, ifStmtPos, shouldBe); + if (res !== TypeAssuranceCondition.NotExist) { + return res; + } } + if (op2 instanceof Local) { + res = this.checkTypeAssuranceWithLocal(op2, castExpr, ifStmtPos, shouldBe); + if (res !== TypeAssuranceCondition.NotExist) { + return res; + } + } + return TypeAssuranceCondition.NotExist; } - if (op2 instanceof Local) { - const declareStmt = op2.getDeclaringStmt(); - if (declareStmt !== null && this.isStmtWithTypeAssuranceNegative(declareStmt, castExpr)) { - return true; + if (operator === NormalBinaryOperator.LogicalOr) { + // a or b,不论a或b里是类型守卫判断,均无法保证分支中的类型明确 + if (shouldBe) { + return TypeAssuranceCondition.NotExist; } } } - return false; + return TypeAssuranceCondition.NotExist; } - private isStmtWithTypeAssurancePositive(declareStmt: Stmt, castExpr: ArkCastExpr): boolean { - if (!(declareStmt instanceof ArkAssignStmt)) { - return false; - } - const rightOp = declareStmt.getRightOp(); - if (!(rightOp instanceof ArkInstanceOfExpr)) { - return false; - } + private isTypeAssuranceMatchCast(instanceOfExpr: ArkInstanceOfExpr, castExpr: ArkCastExpr): boolean { const castOp = castExpr.getOp(); const castType = castExpr.getType(); - const instanceofType = rightOp.getCheckType(); + const instanceofType = instanceOfExpr.getCheckType(); if (castType.getTypeString() !== instanceofType.getTypeString()) { return false; } - const instanceofOp = rightOp.getOp(); + const instanceofOp = instanceOfExpr.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; + private isStmtInBlock(stmt: Stmt, block: BasicBlock): boolean { + for (const s of block.getStmts()) { + if (s === stmt) { + return true; + } } - const instanceofOp = unaryOpRightOp.getOp(); - if (!(castOp instanceof Local && instanceofOp instanceof Local)) { - return false; + 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 castOp.getName() === instanceofOp.getName(); + return null; } - private checkFromStmt( - stmt: Stmt, - scene: Scene, - globalVarMap: Map, - checkAll: { value: boolean }, - visited: Set, - depth: number = 0 - ): Stmt | null { + private checkFromStmt(stmt: Stmt, globalVarMap: Map, checkAll: { value: boolean }, visited: Set, depth: number = 0): Stmt | null { if (depth > CALL_DEPTH_LIMIT) { checkAll.value = false; return null; @@ -363,9 +429,14 @@ export class NoTSLikeAsCheck implements BaseChecker { continue; } visited.add(currentStmt); - if (this.isWithInterfaceAnnotation(currentStmt, scene)) { + if (this.isWithInterfaceAnnotation(currentStmt)) { return currentStmt; } + + const fieldDeclareStmt = this.isCastOpFieldWithInterfaceType(currentStmt); + if (fieldDeclareStmt) { + return fieldDeclareStmt; + } const gv = this.checkIfCastOpIsGlobalVar(currentStmt); if (gv) { const globalDefs = globalVarMap.get(gv.getName()); @@ -392,7 +463,7 @@ export class NoTSLikeAsCheck implements BaseChecker { } const returnStmts = declaringMtd.getReturnStmt(); for (const stmt of returnStmts) { - const res = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited, depth + 1); + const res = this.checkFromStmt(stmt, globalVarMap, checkAll, visited, depth + 1); if (res !== null) { return res; } @@ -401,13 +472,11 @@ export class NoTSLikeAsCheck implements BaseChecker { const paramRef = this.isFromParameter(currentStmt); if (paramRef) { const paramIdx = paramRef.getIndex(); - const callsites = this.cg.getInvokeStmtByMethod( - currentStmt.getCfg().getDeclaringMethod().getSignature() - ); + 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); + const res = this.checkFromStmt(stmt, globalVarMap, checkAll, visited, depth + 1); if (res !== null) { return res; } @@ -418,6 +487,34 @@ export class NoTSLikeAsCheck implements BaseChecker { return null; } + private isCastOpFieldWithInterfaceType(stmt: Stmt): Stmt | undefined { + const obj = this.getCastOp(stmt); + if (obj === null || !(obj instanceof Local)) { + return undefined; + } + const declaringStmt = obj.getDeclaringStmt(); + if (declaringStmt === null || !(declaringStmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = declaringStmt.getRightOp(); + if (!(rightOp instanceof AbstractFieldRef)) { + return undefined; + } + const fieldDeclaring = rightOp.getFieldSignature().getDeclaringSignature(); + if (fieldDeclaring instanceof ClassSignature) { + const field = this.scene.getClass(fieldDeclaring)?.getField(rightOp.getFieldSignature()); + if (!field) { + return undefined; + } + const fieldInitializer = field.getInitializer(); + const lastStmt = fieldInitializer[fieldInitializer.length - 1]; + if (this.isWithInterfaceAnnotation(lastStmt)) { + return lastStmt; + } + } + return undefined; + } + private checkIfCastOpIsGlobalVar(stmt: Stmt): Local | undefined { const obj = this.getCastOp(stmt); if (obj instanceof Local && !obj.getDeclaringStmt()) { @@ -462,7 +559,7 @@ export class NoTSLikeAsCheck implements BaseChecker { } // 判断语句是否为赋值语句,且左值的类型注解为Interface,右值的类型与左值不一样 - private isWithInterfaceAnnotation(stmt: Stmt, scene: Scene): boolean { + private isWithInterfaceAnnotation(stmt: Stmt): boolean { if (!(stmt instanceof ArkAssignStmt)) { return false; } @@ -470,7 +567,7 @@ export class NoTSLikeAsCheck implements BaseChecker { if (!(leftOpType instanceof ClassType)) { return false; } - const leftOpTypeclass = scene.getClass(leftOpType.getClassSignature()); + const leftOpTypeclass = this.scene.getClass(leftOpType.getClassSignature()); if (leftOpTypeclass === null) { return false; } @@ -512,10 +609,20 @@ export class NoTSLikeAsCheck implements BaseChecker { return null; } const rightOp = stmt.getRightOp(); - if (!(rightOp instanceof ArkCastExpr)) { - return null; + if (rightOp instanceof ArkCastExpr) { + return rightOp; + } + if (rightOp instanceof ArkNormalBinopExpr) { + const op1 = rightOp.getOp1(); + const op2 = rightOp.getOp2(); + if (op1 instanceof ArkCastExpr) { + return op1; + } + if (op2 instanceof ArkCastExpr) { + return op2; + } } - return rightOp; + return null; } private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { @@ -532,15 +639,16 @@ export class NoTSLikeAsCheck implements BaseChecker { }); } - private addIssueReport(stmt: Stmt, operand: ArkCastExpr, relatedStmt?: Stmt): void { + private addIssueReport(stmt: Stmt, operand: ArkCastExpr, relatedStmt?: Stmt, incrementCase: boolean = false): void { const severity = this.rule.alert ?? this.metaData.severity; - const warnInfo = this.getLineAndColumn(stmt, operand); + const warnInfo = 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; + if (incrementCase) { + desc = 'Can not use neither increment nor decrement with cast expression ' + desc; + } else if (relatedStmt === undefined) { + desc = `Can not check when function call chain depth exceeds ${CALL_DEPTH_LIMIT}, please check it manually ` + desc; } else { const sinkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const relatedFile = relatedStmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); @@ -550,6 +658,7 @@ export class NoTSLikeAsCheck implements BaseChecker { desc = `${descPrefix} in file ${path.normalize(relatedFile.getName())}: ${relatedStmt.getOriginPositionInfo().getLineNo()} ` + desc; } } + let defects = new Defects( warnInfo.line, warnInfo.startCol, @@ -566,19 +675,4 @@ export class NoTSLikeAsCheck implements BaseChecker { ); 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/NumericSemanticCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..359b025482a1c6bec08b400631a038e9d7a773e0 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/NumericSemanticCheck.ts @@ -0,0 +1,2628 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + AbstractFieldRef, + AbstractInvokeExpr, + AbstractRef, + ArkAssignStmt, + ArkCastExpr, + ArkConditionExpr, + ArkField, + ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + ArkInvokeStmt, + ArkMethod, + ArkNormalBinopExpr, + ArkParameterRef, + ArkTypeOfExpr, + ArkUnopExpr, + ArrayType, + BooleanType, + CallGraph, + ClassSignature, + ClassType, + ClosureFieldRef, + CONSTRUCTOR_NAME, + DVFGBuilder, + FileSignature, + FullPosition, + GlobalRef, + INSTANCE_INIT_METHOD_NAME, + LexicalEnvType, + Local, + MethodSignature, + NAME_DELIMITER, + NamespaceSignature, + NormalBinaryOperator, + Scene, + STATIC_INIT_METHOD_NAME, + Stmt, + TEMP_LOCAL_PREFIX, + Type, + UnaryOperator, + UnionType, + UnknownType, + Value, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Defects, MatcherCallback, Rule, RuleFix, Utils } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, getLineAndColumn, GlobalCallGraphHelper } from './Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { NullConstant, NumberConstant, StringConstant, UndefinedConstant } from 'arkanalyzer/lib/core/base/Constant'; +import { + AliasType, + ArkArrayRef, + ArkClass, + ArkFile, + ArkReturnStmt, + AstTreeUtils, + EnumValueType, + NumberType, + ts, + TupleType, + UnclearReferenceType, +} from 'arkanalyzer'; +import { FixUtils } from '../../utils/common/FixUtils'; +import { Sdk } from 'arkanalyzer/lib/Config'; +import path from 'path'; +import { ModifierType } from 'arkanalyzer/lib/core/model/ArkBaseModel'; +import { WarnInfo } from '../../utils/common/Utils'; +import { SdkUtils } from '../../utils/common/SDKUtils'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { ArkAwaitExpr } from 'arkanalyzer/lib/core/base/Expr'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NumericSemanticCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +enum NumberCategory { + int = 'int', + long = 'long', + number = 'number', +} + +enum RuleCategory { + SDKIntType = 'sdk-api-num2int', + NumericLiteral = 'arkts-numeric-semantic', + ArrayIndex = 'arkts-array-index-expr-type', +} + +enum IssueReason { + OnlyUsedAsIntLong = 'only-used-as-int-or-long', + UsedWithOtherType = 'not-only-used-as-int-or-long', + CannotFindAll = 'cannot-find-all', + RelatedWithNonETS2 = 'related-with-non-ets2', + ActuallyIntConstant = 'actually-int-constant', + Other = 'other', +} + +interface IssueInfo { + issueReason: IssueReason; + numberCategory: NumberCategory; +} + +interface RuleOptions { + ets2Sdks?: Sdk[]; +} + +export class NumericSemanticCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private scene: Scene; + private ets2Sdks?: Sdk[]; + private ets2SdkScene?: Scene; + private cg: CallGraph; + private dvfg: DVFG; + private dvfgBuilder: DVFGBuilder; + private visited: Set = new Set(); + private callDepth = 0; + private classFieldRes: Map = new Map(); + private issuesMap: Map = new Map(); + private sourceFiles: Map = new Map(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.scene = scene; + + // 为ets2的SDK单独生成scene,用于sdk检查时进行匹配使用,单独scene可以避免与源码的scene进行干扰 + let ets2Sdks = (this.rule.option[0] as RuleOptions | undefined)?.ets2Sdks ?? SdkUtils.getEts2SdksWithSdkRelativePath(this.scene.getProjectSdkMap()); + if (ets2Sdks && ets2Sdks.length > 0) { + this.ets2Sdks = ets2Sdks; + this.ets2SdkScene = Utils.generateSceneForEts2SDK(ets2Sdks); + } + + 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.2进行检查,仅对要将arkts1.1迁移到arkts1.2的文件进行number转int的检查和自动修复 + if (arkFile.getLanguage() !== Language.ARKTS1_2) { + continue; + } + // 用于记录与issue相关的文件的tsc信息,避免每次新增issue时重复创建,提升性能。每次遍历新文件时清空map,节省内存。 + this.sourceFiles = new Map(); + const defaultMethod = arkFile.getDefaultClass().getDefaultArkMethod(); + if (defaultMethod) { + this.dvfgBuilder.buildForSingleMethod(defaultMethod); + } + for (let clazz of arkFile.getClasses()) { + this.processClass(clazz); + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + for (let clazz of namespace.getClasses()) { + this.processClass(clazz); + } + } + } + + this.issues = Array.from(this.issuesMap.values()); + }; + + public processClass(arkClass: ArkClass): void { + if (arkClass.getCategory() === ClassCategory.ENUM || arkClass.getCategory() === ClassCategory.TYPE_LITERAL) { + // Enum类型的class不需要处理,仅有statint函数,一定不涉及SDK调用,整型字面量不能进行浮点字面量的修改,也不涉及类型注解修改 + // TYPE_LITERAL类型的class不需要处理,仅作为type使用,该class内无方法,仅有field的定义,且field无初始化语句,仅设定类型 + return; + } + this.classFieldRes = new Map(); + // 查找全部method,包含constructor、%instInit,%statInit等 + for (let mtd of arkClass.getMethods(true)) { + this.processArkMethod(mtd); + } + } + + public processArkMethod(target: ArkMethod): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + // 场景1:需要检查的sdk调用语句,该stmt为sink点 + for (const stmt of stmts) { + try { + this.checkSdkArgsInStmt(stmt); + this.checkSdkReturnValueInStmt(stmt); + this.checkSdkFieldValueInStmt(stmt); + } catch (e) { + logger.error(`Error checking sdk called in stmt: ${stmt.toString()}, method: ${target.getSignature().toString()}, error: ${e}`); + } + } + + // 场景2:需要检查整型字面量或除法出现的stmt,该stmt为sink点。场景2在场景1之后执行,优先让SDK调用来决定变量的类型为int、long、number,剩余的场景2处理,避免issue之间的冲突 + if (target.isGenerated()) { + // statInit、instInit等方法不进行检查,不主动对类属性的类型进行检查,因为类属性的使用范围很广,很难找全,仅对涉及的1/2这种进行告警,自动修复为1.0/2.0 + try { + this.checkFieldInitializerWithIntLiteral(target); + } catch (e) { + logger.error(`Error checking init method with numeric literal, method: ${target.getSignature().toString()}, error: ${e}`); + } + } else { + for (const stmt of stmts) { + try { + this.checkStmtContainsNumericLiteral(stmt); + } catch (e) { + logger.error( + `Error checking stmt with numeric literal, stmt: ${stmt.toString()}, method: ${target.getSignature().toString()}, error: ${e}` + ); + } + } + } + + // 场景3:需要检查array的index,该stmt为sink点 + for (const stmt of stmts) { + try { + this.checkArrayIndexInStmt(stmt); + } catch (e) { + logger.error(`Error checking array index in stmt: ${stmt.toString()}, method: ${target.getSignature().toString()}, error: ${e}`); + } + } + } + + private checkSdkArgsInStmt(stmt: Stmt): void { + const intArgs = this.getSDKIntLongArgs(stmt); + if (intArgs === null || intArgs.size === 0) { + return; + } + + // res用于存放检查过程中所有找到的Local变量,记录这些变量是否均仅当做int使用,若是则可以设置成int类型,跨函数场景下可能包含其他method中的Local变量 + const res = new Map(); + this.callDepth = 0; + for (const [arg, category] of intArgs) { + const issueReason = this.checkValueOnlyUsedAsIntLong(stmt, arg, res, category); + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + this.addIssueReportForSDKArg(RuleCategory.SDKIntType, category, issueReason, true, stmt, arg); + } + } + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null && issueInfo.issueReason === IssueReason.OnlyUsedAsIntLong) { + this.addIssueReportForSDKArg( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + true, + declaringStmt, + local, + undefined, + stmt + ); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReportForSDKArg(RuleCategory.SDKIntType, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field, stmt); + } + }); + } + + private checkSdkReturnValueInStmt(stmt: Stmt): void { + if (!(stmt instanceof ArkAssignStmt)) { + return; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractInvokeExpr)) { + return; + } + const numberCategory = this.checkSDKReturnType(rightOp); + if (!numberCategory) { + return; + } + + const res = new Map(); + this.callDepth = 0; + const leftOp = stmt.getLeftOp(); + this.checkValueOnlyUsedAsIntLong(stmt, leftOp, res, numberCategory); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null) { + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + declaringStmt, + local, + undefined, + stmt + ); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + fieldInfo.numberCategory, + fieldInfo.issueReason, + undefined, + undefined, + field, + stmt + ); + } + }); + } + + private checkSdkFieldValueInStmt(stmt: Stmt): void { + if (!(stmt instanceof ArkAssignStmt)) { + return; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractFieldRef)) { + return; + } + const numberCategory = this.checkSDKFieldType(rightOp); + if (!numberCategory) { + return; + } + const res = new Map(); + this.callDepth = 0; + const leftOp = stmt.getLeftOp(); + if (!Utils.isNearlyNumberType(leftOp.getType())) { + return; + } + this.checkValueOnlyUsedAsIntLong(stmt, leftOp, res, numberCategory); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null) { + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + issueInfo.numberCategory, + issueInfo.issueReason, + declaringStmt, + local, + undefined, + stmt + ); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReportForSDKReturnOrField( + RuleCategory.SDKIntType, + fieldInfo.numberCategory, + fieldInfo.issueReason, + undefined, + undefined, + field, + stmt + ); + } + }); + } + + private checkFieldInitializerWithIntLiteral(method: ArkMethod): void { + // 仅对类属性的初始化语句进行检查,判断其中是否有涉及整型字面量的赋值或涉及除法运算 + if (method.getName() !== STATIC_INIT_METHOD_NAME && method.getName() !== INSTANCE_INIT_METHOD_NAME) { + return; + } + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + return; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof AbstractFieldRef) || !Utils.isNearlyNumberType(leftOp.getType())) { + continue; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && rightOp.getName().startsWith(TEMP_LOCAL_PREFIX)) { + // 类属性的初始化语句使用Local赋值,且Local为临时变量,则可能涉及除法运算 + // 整型字面量参与除法运算的告警和自动修复信息在检查过程中就已生成,无需在此处额外生成 + this.checkValueOnlyUsedAsIntLong(stmt, rightOp, new Map(), NumberCategory.int); + this.checkFieldRef( + leftOp, + stmt.getCfg().getDeclaringMethod().getDeclaringArkClass().getSignature(), + NumberCategory.int, + new Map() + ); + } + if (rightOp instanceof NumberConstant && !this.isNumberConstantActuallyFloat(rightOp)) { + this.checkFieldRef( + leftOp, + stmt.getCfg().getDeclaringMethod().getDeclaringArkClass().getSignature(), + NumberCategory.int, + new Map() + ); + } + } + this.classFieldRes.forEach((fieldInfo, field) => { + this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + }); + } + + private checkStmtContainsNumericLiteral(stmt: Stmt): void { + const res = new Map(); + this.callDepth = 0; + + // 场景1:先判断是否涉及除法运算 + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (leftOp instanceof Local && rightOp instanceof ArkNormalBinopExpr && rightOp.getOperator() === NormalBinaryOperator.Division) { + if (this.isLocalAssigned2Array(leftOp)) { + // local为临时变量,用于给数组元素赋值的场景,不在本规则的实现范围内,归另一处的规则开发实现 + return; + } + if (!Utils.isNearlyNumberType(leftOp.getType())) { + // 对左值进行检查决定是否对其添加类型注解int或number,如果不是number相关类型则无需继续进行检查 + return; + } + this.checkValueOnlyUsedAsIntLong(stmt, stmt.getLeftOp(), res, NumberCategory.number); + // 因为如果let a10 = a1/2; a10 = a2/3;第1句能判断a10为number,则不会继续后面的检查,所以需要额外对除法表达式的op1和op2进行number类型注解的补充 + this.isAbstractExprOnlyUsedAsIntLong(stmt, rightOp, res, NumberCategory.number); + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt === null) { + return; + } + // 无论local的判定结果是什么,均需要进行自动修复类型注解为int或者number + this.addIssueReport(RuleCategory.NumericLiteral, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local); + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + } + }); + return; + } + } + + // 场景2:非除法运算场景,处理其余涉及整型字面量的场景 + if (!this.isStmtContainsIntLiteral(stmt)) { + return; + } + // 这些类型的语句中的整型字面量无需进一步进行分析,直接返回 + if (stmt instanceof ArkInvokeStmt || stmt instanceof ArkReturnStmt || stmt instanceof ArkIfStmt) { + return; + } + // 除赋值语句外的其余语句类型理论上不应该出现,如果出现日志报错,需要分析日志进行场景补充 + if (!(stmt instanceof ArkAssignStmt)) { + logger.error(`Need to handle new type of stmt: ${stmt.toString()}, method: ${stmt.getCfg().getDeclaringMethod().getSignature().toString()}`); + return; + } + + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (!(leftOp instanceof Local)) { + if (leftOp instanceof ArkArrayRef) { + // 对数组元素的赋值中的整型字面量的检查,不在本规则的实现范围内,归另一处的规则开发实现 + return; + } + if (leftOp instanceof AbstractFieldRef) { + // 对类属性直接使用整型字面量进行赋值,int可以赋值给number,不修改属性的类型,保持number + return; + } + logger.error(`Need to handle leftOp type in assign stmt with non Local type, stmt: ${stmt.toString()}`); + return; + } + if (this.isLocalAssigned2Array(leftOp)) { + // local为临时变量,用于给数组元素赋值的场景,不在本规则的实现范围内,归另一处的规则开发实现 + return; + } + if (!Utils.isNearlyNumberType(leftOp.getType())) { + // 对左值进行检查决定是否对其添加类型注解int或number,如果不是number相关类型则无需继续进行检查 + return; + } + + if (rightOp instanceof NumberConstant && !this.isNumberConstantActuallyFloat(rightOp)) { + // 整型字面量直接赋值给左值,判断左值在生命周期内是否仅作为int使用,并且判断左值是否继续赋值给其他变量,其他变量是否也可以定义为int + this.checkAllLocalsAroundLocal(stmt, leftOp, res, NumberCategory.int); + } else if (rightOp instanceof AbstractExpr) { + // 整型字面量作为表达式的一部分,在赋值语句右边出现 + this.checkAbstractExprWithIntLiteral(stmt, leftOp, rightOp, res, NumberCategory.int); + } else if (rightOp instanceof ArkArrayRef) { + // 整型字面量作为数组访问的index,无需做任何处理,直接返回 + return; + } else { + logger.error(`Need to handle new rightOp type, stmt: ${stmt.toString()}, method: ${stmt.getCfg().getDeclaringMethod().getSignature().toString()}`); + return; + } + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt === null) { + return; + } + // 无论local的判定结果是什么,均需要进行自动修复类型注解为int或者number + this.addIssueReport(RuleCategory.NumericLiteral, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local); + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong || fieldInfo.issueReason === IssueReason.UsedWithOtherType) { + // 如果能明确判断出field是int或非int,则添加类型注解int或number,其他找不全的场景不变 + this.addIssueReport(RuleCategory.NumericLiteral, fieldInfo.numberCategory, fieldInfo.issueReason, true, undefined, undefined, field); + } + }); + } + + private checkArrayIndexInStmt(stmt: Stmt): void { + const res = new Map(); + this.callDepth = 0; + const index = this.getIndexValue(stmt); + if (index === null) { + return; + } + // 对于index为1.0、2.0这种number constant,需要告警并自动修复成1、2 + if (index instanceof NumberConstant && this.isFloatActuallyInt(index)) { + this.addIssueReport(RuleCategory.ArrayIndex, NumberCategory.number, IssueReason.ActuallyIntConstant, true, stmt, index); + return; + } + const issueReason = this.checkValueOnlyUsedAsIntLong(stmt, index, res, NumberCategory.int); + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + // 若index原先非int,则获取的数组元素应该是undefined,不可以对其进行强转int,否则对原始代码的语义有修改 + this.addIssueReport(RuleCategory.ArrayIndex, NumberCategory.number, issueReason, false, stmt, index); + } + res.forEach((issueInfo, local) => { + if (this.shouldIgnoreLocal(local)) { + return; + } + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt !== null) { + this.addIssueReport(RuleCategory.ArrayIndex, issueInfo.numberCategory, issueInfo.issueReason, true, declaringStmt, local); + } + }); + this.classFieldRes.forEach((fieldInfo, field) => { + if (fieldInfo.issueReason === IssueReason.OnlyUsedAsIntLong) { + // 如果能明确判断出field是int,则添加类型注解int,其他找不全的场景不变 + this.addIssueReport(RuleCategory.ArrayIndex, NumberCategory.int, fieldInfo.issueReason, true, undefined, undefined, field); + } + }); + } + + private getFieldRefActualArrayRef(stmt: Stmt): ArkInstanceFieldRef | null { + const fieldRef = stmt.getFieldRef(); + if (fieldRef === undefined || !(fieldRef instanceof ArkInstanceFieldRef)) { + return null; + } + const fieldBaseType = fieldRef.getBase().getType(); + if (!(fieldBaseType instanceof UnionType)) { + return null; + } + let containArray = false; + for (const t of fieldBaseType.getTypes()) { + if (t instanceof ArrayType) { + containArray = true; + break; + } + } + if (!containArray) { + return null; + } + const fieldName = fieldRef.getFieldName(); + if (fieldName === 'length') { + return null; + } + return fieldRef; + } + + private getActualIndexPosInStmt(stmt: Stmt): FullPosition { + // 处理array定义时为unionType,例如string[] | undefined,array的index访问语句被错误表示成ArkInstanceFieldRef的场景 + // 由于IR表示在此处的能力限制,此处判断unionType中包含arrayType,且fieldRef的名字非length,取第4个操作数的位置为实际index的位置 + const fieldRef = this.getFieldRefActualArrayRef(stmt); + if (!fieldRef) { + return FullPosition.DEFAULT; + } + const positions = stmt.getOperandOriginalPositions(); + if (!positions || positions.length !== 4) { + return FullPosition.DEFAULT; + } + return positions[3]; + } + + private getIndexValue(stmt: Stmt): Value | null { + // 处理stmt的uses中的array的index访问语句 + const arrayRef = stmt.getArrayRef(); + if (arrayRef !== undefined) { + return arrayRef.getIndex(); + } + + // 处理array的index访问出现在赋值语句左边的情况 + if (stmt.getDef() instanceof ArkArrayRef) { + return (stmt.getDef() as ArkArrayRef).getIndex(); + } + + // 处理array定义时为unionType,例如string[] | undefined,array的index访问语句被错误表示成ArkInstanceFieldRef的场景 + // 由于IR表示在此处的能力限制,此处判断unionType中包含arrayType,且fieldRef的名字非length,且在local或global中能找到同名的情况 + const methodBody = stmt.getCfg().getDeclaringMethod().getBody(); + if (methodBody === undefined) { + return null; + } + + const fieldRef = this.getFieldRefActualArrayRef(stmt); + if (!fieldRef) { + return null; + } + let index = methodBody.getLocals().get(fieldRef.getFieldName()); + if (index !== undefined) { + return index; + } + const global = methodBody.getUsedGlobals()?.get(fieldRef.getFieldName()); + if (global === undefined || !(global instanceof GlobalRef)) { + return null; + } + return global.getRef(); + } + + private isLocalAssigned2Array(local: Local): boolean { + if (!local.getName().startsWith(TEMP_LOCAL_PREFIX)) { + return false; + } + const usedStmts = local.getUsedStmts(); + for (const stmt of usedStmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (leftOp instanceof ArkArrayRef) { + // 临时变量赋值给数组元素,不在此规则中检查,例如a[0] = 2/3 + return true; + } + if (leftOp instanceof ArkInstanceFieldRef) { + const base = leftOp.getBase(); + if (base.getType() instanceof TupleType) { + // 临时变量赋值给元组元素,不在此规则中检查,例如a[0] = 2/3 + return true; + } + } + } + return false; + } + + private shouldIgnoreLocal(local: Local): boolean { + // 临时变量没有源码的定义语句,无需自动修复类型注解 + if (local.getName().startsWith(TEMP_LOCAL_PREFIX)) { + return true; + } + const declaringStmt = local.getDeclaringStmt(); + // 闭包变量的定义在外层函数,在外层函数处修复,无需在此处修复 + if (declaringStmt instanceof ArkAssignStmt && declaringStmt.getRightOp() instanceof ClosureFieldRef) { + return true; + } + + // 对于for (const i of arr)这样的写法,不能为i添加类型注解 + if (declaringStmt instanceof ArkAssignStmt) { + const rightOp = declaringStmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return false; + } + const castOp = rightOp.getOp(); + if (!(castOp instanceof Local)) { + return false; + } + const castOpDeclaring = castOp.getDeclaringStmt(); + if (!(castOpDeclaring instanceof ArkAssignStmt)) { + return false; + } + const castOpRight = castOpDeclaring.getRightOp(); + if (!(castOpRight instanceof ArkInstanceFieldRef)) { + return false; + } + const fieldSig = castOpRight.getFieldSignature(); + if (fieldSig.getFieldName() === 'value') { + const declaringSig = fieldSig.getDeclaringSignature(); + if (declaringSig instanceof ClassSignature && declaringSig.getClassName() === 'IteratorYieldResult') { + return true; + } + } + } + return false; + } + + private isStmtContainsIntLiteral(stmt: Stmt): boolean { + const uses = stmt.getUses(); + for (const use of uses) { + if (use instanceof NumberConstant && !this.isNumberConstantActuallyFloat(use)) { + return true; + } + } + return false; + } + + private checkAllLocalsAroundLocal(stmt: Stmt, local: Local, hasChecked: Map, numberCategory: NumberCategory): void { + const issueReason = this.isLocalOnlyUsedAsIntLong(stmt, local, hasChecked, NumberCategory.int); + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + return; + } + // res中是所有赋值给local的值传递链上的所有Local的结果,还需要查找所有由local进行赋值的链上的所有Local的结果 + local.getUsedStmts().forEach(s => { + if (s instanceof ArkAssignStmt && s.getRightOp() instanceof Local && s.getRightOp() === local) { + const leftOp = s.getLeftOp(); + if (leftOp instanceof Local) { + if (hasChecked.has(leftOp)) { + // 对于a = a语句,此处必须判断,否则会死循环 + return; + } + this.checkAllLocalsAroundLocal(s, leftOp, hasChecked, numberCategory); + } + } + }); + } + + private checkAbstractExprWithIntLiteral( + stmt: Stmt, + leftOp: Local, + rightOp: AbstractExpr, + hasChecked: Map, + numberCategory: NumberCategory + ): void { + if (rightOp instanceof AbstractInvokeExpr || rightOp instanceof ArkAwaitExpr) { + // 整型字面量作为函数调用的入参,不继续分析,后续如果有需要可以进一步对调用的函数进行检查,是否能将入参改为int + return; + } + if (rightOp instanceof ArkConditionExpr || rightOp instanceof ArkCastExpr || rightOp instanceof ArkTypeOfExpr) { + // 整型字面量参与这些表达式的运算,不是直接给number变量赋值,无需继续分析 + return; + } + + const declaringStmt = leftOp.getDeclaringStmt(); + if (declaringStmt === null) { + return; + } + + if (rightOp instanceof ArkUnopExpr) { + // 整型字面量参与取反一元操作符的运算,得到左值是int还是number,与右边有关 + const operator = rightOp.getOperator(); + if (operator === UnaryOperator.Neg) { + this.checkAllLocalsAroundLocal(declaringStmt, leftOp, hasChecked, numberCategory); + } + return; + } + if (rightOp instanceof ArkNormalBinopExpr) { + const operator = rightOp.getOperator(); + + if (operator === NormalBinaryOperator.LogicalAnd || operator === NormalBinaryOperator.LogicalOr) { + // 整型字面量参与||、&&运算,不会影响左值的类型,不处理,直接退出 + return; + } + + const op1 = rightOp.getOp1(); + const op2 = rightOp.getOp2(); + + if (operator === NormalBinaryOperator.Division) { + this.checkAllLocalsAroundLocal(declaringStmt, leftOp, hasChecked, numberCategory); + return; + } + if ( + operator === NormalBinaryOperator.Addition || + operator === NormalBinaryOperator.Subtraction || + operator === NormalBinaryOperator.Multiplication || + operator === NormalBinaryOperator.Exponentiation || + operator === NormalBinaryOperator.NullishCoalescing + ) { + // 整型字面量参与+、-、*、**、??二元运算,左值的类型取决于另外一个操作数的类型,若其为int则左值可以为int,若其为number则左值为number + const op1Res = this.checkValueOnlyUsedAsIntLong(stmt, op1, hasChecked, numberCategory); + const op2Res = this.checkValueOnlyUsedAsIntLong(stmt, op2, hasChecked, numberCategory); + if (op1Res === IssueReason.OnlyUsedAsIntLong && op2Res === IssueReason.OnlyUsedAsIntLong) { + this.checkAllLocalsAroundLocal(declaringStmt, leftOp, hasChecked, numberCategory); + return; + } + hasChecked.set(leftOp, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); + return; + } + if ( + operator === NormalBinaryOperator.BitwiseAnd || + operator === NormalBinaryOperator.BitwiseOr || + operator === NormalBinaryOperator.BitwiseXor || + operator === NormalBinaryOperator.LeftShift || + operator === NormalBinaryOperator.RightShift || + operator === NormalBinaryOperator.UnsignedRightShift || + operator === NormalBinaryOperator.Remainder + ) { + // 位运算与取余运算,左边一定是整型,与右边是否为整型字面量无关,与1.1,1.2也无关,无需处理 + return; + } + logger.error(`Need to handle new type of binary operator: ${operator}`); + return; + } + logger.error(`Need to handle new type of expr: ${rightOp.toString()}`); + return; + } + + // 语句为sdk的调用且形参有int或long类型,找出所有int类型形参的实参 + private getSDKIntLongArgs(stmt: Stmt): Map | null { + let invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr === undefined) { + return null; + } + const callMethod = this.scene.getMethod(invokeExpr.getMethodSignature()); + if (callMethod === null || !SdkUtils.isMethodFromSdk(callMethod)) { + return null; + } + + const args = invokeExpr.getArgs(); + + // 根据找到的对应arkts1.1中的SDK接口匹配到对应在arkts1.2中的SDK接口 + const ets2SdkSignature = this.getEts2SdkSignatureWithEts1Method(callMethod, args, true); + if (ets2SdkSignature === null) { + return null; + } + const params = ets2SdkSignature.getMethodSubSignature().getParameters(); + if (params.length < args.length) { + return null; + } + const res: Map = new Map(); + args.forEach((arg, index) => { + if (this.isIntType(params[index].getType()) && !this.isIntType(arg.getType())) { + res.set(arg, NumberCategory.int); + } else if (this.isLongType(params[index].getType()) && !this.isLongType(arg.getType())) { + res.set(arg, NumberCategory.long); + } + }); + if (res.size === 0) { + return null; + } + return res; + } + + private checkSDKReturnType(invokeExpr: AbstractInvokeExpr): NumberCategory | null { + const callMethod = this.scene.getMethod(invokeExpr.getMethodSignature()); + if (callMethod === null || !SdkUtils.isMethodFromSdk(callMethod)) { + return null; + } + const args = invokeExpr.getArgs(); + + // 根据找到的对应arkts1.1中的SDK接口匹配到对应在arkts1.2中的SDK接口 + const ets2SdkSignature = this.getEts2SdkSignatureWithEts1Method(callMethod, args, false); + if (ets2SdkSignature === null) { + return null; + } + const returnType = ets2SdkSignature.getType(); + if (this.isLongType(returnType)) { + return NumberCategory.long; + } + if (this.isIntType(returnType)) { + return NumberCategory.int; + } + return null; + } + + private checkSDKFieldType(fieldRef: AbstractFieldRef): NumberCategory | null { + if (!SdkUtils.isFieldFromSdk(fieldRef) || !Utils.isNearlyNumberType(fieldRef.getType())) { + return null; + } + const ets1SdkFileSig = fieldRef.getFieldSignature().getDeclaringSignature().getDeclaringFileSignature(); + const ets2SdkFileSig = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName().replace('.d.ts', '.d.ets')); + const ets2SdkFileSigBak = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName()); + const ets2SdkFile = this.ets2SdkScene?.getFile(ets2SdkFileSig) ?? this.ets2SdkScene?.getFile(ets2SdkFileSigBak); + if (!ets2SdkFile) { + return null; + } + let ets2Field = SdkUtils.getSdkField(ets2SdkFile, fieldRef); + if (!ets2Field) { + return null; + } + if (this.isIntType(ets2Field.getType())) { + return NumberCategory.int; + } + if (this.isLongType(ets2Field.getType())) { + return NumberCategory.long; + } + return null; + } + + private matchEts1NumberEts2IntLongReturnSig(ets2Sigs: MethodSignature[], ets1Sig: MethodSignature): MethodSignature | null { + const ets1Params = ets1Sig.getMethodSubSignature().getParameters(); + for (const ets2Sig of ets2Sigs) { + let allParamMatched = true; + const ets2Params = ets2Sig.getMethodSubSignature().getParameters(); + if (ets2Params.length !== ets1Params.length) { + continue; + } + for (let i = 0; i < ets1Params.length; i++) { + const ets2ParamType = ets2Params[i].getType(); + const ets1ParamType = ets1Params[i].getType(); + if ( + ets2ParamType === ets1ParamType || + (ets1ParamType instanceof NumberType && (this.isIntType(ets2ParamType) || this.isLongType(ets2ParamType))) + ) { + continue; + } + allParamMatched = false; + break; + } + if (allParamMatched) { + const returnType = ets2Sig.getType(); + if (this.isLongType(returnType) || this.isIntType(returnType)) { + return ets2Sig; + } + } + } + return null; + } + + private matchEts1NumberEts2IntLongMethodSig(ets2Sigs: MethodSignature[], ets1Sig: MethodSignature): MethodSignature | null { + let intSDKMatched: MethodSignature | null = null; + const ets1Params = ets1Sig.getMethodSubSignature().getParameters(); + for (const ets2Sig of ets2Sigs) { + let isInt = false; + let isLong = false; + const ets2Params = ets2Sig.getMethodSubSignature().getParameters(); + if (ets2Params.length !== ets1Params.length) { + continue; + } + for (let i = 0; i < ets1Params.length; i++) { + const ets2ParamType = ets2Params[i].getType(); + const ets1ParamType = ets1Params[i].getType(); + if (ets2ParamType === ets1ParamType) { + continue; + } + if (this.isIntType(ets2ParamType) && ets1ParamType instanceof NumberType) { + isInt = true; + continue; + } + if (this.isLongType(ets2ParamType) && ets1ParamType instanceof NumberType) { + isLong = true; + continue; + } + isInt = false; + isLong = false; + } + if (isLong) { + return ets2Sig; + } + if (isInt) { + intSDKMatched = ets2Sig; + } + } + return intSDKMatched; + } + + // checkArg = true is for checking SDK arg with int or long; otherwise is for checking SDK return with int or long + private getEts2SdkSignatureWithEts1Method(ets1SDK: ArkMethod, args: Value[], checkArg: boolean, exactMatch: boolean = true): MethodSignature | null { + const ets2Sdks = this.ets2Sdks; + if (ets2Sdks === undefined || ets2Sdks.length === 0) { + return null; + } + + const ets1SigMatched = SdkUtils.getSdkMatchedSignature(ets1SDK, args); + if (ets1SigMatched === null) { + return null; + } + + const ets1SdkFileSig = ets1SDK.getDeclaringArkFile().getFileSignature(); + const ets2SdkFileSig = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName().replace('.d.ts', '.d.ets')); + const ets2SdkFileSigBak = new FileSignature(ets1SdkFileSig.getProjectName(), ets1SdkFileSig.getFileName()); + const ets2SdkFile = this.ets2SdkScene?.getFile(ets2SdkFileSig) ?? this.ets2SdkScene?.getFile(ets2SdkFileSigBak); + if (!ets2SdkFile) { + return null; + } + const ets2SdkMethod = this.getEts2SdkWithEts1SdkInfo(ets2SdkFile, ets1SDK); + if (ets2SdkMethod === null) { + return null; + } + const declareSigs = ets2SdkMethod.getDeclareSignatures(); + if (declareSigs === null) { + return null; + } + if (!exactMatch && declareSigs.length === 1) { + return declareSigs[0]; + } + if (checkArg) { + return this.matchEts1NumberEts2IntLongMethodSig(declareSigs, ets1SigMatched); + } + return this.matchEts1NumberEts2IntLongReturnSig(declareSigs, ets1SigMatched); + } + + private getEts2SdkWithEts1SdkInfo(ets2File: ArkFile, ets1SDK: ArkMethod): ArkMethod | null { + const ets1Class = ets1SDK.getDeclaringArkClass(); + const ets1Namespace = ets1Class.getDeclaringArkNamespace(); + if (ets1Namespace === undefined) { + return ets2File.getClassWithName(ets1Class.getName())?.getMethodWithName(ets1SDK.getName()) ?? null; + } + return ets2File.getNamespaceWithName(ets1Namespace.getName())?.getClassWithName(ets1Class.getName())?.getMethodWithName(ets1SDK.getName()) ?? null; + } + + // 判断类型是否为int,当前ArkAnalyzer对于int的表示应该是name为int的AliasType或UnclearReferenceType + private isIntType(checkType: Type): boolean { + if (checkType instanceof AliasType || checkType instanceof UnclearReferenceType) { + if (checkType.getName() === NumberCategory.int) { + return true; + } + } + // 函数返回值的Promise其实也是int类型 + if (checkType instanceof UnclearReferenceType && checkType.getName() === 'Promise') { + const gTypes = checkType.getGenericTypes(); + for (const gType of gTypes) { + if (this.isIntType(gType)) { + return true; + } + } + } + if (checkType instanceof ClassType && checkType.getClassSignature().getClassName() === 'Promise') { + const gTypes = checkType.getRealGenericTypes(); + if (gTypes === undefined) { + return false; + } + for (const gType of gTypes) { + if (this.isIntType(gType)) { + return true; + } + } + } + return false; + } + + // 判断类型是否为ilong,当前ArkAnalyzer对于long的表示应该是name为long的AliasType或UnclearReferenceType + private isLongType(checkType: Type): boolean { + if (checkType instanceof AliasType || checkType instanceof UnclearReferenceType) { + if (checkType.getName() === NumberCategory.long) { + return true; + } + // 函数返回值的Promise其实也是long类型 + if (checkType instanceof UnclearReferenceType && checkType.getName() === 'Promise') { + const gTypes = checkType.getGenericTypes(); + for (const gType of gTypes) { + if (this.isLongType(gType)) { + return true; + } + } + } + if (checkType instanceof ClassType && checkType.getClassSignature().getClassName() === 'Promise') { + const gTypes = checkType.getRealGenericTypes(); + if (gTypes === undefined) { + return false; + } + for (const gType of gTypes) { + if (this.isLongType(gType)) { + return true; + } + } + } + } + return false; + } + + // 此处value作为函数入参、数组下标、a/b,因为三地址码原则的限制,只可能是Local和NumberConstant类型,其他value的类型均不可能存在 + private checkValueOnlyUsedAsIntLong(stmt: Stmt, value: Value, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + if (stmt.getCfg().getDeclaringMethod().getLanguage() !== Language.ARKTS1_2) { + return IssueReason.RelatedWithNonETS2; + } + if (value instanceof NumberConstant) { + if (this.isNumberConstantActuallyFloat(value)) { + return IssueReason.UsedWithOtherType; + } + return IssueReason.OnlyUsedAsIntLong; + } + if (value instanceof UndefinedConstant || value instanceof NullConstant) { + // 对于用null或undefined赋值的场景,认为未进行初始化,还需其他赋值语句进行检查 + return IssueReason.OnlyUsedAsIntLong; + } + if (value instanceof StringConstant) { + // 存在将‘100%’,‘auto’等赋值给numberType的情况,可能是ArkAnalyzer对左值的推导有错误,左值应该是联合类型 + return IssueReason.UsedWithOtherType; + } + if (value instanceof Local) { + return this.isLocalOnlyUsedAsIntLong(stmt, value, hasChecked, numberCategory); + } + if (value instanceof AbstractExpr) { + return this.isAbstractExprOnlyUsedAsIntLong(stmt, value, hasChecked, numberCategory); + } + if (value instanceof AbstractRef) { + return this.isAbstractRefOnlyUsedAsIntLong(stmt, value, hasChecked, numberCategory); + } + logger.error(`Need to handle new value type: ${value.getType().getTypeString()}`); + return IssueReason.Other; + } + + private isNumberConstantActuallyFloat(constant: NumberConstant): boolean { + const valueStr = constant.getValue(); + if (valueStr.includes('.') && !valueStr.includes('e')) { + // 数字字面量非科学计数的写法,并且有小数点,则一定是浮点数,1.0也认为是float + return true; + } + const num = Number(constant.getValue()); + if (isNaN(num)) { + // 超大数字字面量转换后是NaN,按照number处理 + return true; + } + return !Number.isInteger(num); + } + + // 判断number constant是否为1.0、2.0这种可以转成1、2的整型形式 + private isFloatActuallyInt(constant: NumberConstant): boolean { + const parts = constant.getValue().split('.'); + if (parts.length !== 2) { + return false; + } + return /^0+$/.test(parts[1]); + } + + // 根据local的类型初步判断结果 + // 有些场景直接返回检查结果,不再继续检查,例如:类型为枚举、未知类型、与number无关的复杂类型等 + // 有些场景需要继续根据local的使用进行判断,例如:与number有关的类型等 + private checkResWithLocalType(local: Local, stmt: Stmt): IssueReason | null { + const localType = local.getType(); + if (!Utils.isNearlyNumberType(localType) && !(localType instanceof BooleanType)) { + // 对于联合类型仅包含number和null、undefined,可以认为是OK的,需要进一步根据local的使用情况进行判断 + // 对于return a || b, arkanalyzer会认为return op是boolean类型,其实是a的类型或b的类型,此处应该是number,需要正常继续解析表达式a || b + if (localType instanceof UnknownType || localType instanceof UnclearReferenceType) { + // 类型推导失败为unknownType或UnclearReferenceType + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkArrayRef && (stmt.getRightOp() as ArkArrayRef).getIndex() === local) { + // class field初始化为函数指针,导致匿名函数中使用到的闭包变量未识别,其类型为unknownType,需要继续进行查找 + return null; + } + return IssueReason.CannotFindAll; + } + if (localType instanceof EnumValueType) { + // local是枚举类型的值,无法改变枚举类型的定义,当做number使用 + return IssueReason.UsedWithOtherType; + } + // 剩余情况有aliasType、classType、函数指针、genericType等复杂场景,不再继续判断,直接返回UsedWithOtherType + logger.trace(`Local type is not number, local: ${local.getName()}, local type: ${local.getType().getTypeString()}`); + return IssueReason.UsedWithOtherType; + } + return null; + } + + private isLocalOnlyUsedAsIntLong(stmt: Stmt, local: Local, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + const currentInfo = hasChecked.get(local); + // hasChecked map中已有此local,若原先为int,现在为long则使用long替换,其余情况不改动,直接返回,避免死循环 + if (currentInfo) { + if (currentInfo.numberCategory === NumberCategory.int && numberCategory === NumberCategory.long) { + hasChecked.set(local, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: NumberCategory.long }); + } + return IssueReason.OnlyUsedAsIntLong; + } + // 在之前的语句检测中已查找过此local并生成相应的issue,直接根据issue的内容返回结果,如果issue中是int,检查的是long,则结果为long + const currentIssue = this.getLocalIssueFromIssueList(local, stmt); + if (currentIssue && currentIssue.fix instanceof RuleFix) { + const issueReason = this.getIssueReasonFromDefectInfo(currentIssue.defect); + const issueCategory = this.getNumberCategoryFromFixInfo(currentIssue.fix as RuleFix); + if (issueReason !== null && issueCategory !== null) { + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + hasChecked.set(local, { issueReason: issueReason, numberCategory: numberCategory }); + return issueReason; + } + if (numberCategory === NumberCategory.long) { + hasChecked.set(local, { issueReason: issueReason, numberCategory: numberCategory }); + } else { + hasChecked.set(local, { issueReason: issueReason, numberCategory: issueCategory }); + } + return issueReason; + } + } + + if (stmt.getCfg().getDeclaringMethod().getLanguage() !== Language.ARKTS1_2) { + hasChecked.set(local, { issueReason: IssueReason.RelatedWithNonETS2, numberCategory: NumberCategory.number }); + return IssueReason.RelatedWithNonETS2; + } + + // 先将value加入map中,默认设置成false,避免后续递归查找阶段出现死循环,最后再根据查找结果绝对是否重新设置成true + hasChecked.set(local, { issueReason: IssueReason.Other, numberCategory: NumberCategory.number }); + + const resWithLocalType = this.checkResWithLocalType(local, stmt); + if (resWithLocalType) { + if (resWithLocalType === IssueReason.OnlyUsedAsIntLong) { + hasChecked.set(local, { issueReason: resWithLocalType, numberCategory: numberCategory }); + } else { + hasChecked.set(local, { issueReason: resWithLocalType, numberCategory: NumberCategory.number }); + } + return resWithLocalType; + } + + let checkStmts: Stmt[] = []; + const declaringStmt = local.getDeclaringStmt(); + if (declaringStmt === null) { + // 无定义语句的local可能来自于全局变量或import变量,需要根据import信息查找其原始local + // 也可能是内层匿名类中使用到的外层函数中的变量,在内存类属性初始化时无定义语句 + const declaringMethod = stmt.getCfg().getDeclaringMethod(); + const newLocal = + this.getLocalFromOuterMethod(local, declaringMethod) ?? + this.getLocalFromGlobal(local, declaringMethod) ?? + this.getLocalFromImportInfo(local, declaringMethod); + if (newLocal === null) { + // local非来自于import,确实是缺少定义语句,或者是从非1.2文件import,直接返回false,因为就算是能确认local仅当做int使用,也找不到定义语句去修改类型注解为int,所以后续检查都没有意义 + logger.error(`Missing declaring stmt, local: ${local.getName()}`); + return hasChecked.get(local)!.issueReason; + } + const declaringStmt = newLocal.getDeclaringStmt(); + if (declaringStmt === null) { + // local变量未找到定义语句,直接返回false,因为就算是能确认local仅当做int使用,也找不到定义语句去修改类型注解为int,所以后续检查都没有意义 + logger.error(`Missing declaring stmt, local: ${local.getName()}`); + hasChecked.set(local, { issueReason: IssueReason.CannotFindAll, numberCategory: NumberCategory.number }); + return IssueReason.CannotFindAll; + } + hasChecked.delete(local); + return this.isLocalOnlyUsedAsIntLong(declaringStmt, newLocal, hasChecked, numberCategory); + } + // declaringStmt存在,但是是export let a定义的全局变量并对外export,也认为是number,不作为int使用,因为其使用范围可能很广,无法找全 + const declaringMethod = declaringStmt.getCfg().getDeclaringMethod(); + if (declaringMethod.isDefaultArkMethod()) { + const exportInfo = declaringMethod.getDeclaringArkFile().getExportInfoBy(local.getName()); + if (exportInfo !== undefined) { + const arkExport = exportInfo.getArkExport(); + if (arkExport instanceof Local) { + hasChecked.set(local, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); + return IssueReason.UsedWithOtherType; + } + } + } + + checkStmts.push(declaringStmt); + local.getUsedStmts().forEach(s => { + if (s !== stmt) { + checkStmts.push(s); + } + }); + // usedStmts中不会记录local为leftOp的stmt,在此处进行补充 + declaringStmt + .getCfg() + .getStmts() + .forEach(s => { + if (s === declaringStmt || !(s instanceof ArkAssignStmt) || s.getLeftOp() !== local) { + return; + } + checkStmts.push(s); + }); + + for (const s of checkStmts) { + const res = this.checkRelatedStmtForLocal(s, local, hasChecked, numberCategory); + if (res.issueReason !== IssueReason.OnlyUsedAsIntLong) { + hasChecked.set(local, res); + return res.issueReason; + } + } + hasChecked.set(local, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); + return IssueReason.OnlyUsedAsIntLong; + } + + private checkRelatedStmtForLocal(stmt: Stmt, local: Local, hasChecked: Map, numberCategory: NumberCategory): IssueInfo { + if (stmt instanceof ArkAssignStmt && stmt.getLeftOp() === local) { + const issueReason = this.checkValueOnlyUsedAsIntLong(stmt, stmt.getRightOp(), hasChecked, numberCategory); + if (issueReason === IssueReason.OnlyUsedAsIntLong) { + return { issueReason, numberCategory }; + } else { + return { issueReason, numberCategory: NumberCategory.number }; + } + } + // 当前检查的local位于赋值语句的右边,若参与除法运算则看做double类型使用,若作为SDK入参依据SDK定义,其余运算、赋值等处理不会影响其自身从int -> number,所以不处理 + if (stmt instanceof ArkAssignStmt && stmt.getLeftOp() !== local) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkNormalBinopExpr && rightOp.getOperator() === NormalBinaryOperator.Division) { + return { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }; + } + if (rightOp instanceof AbstractInvokeExpr) { + const res = this.checkLocalUsedAsSDKArg(rightOp, local, hasChecked); + if (res !== null) { + return res; + } + } + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory }; + } + if (stmt instanceof ArkInvokeStmt) { + // 函数调用语句,local作为实参或base,除作为SDK入参之外,其余场景不会影响其值的变化,不会导致int被重新赋值为number使用 + const res = this.checkLocalUsedAsSDKArg(stmt.getInvokeExpr(), local, hasChecked); + if (res !== null) { + return res; + } + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory }; + } + if (stmt instanceof ArkReturnStmt || stmt instanceof ArkIfStmt) { + // return语句,local作为返回值,不会影响其值的变化,不会导致int被重新赋值为number使用 + // 条件判断语句,local作为condition expr的op1或op2,进行二元条件判断,不会影响其值的变化,不会导致int被重新赋值为number使用 + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory }; + } + logger.error(`Need to check new type of stmt: ${stmt.toString()}, method: ${stmt.getCfg().getDeclaringMethod().getSignature().toString()}`); + return { issueReason: IssueReason.Other, numberCategory: NumberCategory.number }; + } + + // 判断local是否是SDK invoke expr的入参,且其类型是int或long,否则返回null + private checkLocalUsedAsSDKArg(expr: AbstractInvokeExpr, local: Local, hasChecked: Map): IssueInfo | null { + const method = this.scene.getMethod(expr.getMethodSignature()); + if (method === null) { + if (expr instanceof ArkInstanceInvokeExpr && Utils.isNearlyPrimitiveType(expr.getBase().getType())) { + // 调用方法为builtIn方法,但因为类型推导失败,导致获取的方法签名为%unk/%unk + return null; + } + logger.trace(`Failed to find method: ${expr.getMethodSignature().toString()}`); + return null; + } + const args = expr.getArgs(); + if (SdkUtils.isMethodFromSdk(method)) { + const ets2SDKSig = this.getEts2SdkSignatureWithEts1Method(method, args, true); + if (ets2SDKSig === null) { + return null; + } + const argIndex = expr.getArgs().indexOf(local); + if (argIndex < 0 || argIndex >= expr.getArgs().length) { + return null; + } + const params = ets2SDKSig.getMethodSubSignature().getParameters(); + const currLocal = hasChecked.get(local); + if (this.isIntType(params[argIndex].getType())) { + if (currLocal === undefined) { + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: NumberCategory.int }; + } + if (currLocal.numberCategory === NumberCategory.long) { + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: NumberCategory.long }; + } + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: NumberCategory.int }; + } + if (this.isLongType(params[argIndex].getType())) { + return { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: NumberCategory.long }; + } + } + return null; + } + + private getLocalFromGlobal(local: Local, method: ArkMethod): Local | null { + const defaultMethod = method.getDeclaringArkFile().getDefaultClass().getDefaultArkMethod(); + if (!defaultMethod) { + return null; + } + const global = defaultMethod.getBody()?.getLocals().get(local.getName()); + if (global) { + return global; + } + return null; + } + + private getLocalFromImportInfo(local: Local, method: ArkMethod): Local | null { + const importInfo = method.getDeclaringArkFile().getImportInfoBy(local.getName()); + if (importInfo === undefined) { + return null; + } + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return null; + } + const exportLocal = importInfo.getLazyExportInfo()?.getArkExport(); + if (exportLocal === null || exportLocal === undefined) { + return null; + } + if (exportLocal instanceof Local) { + return exportLocal; + } + return null; + } + + // 对于method中的let obj: Obj = {aa: a}的对象字面量,其中使用到a变量为method中的local或global,当前ArkAnalyzer未能对其进行识别和表示,此处手动查找 + // 对于class的field为lambda函数定义的函数指针的场景,lambda函数中使用到的外层的变量,当前ArkAnalyzer未能对其进行识别和表示,此处手动查找 + private getLocalFromOuterMethod(local: Local, method: ArkMethod): Local | null { + const outerMethod = method.getOuterMethod(); + if (outerMethod) { + const newLocal = outerMethod.getBody()?.getLocals().get(local.getName()); + if (newLocal) { + if (newLocal.getDeclaringStmt()) { + return newLocal; + } else { + return this.getLocalFromOuterMethod(newLocal, outerMethod); + } + } + } + + const clazz = method.getDeclaringArkClass(); + return this.findLocalFromOuterClass(local, clazz); + } + + private findLocalFromOuterClass(local: Local, objectClass: ArkClass): Local | null { + if (objectClass.getCategory() !== ClassCategory.INTERFACE && objectClass.getCategory() !== ClassCategory.OBJECT) { + // 此查找仅涉及对象字面量中直接使用变量的场景,其余场景不涉及 + return null; + } + // 根据class的名字获取外层method的名字和其对应的class,例如'%AC3$%dflt.%outer111$%outer11$outer1'表示default class中的outer111$%outer11$outer1 method + const firstDelimiterIndex = objectClass.getName().indexOf(NAME_DELIMITER); + const classAndMethodName = objectClass.getName().substring(firstDelimiterIndex + 1); + const lastDotIndex = classAndMethodName.lastIndexOf('.'); + const className = classAndMethodName.substring(0, lastDotIndex); + const methodName = classAndMethodName.substring(lastDotIndex + 1); + const outerClass = objectClass.getDeclaringArkFile().getClassWithName(className); + if (outerClass === null) { + logger.error(`Failed to find outer class of anonymous class: ${objectClass.getName()}, outerClass name: ${className}`); + return null; + } + const outerMethod = outerClass.getMethodWithName(methodName) ?? outerClass.getStaticMethodWithName(methodName); + if (outerMethod === null) { + logger.error( + `Failed to find outer method of anonymous class: ${objectClass.getName()}, outerClass name: ${className}, outerMethod name:${methodName}` + ); + return null; + } + const newLocal = outerMethod.getBody()?.getLocals().get(local.getName()); + if (newLocal) { + const declaringStmt = newLocal.getDeclaringStmt(); + if (declaringStmt) { + return newLocal; + } + return this.getLocalFromOuterMethod(newLocal, outerMethod); + } + const globalRef = outerMethod.getBody()?.getUsedGlobals()?.get(local.getName()); + if (globalRef && globalRef instanceof GlobalRef) { + const ref = globalRef.getRef(); + if (ref && ref instanceof Local) { + return ref; + } + return null; + } + if (outerClass.isAnonymousClass()) { + return this.findLocalFromOuterClass(local, outerClass); + } + return null; + } + + private isAbstractExprOnlyUsedAsIntLong(stmt: Stmt, expr: AbstractExpr, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + if (expr instanceof ArkNormalBinopExpr) { + if (expr.getOperator() === NormalBinaryOperator.Division) { + const op1 = expr.getOp1(); + const op2 = expr.getOp2(); + if (op1 instanceof NumberConstant && !this.isNumberConstantActuallyFloat(op1)) { + this.addIssueReport(RuleCategory.NumericLiteral, NumberCategory.number, IssueReason.UsedWithOtherType, true, stmt, op1); + } else if (op1 instanceof Local) { + hasChecked.set(op1, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); + } + if (op2 instanceof NumberConstant && !this.isNumberConstantActuallyFloat(op2)) { + this.addIssueReport(RuleCategory.NumericLiteral, NumberCategory.number, IssueReason.UsedWithOtherType, true, stmt, op2); + } else if (op2 instanceof Local) { + hasChecked.set(op2, { issueReason: IssueReason.UsedWithOtherType, numberCategory: NumberCategory.number }); + } + return IssueReason.UsedWithOtherType; + } + const isOp1Int = this.checkValueOnlyUsedAsIntLong(stmt, expr.getOp1(), hasChecked, numberCategory); + const isOp2Int = this.checkValueOnlyUsedAsIntLong(stmt, expr.getOp2(), hasChecked, numberCategory); + if (isOp1Int === IssueReason.OnlyUsedAsIntLong && isOp2Int === IssueReason.OnlyUsedAsIntLong) { + return IssueReason.OnlyUsedAsIntLong; + } + if (isOp1Int === IssueReason.UsedWithOtherType || isOp2Int === IssueReason.UsedWithOtherType) { + return IssueReason.UsedWithOtherType; + } + if (isOp1Int === IssueReason.RelatedWithNonETS2 || isOp2Int === IssueReason.RelatedWithNonETS2) { + return IssueReason.RelatedWithNonETS2; + } + if (isOp1Int === IssueReason.CannotFindAll || isOp2Int === IssueReason.CannotFindAll) { + return IssueReason.CannotFindAll; + } + return IssueReason.Other; + } + if (expr instanceof AbstractInvokeExpr) { + const method = this.scene.getMethod(expr.getMethodSignature()); + if (method === null) { + logger.trace(`Failed to find method: ${expr.getMethodSignature().toString()}`); + return IssueReason.Other; + } + if (SdkUtils.isMethodFromSdk(method)) { + const ets2SDKSig = this.getEts2SdkSignatureWithEts1Method(method, expr.getArgs(), false); + if (ets2SDKSig === null) { + return IssueReason.UsedWithOtherType; + } + if (this.isIntType(ets2SDKSig.getType()) || this.isLongType(ets2SDKSig.getType())) { + return IssueReason.OnlyUsedAsIntLong; + } + return IssueReason.UsedWithOtherType; + } + if (method.getLanguage() !== Language.ARKTS1_2) { + return IssueReason.RelatedWithNonETS2; + } + const returnStmt = method.getReturnStmt(); + for (const s of returnStmt) { + if (!(s instanceof ArkReturnStmt)) { + continue; + } + const res = this.checkValueOnlyUsedAsIntLong(s, s.getOp(), hasChecked, numberCategory); + if (res !== IssueReason.OnlyUsedAsIntLong) { + return res; + } + } + return IssueReason.OnlyUsedAsIntLong; + } + if (expr instanceof ArkAwaitExpr) { + const promise = expr.getPromise(); + if (promise instanceof Local) { + const declaringStmt = promise.getDeclaringStmt(); + if (declaringStmt === null || !(declaringStmt instanceof ArkAssignStmt)) { + logger.error('Missing or wrong declaringStmt for await promise'); + return IssueReason.CannotFindAll; + } + return this.checkValueOnlyUsedAsIntLong(declaringStmt, declaringStmt.getRightOp(), hasChecked, numberCategory); + } + logger.error(`Need to handle new type of promise: ${promise.getType().toString()}`); + return IssueReason.Other; + } + if (expr instanceof ArkCastExpr) { + return this.checkValueOnlyUsedAsIntLong(stmt, expr.getOp(), hasChecked, numberCategory); + } + if (expr instanceof ArkUnopExpr) { + if (expr.getOperator() === UnaryOperator.Neg || expr.getOperator() === UnaryOperator.BitwiseNot) { + return this.checkValueOnlyUsedAsIntLong(stmt, expr.getOp(), hasChecked, numberCategory); + } + if (expr.getOperator() === UnaryOperator.LogicalNot) { + // let a = 1; let b = !a,不会导致a产生int到number的变化 + return IssueReason.OnlyUsedAsIntLong; + } + logger.error(`Need to handle new type of unary operator: ${expr.getOperator().toString()}`); + return IssueReason.Other; + } + // 剩余的expr的类型不应该出现在这里,如果出现了表示有场景未考虑到,打印日志记录,进行补充 + logger.error(`Need to handle new type of expr: ${expr.toString()}`); + return IssueReason.Other; + } + + private isAbstractRefOnlyUsedAsIntLong(stmt: Stmt, ref: AbstractRef, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + if (ref instanceof ArkArrayRef) { + // 使用数组中某元素进行赋值的场景很复杂,需要判断index的具体值,需要判断数组中的队应元素的全部使用场景,当前不做检查,直接返回false + return IssueReason.CannotFindAll; + } + if (ref instanceof AbstractFieldRef) { + return this.checkFieldRef(ref, stmt.getCfg().getDeclaringMethod().getDeclaringArkClass().getSignature(), numberCategory, hasChecked); + } + if (ref instanceof ArkParameterRef) { + return this.checkAllArgsOfParameter(stmt, hasChecked, numberCategory); + } + if (ref instanceof ClosureFieldRef) { + return this.checkClosureFieldRef(ref, hasChecked, numberCategory); + } + // 其他ref类型经分析不应该出现在此处,若存在输出日志,通过分析日志信息进行补充处理,包括:ArkCaughtExceptionRef, GlobalRef, ArkThisRef + logger.error(`Need to check new type of ref in stmt: ${stmt.toString()}`); + return IssueReason.Other; + } + + private checkFieldRef( + fieldRef: AbstractFieldRef, + currentClassSig: ClassSignature, + numberCategory: NumberCategory, + hasChecked: Map + ): IssueReason { + if (SdkUtils.isFieldFromSdk(fieldRef)) { + const ets2FieldType = this.checkSDKFieldType(fieldRef); + if (ets2FieldType && (ets2FieldType === NumberCategory.int || ets2FieldType === NumberCategory.long)) { + return IssueReason.OnlyUsedAsIntLong; + } + return IssueReason.UsedWithOtherType; + } + + const refType = fieldRef.getType(); + const fieldBase = fieldRef.getFieldSignature().getDeclaringSignature(); + if (fieldBase instanceof NamespaceSignature) { + return IssueReason.CannotFindAll; + } + const baseClass = this.scene.getClass(fieldBase); + if (baseClass === null) { + return IssueReason.CannotFindAll; + } + if (baseClass.getLanguage() !== Language.ARKTS1_2) { + return IssueReason.RelatedWithNonETS2; + } + if ( + baseClass.getCategory() === ClassCategory.ENUM || + baseClass.getCategory() === ClassCategory.OBJECT || + baseClass.getCategory() === ClassCategory.INTERFACE + ) { + // 如果是使用enum枚举类型进行赋值,不能修改为int,只能是number + // 如果是使用object对象字面量类型进行赋值,arkts1.1和1.2规定左边一定需要声明具体interface,其中一定写明number类型,不能修改为int + return IssueReason.UsedWithOtherType; + } + if (baseClass.getSignature().toString() !== currentClassSig.toString()) { + return IssueReason.CannotFindAll; + } + const field = baseClass.getField(fieldRef.getFieldSignature()); + if (field === null) { + return IssueReason.CannotFindAll; + } + const existRes = this.classFieldRes.get(field); + if (existRes !== undefined) { + return existRes.issueReason; + } + if (!Utils.isNearlyNumberType(refType)) { + if (refType instanceof UnknownType) { + const res = IssueReason.CannotFindAll; + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + return res; + } + const res = IssueReason.UsedWithOtherType; + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + return res; + } + if (field.containsModifier(ModifierType.PRIVATE)) { + // 如果属性有setter方法,则无法找全其赋值的地方,无法判断是否为int,保守方式判定为number + // 如果属性有getter方法,则无法找全其使用的地方,如果有用作除法运算,则应该是number,保守方式判定为number + if (this.fieldWithSetter(field, baseClass) || this.fieldWithGetter(field, baseClass)) { + const res = IssueReason.CannotFindAll; + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + return res; + } + if (field.containsModifier(ModifierType.READONLY)) { + // 先写入默认值,避免后续查找时出现死循环,得到结果后再进行替换 + this.classFieldRes.set(field, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); + const res = this.checkReadonlyFieldInitializer(field, baseClass, numberCategory, hasChecked); + if (res === IssueReason.OnlyUsedAsIntLong) { + this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + } else { + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + } + return res; + } + this.classFieldRes.set(field, { issueReason: IssueReason.OnlyUsedAsIntLong, numberCategory: numberCategory }); + const res = this.checkPrivateField(field, baseClass, numberCategory, hasChecked); + if (res === IssueReason.OnlyUsedAsIntLong) { + this.classFieldRes.set(field, { issueReason: res, numberCategory: numberCategory }); + } else { + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + } + return res; + } + // 此处若想充分解析,需要在整个项目中找到该field的所有使用到的地方,效率很低,且很容易找漏,当前不做检查,直接返回false + const res = IssueReason.CannotFindAll; + this.classFieldRes.set(field, { issueReason: res, numberCategory: NumberCategory.number }); + return res; + } + + private checkReadonlyFieldInitializer( + field: ArkField, + baseClass: ArkClass, + numberCategory: NumberCategory, + hasChecked: Map + ): IssueReason { + const constructorMethod = baseClass.getMethodWithName(CONSTRUCTOR_NAME); + if (constructorMethod === null) { + return IssueReason.CannotFindAll; + } + // readonly field只允许在构造函数、staticInit、instInit三处中的一处进行初始化 + const res = + this.checkReadonlyFieldInitInMethod(field, constructorMethod, numberCategory, hasChecked) ?? + this.checkReadonlyFieldInitInMethod(field, baseClass.getStaticInitMethod(), numberCategory, hasChecked) ?? + this.checkReadonlyFieldInitInMethod(field, baseClass.getInstanceInitMethod(), numberCategory, hasChecked); + + if (res === null) { + return IssueReason.CannotFindAll; + } + return res; + } + + private checkReadonlyFieldInitInMethod( + field: ArkField, + method: ArkMethod, + numberCategory: NumberCategory, + hasChecked: Map + ): IssueReason | null { + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + return null; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof AbstractFieldRef)) { + continue; + } + if (leftOp.getFieldName() === field.getName()) { + return this.checkValueOnlyUsedAsIntLong(stmt, stmt.getRightOp(), hasChecked, numberCategory); + } + } + return null; + } + + private checkPrivateField(field: ArkField, baseClass: ArkClass, numberCategory: NumberCategory, hasChecked: Map): IssueReason { + const methods = baseClass.getMethods(true); + for (const method of methods) { + if (method.getName().startsWith('Set-') || method.getName().startsWith('Get-')) { + continue; + } + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + continue; + } + for (const stmt of stmts) { + const res = this.checkFieldUsedInStmt(field, stmt, numberCategory, hasChecked); + if (res === null) { + continue; + } + if (res !== IssueReason.OnlyUsedAsIntLong) { + return res; + } + } + } + return IssueReason.OnlyUsedAsIntLong; + } + + // 当前仅查找当前field的fieldRef在左边与fieldRef在右边的场景,其余均不检查,认为cannot find all + private checkFieldUsedInStmt(field: ArkField, stmt: Stmt, numberCategory: NumberCategory, hasChecked: Map): IssueReason | null { + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (leftOp instanceof AbstractFieldRef) { + if (this.isFieldRefMatchArkField(leftOp, field)) { + return this.checkValueOnlyUsedAsIntLong(stmt, rightOp, hasChecked, numberCategory); + } + return null; + } + if (rightOp instanceof AbstractFieldRef) { + if (this.isFieldRefMatchArkField(rightOp, field)) { + if (leftOp instanceof Local && leftOp.getName().startsWith(TEMP_LOCAL_PREFIX)) { + return this.isLocalOnlyUsedAsIntLong(stmt, leftOp, hasChecked, numberCategory); + } + return IssueReason.OnlyUsedAsIntLong; + } + return null; + } + } + const usedFieldRef = stmt.getFieldRef(); + if (usedFieldRef === undefined) { + return null; + } + if (this.isFieldRefMatchArkField(usedFieldRef, field)) { + return IssueReason.CannotFindAll; + } + return null; + } + + private isFieldRefMatchArkField(fieldRef: AbstractFieldRef, field: ArkField): boolean { + const refDeclaringSig = fieldRef.getFieldSignature().getDeclaringSignature(); + if (refDeclaringSig instanceof NamespaceSignature) { + return false; + } + if (refDeclaringSig.toString() !== field.getDeclaringArkClass().getSignature().toString()) { + return false; + } + return fieldRef.getFieldName() === field.getName(); + } + + private fieldWithSetter(field: ArkField, baseClass: ArkClass): boolean { + const methods = baseClass.getMethods(); + for (const method of methods) { + if (!method.getName().startsWith('Set-')) { + continue; + } + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + continue; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof AbstractFieldRef)) { + continue; + } + if (field.getName() === leftOp.getFieldName()) { + return true; + } + } + } + return false; + } + + private fieldWithGetter(field: ArkField, baseClass: ArkClass): boolean { + const methods = baseClass.getMethods(); + for (const method of methods) { + if (!method.getName().startsWith('Get-')) { + continue; + } + const stmts = method.getCfg()?.getStmts(); + if (stmts === undefined) { + continue; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkReturnStmt)) { + continue; + } + const op = stmt.getOp(); + if (op instanceof Local) { + const opDeclaringStmt = op.getDeclaringStmt(); + if (!(opDeclaringStmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = opDeclaringStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceFieldRef)) { + continue; + } + if (field.getName() === rightOp.getFieldName()) { + return true; + } + } + } + } + return false; + } + + private checkAllArgsOfParameter(stmt: Stmt, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + let checkAll = { value: true }; + let visited: Set = new Set(); + const result = this.checkFromStmt(stmt, hasChecked, numberCategory, checkAll, visited); + if (!checkAll.value) { + return IssueReason.CannotFindAll; + } + return result; + } + + private checkClosureFieldRef(closureRef: ClosureFieldRef, hasChecked: Map, numberCategory: NumberCategory): IssueReason { + const closureBase = closureRef.getBase(); + const baseType = closureBase.getType(); + if (!(baseType instanceof LexicalEnvType)) { + // 此场景应该不可能出现,如果出现说明IR解析错误 + logger.error(`ClosureRef base must be LexicalEnvType, but here is ${baseType.getTypeString()}`); + return IssueReason.Other; + } + const outerLocal = baseType.getClosures().filter(local => local.getName() === closureRef.getFieldName()); + if (outerLocal.length !== 1) { + logger.error('Failed to find the local from outer method of the closure local.'); + return IssueReason.Other; + } + const declaringStmt = outerLocal[0].getDeclaringStmt(); + if (declaringStmt === null) { + logger.error('Failed to find the declaring stmt of the local from outer method of the closure local.'); + return IssueReason.Other; + } + return this.isLocalOnlyUsedAsIntLong(declaringStmt, outerLocal[0], hasChecked, numberCategory); + } + + private checkFromStmt( + stmt: Stmt, + hasChecked: Map, + numberCategory: NumberCategory, + checkAll: { value: boolean }, + visited: Set + ): IssueReason { + const method = stmt.getCfg().getDeclaringMethod(); + if (!this.visited.has(method)) { + this.dvfgBuilder.buildForSingleMethod(method); + this.visited.add(method); + } + + 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); + + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod(currentStmt.getCfg().getDeclaringMethod().getSignature()); + this.processCallsites(callsites); + const argMap = this.collectCallSiteArgs(paramIdx, callsites); + this.callDepth++; + if (this.callDepth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return IssueReason.CannotFindAll; + } + for (const [callSite, arg] of argMap) { + const res = this.checkValueOnlyUsedAsIntLong(callSite, arg, hasChecked, numberCategory); + if (res !== IssueReason.OnlyUsedAsIntLong) { + return res; + } + } + return IssueReason.OnlyUsedAsIntLong; + } + } + return IssueReason.Other; + } + + 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 isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectCallSiteArgs(argIdx: number, callsites: Stmt[]): Map { + const argMap = new Map(); + callsites.forEach(callsite => { + const arg = callsite.getInvokeExpr()!.getArg(argIdx); + if (arg !== undefined) { + argMap.set(callsite, arg); + } + }); + return argMap; + } + + private getIssueReasonFromDefectInfo(defect: Defects): IssueReason | null { + const issueProblem = defect.problem; + // 一定要将IssueReason.UsedWithOtherType放在IssueReason.OnlyUsedAsIntLong之前判断,因为他俩有包含关系,位置调换会导致错误 + if (issueProblem.includes(IssueReason.UsedWithOtherType)) { + return IssueReason.UsedWithOtherType; + } + if (issueProblem.includes(IssueReason.OnlyUsedAsIntLong)) { + return IssueReason.OnlyUsedAsIntLong; + } + if (issueProblem.includes(IssueReason.RelatedWithNonETS2)) { + return IssueReason.RelatedWithNonETS2; + } + if (issueProblem.includes(IssueReason.CannotFindAll)) { + return IssueReason.CannotFindAll; + } + if (issueProblem.includes(IssueReason.Other)) { + return IssueReason.Other; + } + return null; + } + + private getNumberCategoryFromFixInfo(fix: RuleFix): NumberCategory | null { + const fixText = fix.text; + let match = fix.text.match(/^([^=;]+:[^=;]+)([\s\S]*)$/); + if (match === null || match.length < 2) { + return null; + } + if (match[1].includes(NumberCategory.int)) { + return NumberCategory.int; + } + if (match[1].includes(NumberCategory.long)) { + return NumberCategory.long; + } + if (match[1].includes(NumberCategory.number)) { + return NumberCategory.number; + } + return null; + } + + private getFieldIssueFromIssueList(field: ArkField): IssueReport | null { + const filePath = field.getDeclaringArkClass().getDeclaringArkFile().getFilePath(); + const position: WarnInfo = { + line: field.getOriginPosition().getLineNo(), + startCol: field.getOriginPosition().getColNo(), + endCol: field.getOriginPosition().getColNo(), + filePath: field.getDeclaringArkClass().getDeclaringArkFile().getFilePath(), + }; + const mapKey = `${filePath}%${position.line}%${position.startCol}%${position.endCol}%${this.rule.ruleId}`; + return this.issuesMap.get(mapKey) ?? null; + } + + private getLocalIssueFromIssueList(local: Local, stmt: Stmt): IssueReport | null { + const filePath = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getFilePath(); + const position = getLineAndColumn(stmt, local, true); + const mapKey = `${filePath}%${position.line}%${position.startCol}%${position.endCol}%${this.rule.ruleId}`; + return this.issuesMap.get(mapKey) ?? null; + } + + private getWarnInfo(field?: ArkField, issueStmt?: Stmt, value?: Value): WarnInfo | null { + let warnInfo: WarnInfo | null = null; + + if (field === undefined) { + if (issueStmt && value) { + warnInfo = getLineAndColumn(issueStmt, value, true); + if (warnInfo.line === -1) { + // 可能是因为获取array index时,array是联合类型导致index未推导成功,checker里面额外去body里找local替换index + // 但是获取index的position信息时,需要使用原始的index去stmt中查找位置 + const actualPosition = this.getActualIndexPosInStmt(issueStmt); + const originPath = issueStmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getFilePath(); + warnInfo = { + line: actualPosition.getFirstLine(), + startCol: actualPosition.getFirstCol(), + endLine: actualPosition.getLastLine(), + endCol: actualPosition.getLastCol(), + filePath: originPath, + }; + } + } else { + logger.error('Missing stmt or value when adding issue.'); + return warnInfo; + } + } else { + warnInfo = { + line: field.getOriginPosition().getLineNo(), + startCol: field.getOriginPosition().getColNo(), + endCol: field.getOriginPosition().getColNo(), + filePath: field.getDeclaringArkClass().getDeclaringArkFile().getFilePath(), + }; + } + if (warnInfo.line === -1) { + if (issueStmt) { + logger.error(`failed to get position info of value in issue stmt: ${issueStmt.toString()}`); + } else if (field) { + logger.error(`failed to get position info of field: ${field.getSignature().toString()}`); + } else { + logger.error(`failed to get position info`); + } + return null; + } + return warnInfo; + } + + private getProblem(ruleCategory: RuleCategory, reason: IssueReason): string | null { + if (ruleCategory === RuleCategory.SDKIntType) { + return 'SDKIntType-' + reason; + } + if (ruleCategory === RuleCategory.NumericLiteral) { + return 'NumericLiteral-' + reason; + } + if (ruleCategory === RuleCategory.ArrayIndex) { + return 'IndexIntType-' + reason; + } + logger.error(`Have not support rule ${ruleCategory} yet.`); + return null; + } + + private getDesc(ruleCategory: RuleCategory, reason: IssueReason, couldAutofix: boolean): string | null { + if (ruleCategory === RuleCategory.NumericLiteral) { + if (reason === IssueReason.OnlyUsedAsIntLong) { + return `It is used as ${NumberCategory.int} (${ruleCategory})`; + } + return `It is used as ${NumberCategory.number} (${ruleCategory})`; + } + if (ruleCategory === RuleCategory.ArrayIndex) { + if (reason === IssueReason.OnlyUsedAsIntLong) { + return `It is used as ${NumberCategory.int} (${ruleCategory})`; + } + if (reason === IssueReason.ActuallyIntConstant) { + return `The number constant could be changed to int constant (${ruleCategory})`; + } + if (couldAutofix) { + return `It is used as ${NumberCategory.number} (${ruleCategory})`; + } + return `The array index is used as ${NumberCategory.number}, please check if it's ok (${ruleCategory})`; + } + logger.error(`Have not support rule ${ruleCategory} yet.`); + return null; + } + + private shouldSkipDuplicatedIssue(numberCategory: NumberCategory, field?: ArkField, value?: Value, issueStmt?: Stmt): boolean { + // 添加新的issue之前需要检查一下已有issue,避免重复issue,或2个issue之间冲突,一个issue要改为int,一个issue要改为long + let currentIssue: IssueReport | null = null; + let issueCategory: NumberCategory | null = null; + if (field !== undefined) { + currentIssue = this.getFieldIssueFromIssueList(field); + if (currentIssue) { + issueCategory = this.getNumberCategoryFromFixInfo(currentIssue.fix as RuleFix); + } + } else if (value instanceof Local) { + if (issueStmt) { + currentIssue = this.getLocalIssueFromIssueList(value, issueStmt); + if (currentIssue && currentIssue.fix) { + issueCategory = this.getNumberCategoryFromFixInfo(currentIssue.fix as RuleFix); + } + } + } + if (currentIssue && issueCategory) { + const issueReason = this.getIssueReasonFromDefectInfo(currentIssue.defect); + if (issueReason === null) { + return false; + } + if (issueReason !== IssueReason.OnlyUsedAsIntLong) { + return true; + } + if (issueCategory !== NumberCategory.long && numberCategory === NumberCategory.long) { + // 删除掉之前的修复为int的,用本次即将add的新的issue替代 + this.issuesMap.delete(this.getIssuesMapKey(currentIssue.defect.mergeKey)); + return false; + } else { + // 已有的issue已经足够进行自动修复处理,无需重复添加 + return true; + } + } + return false; + } + + private getIssuesMapKey(mergeKey: string): string { + const lastIndex = mergeKey.lastIndexOf('%'); + return mergeKey.substring(0, lastIndex); + } + + private addIssueReportForSDKArg( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + couldAutofix: boolean, + issueStmt?: Stmt, + value?: Value, + field?: ArkField, + usedStmt?: Stmt + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + if (!warnInfo || !problem) { + return; + } + let desc: string; + if (reason === IssueReason.OnlyUsedAsIntLong) { + if (usedStmt) { + desc = `It has relationship with the arg of SDK API in ${this.getUsedStmtDesc(usedStmt, issueStmt)} and only used as ${numberCategory}, should be defined as ${numberCategory} (${ruleCategory})`; + } else { + logger.error('Missing used stmt when getting issue description'); + return; + } + } else { + desc = `The arg of SDK API should be ${numberCategory} here (${ruleCategory})`; + } + + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; + } + + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + couldAutofix + ); + + if (!couldAutofix) { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); + return; + } + const autofix = this.generateSDKArgRuleFix(warnInfo, reason, numberCategory, issueStmt, value, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } else { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + return; + } + + private addIssueReportForSDKReturnOrField( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + issueStmt?: Stmt, + value?: Value, + field?: ArkField, + usedStmt?: Stmt + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + if (!warnInfo || !problem) { + return; + } + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; + } + + let desc: string; + if (reason === IssueReason.OnlyUsedAsIntLong) { + if (usedStmt) { + desc = `It has relationship with the SDK API in ${this.getUsedStmtDesc(usedStmt, issueStmt)} and only used as ${numberCategory}, should be defined as ${numberCategory} (${ruleCategory})`; + } else { + logger.error('Missing used stmt when getting issue description'); + return; + } + } else { + desc = `It is used as number (${ruleCategory})`; + } + + 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 autofix = this.generateSDKReturnOrFieldRuleFix(warnInfo, numberCategory, issueStmt, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } else { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + return; + } + + private addIssueReport( + ruleCategory: RuleCategory, + numberCategory: NumberCategory, + reason: IssueReason, + couldAutofix: boolean, + issueStmt?: Stmt, + value?: Value, + field?: ArkField + ): void { + const severity = this.rule.alert ?? this.metaData.severity; + let warnInfo = this.getWarnInfo(field, issueStmt, value); + let problem = this.getProblem(ruleCategory, reason); + let desc = this.getDesc(ruleCategory, reason, couldAutofix); + if (!warnInfo || !problem || !desc) { + return; + } + + const shouldSkip = this.shouldSkipDuplicatedIssue(numberCategory, field, value, issueStmt); + if (shouldSkip) { + return; + } + + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + couldAutofix + ); + + if (!couldAutofix) { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); + return; + } + if (ruleCategory === RuleCategory.NumericLiteral) { + const autofix = this.generateNumericLiteralRuleFix(warnInfo, reason, issueStmt, value, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + return; + } + if (ruleCategory === RuleCategory.ArrayIndex) { + if (reason === IssueReason.ActuallyIntConstant && issueStmt && value instanceof NumberConstant) { + const autofix = this.generateIntConstantIndexRuleFix(warnInfo, issueStmt, value); + if (autofix === null) { + defects.fixable = false; + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, undefined)); + } else { + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + } else { + const autofix = this.generateNumericLiteralRuleFix(warnInfo, reason, issueStmt, value, field); + if (autofix === null) { + // 此规则必须修复,若autofix为null,则表示无需修复,不添加issue + return; + } + this.issuesMap.set(this.getIssuesMapKey(defects.mergeKey), new IssueReport(defects, autofix)); + } + return; + } + } + + private getUsedStmtDesc(usedStmt: Stmt, issueStmt?: Stmt): string { + const issueFile = issueStmt?.getCfg().getDeclaringMethod().getDeclaringArkFile(); + const usedFile = usedStmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + const line = usedStmt.getOriginPositionInfo().getLineNo(); + if (issueFile && issueFile !== usedFile) { + return `${path.normalize(usedFile.getName())}: ${line}`; + } + return `line ${line}`; + } + + private getSourceFile(field?: ArkField, issueStmt?: Stmt): ts.SourceFile | null { + let arkFile: ArkFile; + if (field) { + arkFile = field.getDeclaringArkClass().getDeclaringArkFile(); + } else if (issueStmt) { + arkFile = issueStmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + } else { + logger.error('Missing both issue stmt and field when generating auto fix info.'); + return null; + } + let sourceFile = this.sourceFiles.get(arkFile.getFileSignature()); + if (!sourceFile) { + sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + this.sourceFiles.set(arkFile.getFileSignature(), sourceFile); + } + return sourceFile; + } + + private generateRuleFixForLocalDefine(sourceFile: ts.SourceFile, warnInfo: WarnInfo, numberCategory: NumberCategory): RuleFix | null { + // warnInfo中对于变量声明语句的位置信息只包括变量名,不包括变量声明时的类型注解位置 + // 此处先获取变量名后到行尾的字符串信息,判断是替换‘: number’ 或增加 ‘: int’ + const localRange = FixUtils.getRangeWithAst(sourceFile, { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: warnInfo.line, + endCol: warnInfo.endCol, + }); + const restRange = FixUtils.getLineRangeWithStartCol(sourceFile, warnInfo.line, warnInfo.endCol); + if (!localRange || !restRange) { + logger.error('Failed to getting range info of issue file when generating auto fix info.'); + return null; + } + const restString = FixUtils.getSourceWithRange(sourceFile, restRange); + if (!restString) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + + // 场景1:变量或函数入参,无类型注解的场景,直接在localString后面添加': int',同时考虑可选参数即'?:' + if (!restString.trimStart().startsWith(':') && !restString.trimStart().startsWith('?')) { + let ruleFix = new RuleFix(); + ruleFix.range = localRange; + const localString = FixUtils.getSourceWithRange(sourceFile, ruleFix.range); + if (!localString) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + ruleFix.text = `${localString}: ${numberCategory}`; + return ruleFix; + } + // 场景2:变量或函数入参,有类型注解的场景,需要将类型注解替换成新的类型,同时考虑可选参数即'?:' + const match = restString.match(/^(\s*\??\s*:[^=,);]+)([\s\S]*)$/); + if (match === null || match.length < 3) { + return null; + } + // 如果需要替换成number,但是已经存在类型注解number,则返回null,不需要告警和自动修复 + if (match[1].includes(numberCategory)) { + return null; + } + let ruleFix = new RuleFix(); + ruleFix.range = [localRange[0], localRange[1] + match[1].length]; + const localString = FixUtils.getSourceWithRange(sourceFile, ruleFix.range); + if (!localString) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + const parts = localString.split(':'); + if (parts.length !== 2) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + if (!parts[1].includes(NumberCategory.number)) { + // 原码含有类型注解但是其类型中不含number,无法进行替换 + return null; + } + ruleFix.text = `${parts[0].trimEnd()}: ${parts[1].trimStart().replace(NumberCategory.number, numberCategory)}`; + return ruleFix; + } + + private generateRuleFixForFieldDefine(sourceFile: ts.SourceFile, warnInfo: WarnInfo, numberCategory: NumberCategory): RuleFix | null { + // warnInfo中对于field的endCol与startCol一样,均为filed首列位置,包含修饰符位置,这里autofix采用整行替换方式进行 + const fullRange = FixUtils.getLineRangeWithStartCol(sourceFile, warnInfo.line, warnInfo.startCol); + if (fullRange === null) { + logger.error('Failed to getting range info of issue file when generating auto fix info.'); + return null; + } + const fullValueString = FixUtils.getSourceWithRange(sourceFile, fullRange); + if (fullValueString === null) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + + const ruleFix = new RuleFix(); + // 场景1:对于类属性private a: number 或 private a: number = xxx, fullValueString为private开始到行尾的内容,需要替换为private a: int + let match = fullValueString.match(/^([^=;]+:[^=;]+)([\s\S]*)$/); + if (match !== null && match.length > 2) { + if (match[1].includes(numberCategory)) { + // 判断field是否已经有正确的类型注解 + return null; + } + ruleFix.range = [fullRange[0], fullRange[0] + match[1].length]; + const originalText = FixUtils.getSourceWithRange(sourceFile, ruleFix.range); + if (!originalText) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + if (!originalText.includes(NumberCategory.number)) { + // 原码含有类型注解但是其类型中不含number,无法进行替换 + return null; + } + ruleFix.text = originalText.replace(NumberCategory.number, numberCategory); + return ruleFix; + } + // 场景2:对于private a = 123,originalText为private开始到行尾的内容,需要替换为private a: int = 123 + match = fullValueString.match(/^([^=;]+)([\s\S]*)$/); + if (match !== null && match.length > 2) { + ruleFix.range = [fullRange[0], fullRange[0] + match[1].trimEnd().length]; + const originalText = FixUtils.getSourceWithRange(sourceFile, ruleFix.range); + if (!originalText) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + ruleFix.text = `${originalText}: ${numberCategory}`; + return ruleFix; + } + // 正常情况下不会走到此处,因为field一定有类型注解或初始化值来确定其类型 + return null; + } + + private generateSDKArgRuleFix( + warnInfo: WarnInfo, + issueReason: IssueReason, + numberCategory: NumberCategory, + issueStmt?: Stmt, + value?: Value, + field?: ArkField + ): RuleFix | null { + const sourceFile = this.getSourceFile(field, issueStmt); + if (!sourceFile) { + return null; + } + if (field) { + return this.generateRuleFixForFieldDefine(sourceFile, warnInfo, numberCategory); + } + + if (issueReason === IssueReason.OnlyUsedAsIntLong) { + return this.generateRuleFixForLocalDefine(sourceFile, warnInfo, numberCategory); + } + // 强转场景,获取到对应位置信息,在其后添加'.toInt()'或'.toLong()' + let endLine = warnInfo.line; + if (warnInfo.endLine !== undefined) { + endLine = warnInfo.endLine; + } + const range = FixUtils.getRangeWithAst(sourceFile, { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: endLine, + endCol: warnInfo.endCol, + }); + if (range === null) { + logger.error('Failed to getting range info of issue file when generating auto fix info.'); + return null; + } + const valueString = FixUtils.getSourceWithRange(sourceFile, range); + if (valueString === null) { + logger.error('Failed to getting text of the fix range info when generating auto fix info.'); + return null; + } + const ruleFix = new RuleFix(); + ruleFix.range = range; + if (value === undefined) { + logger.error('Missing issue SDK arg when generating auto fix info.'); + return null; + } + let transStr: string; + if (numberCategory === NumberCategory.int) { + transStr = '.toInt()'; + } else if (numberCategory === NumberCategory.long) { + transStr = '.toLong()'; + } else { + logger.error(`Have not support number category ${numberCategory} yet.`); + return null; + } + + if (value instanceof Local) { + if (!value.getName().startsWith(TEMP_LOCAL_PREFIX)) { + ruleFix.text = `${valueString}${transStr}`; + return ruleFix; + } + const declaringStmt = value.getDeclaringStmt(); + if (declaringStmt === null) { + ruleFix.text = `(${valueString})${transStr}`; + return ruleFix; + } + if (declaringStmt instanceof ArkAssignStmt) { + const rightOp = declaringStmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr || rightOp instanceof AbstractFieldRef || rightOp instanceof ArkArrayRef) { + ruleFix.text = `${valueString}${transStr}`; + return ruleFix; + } + ruleFix.text = `(${valueString})${transStr}`; + return ruleFix; + } + logger.error('Temp local declaring stmt must be assign stmt.'); + return null; + } else { + ruleFix.text = `(${valueString})${transStr}`; + return ruleFix; + } + } + + private generateSDKReturnOrFieldRuleFix(warnInfo: WarnInfo, numberCategory: NumberCategory, issueStmt?: Stmt, field?: ArkField): RuleFix | null { + const sourceFile = this.getSourceFile(field, issueStmt); + if (!sourceFile) { + return null; + } + if (field) { + return this.generateRuleFixForFieldDefine(sourceFile, warnInfo, numberCategory); + } + return this.generateRuleFixForLocalDefine(sourceFile, warnInfo, numberCategory); + } + + private generateIntConstantIndexRuleFix(warnInfo: WarnInfo, issueStmt: Stmt, constant: NumberConstant): RuleFix | null { + if (!this.isFloatActuallyInt(constant)) { + return null; + } + const sourceFile = this.getSourceFile(undefined, issueStmt); + if (!sourceFile) { + return null; + } + const range = FixUtils.getRangeWithAst(sourceFile, { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: warnInfo.line, + endCol: warnInfo.endCol, + }); + if (range === null) { + logger.error('Failed to getting range info of issue file when generating auto fix info.'); + return null; + } + const ruleFix = new RuleFix(); + ruleFix.range = range; + const parts = constant.getValue().split('.'); + if (parts.length !== 2) { + return null; + } + ruleFix.text = parts[0]; + return ruleFix; + } + + private generateNumericLiteralRuleFix(warnInfo: WarnInfo, issueReason: IssueReason, issueStmt?: Stmt, value?: Value, field?: ArkField): RuleFix | null { + const sourceFile = this.getSourceFile(field, issueStmt); + if (!sourceFile) { + return null; + } + + if (field) { + if (issueReason === IssueReason.OnlyUsedAsIntLong) { + return this.generateRuleFixForFieldDefine(sourceFile, warnInfo, NumberCategory.int); + } else { + return this.generateRuleFixForFieldDefine(sourceFile, warnInfo, NumberCategory.number); + } + } + + if (value instanceof NumberConstant) { + // 对整型字面量进行自动修复,转成浮点字面量,例如1->1.0 + if (this.isNumberConstantActuallyFloat(value)) { + // 无需修复 + return null; + } + if (warnInfo.endLine === undefined) { + // 按正常流程不应该存在此场景 + logger.error('Missing end line info in warnInfo when generating auto fix info.'); + return null; + } + const range = FixUtils.getRangeWithAst(sourceFile, { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: warnInfo.endLine, + endCol: warnInfo.endCol, + }); + if (range === null) { + logger.error('Failed to getting range info of issue file when generating auto fix info.'); + return null; + } + + const valueStr = value.getValue(); + const ruleFixText = NumericSemanticCheck.CreateFixTextForIntLiteral(valueStr); + const ruleFix = new RuleFix(); + ruleFix.range = range; + ruleFix.text = ruleFixText; + return ruleFix; + } + // 非整型字面量 + // warnInfo中对于变量声明语句的位置信息只包括变量名,不包括变量声明时的类型注解位置,此处获取变量名后到行尾的字符串信息,替换‘: number’ 或增加 ‘: int’ + if (issueReason === IssueReason.OnlyUsedAsIntLong) { + return this.generateRuleFixForLocalDefine(sourceFile, warnInfo, NumberCategory.int); + } + return this.generateRuleFixForLocalDefine(sourceFile, warnInfo, NumberCategory.number); + } + private static CreateFixTextForIntLiteral(valueStr: string): string { + if (!NumericSemanticCheck.IsNotDecimalNumber(valueStr)) { + return valueStr + '.0'; + } + + return valueStr + '.toDouble()'; + } + + private static IsNotDecimalNumber(value: string): boolean { + const loweredValue = value.toLowerCase(); + return loweredValue.startsWith('0b') || loweredValue.startsWith('0x') || loweredValue.startsWith('0o') || loweredValue.includes('e'); + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts index 66a5c66380b92443cde465bcf577ad4e05791028..80bf82743066d807cae69c9eb67854bf1f9bc249 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts @@ -68,15 +68,24 @@ export class ObjectLiteralCheck implements BaseChecker { for (let arkFile of scene.getFiles()) { const topLevelVarMap: Map = new Map(); - this.collectImportedVar(topLevelVarMap, arkFile); - this.collectTopLevelVar(topLevelVarMap, arkFile, scene); + this.collectImportedVar(topLevelVarMap, arkFile, scene); + this.collectTopLevelVar(topLevelVarMap, arkFile.getDefaultClass(), scene); - const handleClass = (cls: ArkClass): void => { - cls.getMethods().forEach(m => this.processArkMethod(m, topLevelVarMap, scene)); + const handleClass = (cls: ArkClass, localTopLevelVar: Map | undefined = undefined): void => { + if (!localTopLevelVar) { + cls.getMethods().forEach(m => this.processArkMethod(m, topLevelVarMap, scene)); + } else { + topLevelVarMap.forEach((v, k) => localTopLevelVar.set(k, v)); + cls.getMethods().forEach(m => this.processArkMethod(m, localTopLevelVar, scene)); + } }; arkFile.getClasses().forEach(cls => handleClass(cls)); - arkFile.getAllNamespacesUnderThisFile().forEach(n => n.getClasses().forEach(cls => handleClass(cls))); + arkFile.getAllNamespacesUnderThisFile().forEach(n => { + const localTopLevelVar: Map = new Map(); + this.collectTopLevelVar(localTopLevelVar, n.getDefaultClass(), scene); + n.getClasses().forEach(cls => handleClass(cls, localTopLevelVar)); + }); } }; @@ -101,12 +110,12 @@ export class ObjectLiteralCheck implements BaseChecker { 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); + this.addIssueReport(stmt, rightOp, checkAll.value); } } } - private collectImportedVar(importVarMap: Map, file: ArkFile) { + private collectImportedVar(importVarMap: Map, file: ArkFile, scene: Scene): void { file.getImportInfos().forEach(importInfo => { const exportInfo = importInfo.getLazyExportInfo(); if (exportInfo === null) { @@ -120,12 +129,13 @@ export class ObjectLiteralCheck implements BaseChecker { if (!declaringStmt) { return; } + DVFGHelper.buildSingleDVFG(declaringStmt.getCfg().getDeclaringMethod(), scene); importVarMap.set(arkExport.getName(), [declaringStmt]); }); } - private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { - const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); + private collectTopLevelVar(topLevelVarMap: Map, defaultClass: ArkClass, scene: Scene): void { + const defaultMethod = defaultClass.getDefaultArkMethod(); if (!defaultMethod) { return; } @@ -135,11 +145,16 @@ export class ObjectLiteralCheck implements BaseChecker { if (!(stmt instanceof ArkAssignStmt)) { continue; } + let name = undefined; const leftOp = stmt.getLeftOp(); - if (!(leftOp instanceof Local)) { + if (leftOp instanceof Local) { + name = leftOp.getName(); + } else if (leftOp instanceof ArkInstanceFieldRef && leftOp.getBase() instanceof Local) { + name = `${leftOp.getBase().getName()}.${leftOp.getFieldSignature().getFieldName()}`; + } + if (!name) { continue; } - const name = leftOp.getName(); if (name.startsWith('%') || name === 'this') { continue; } @@ -173,23 +188,20 @@ export class ObjectLiteralCheck implements BaseChecker { res.push(currentStmt); continue; } + const gvName = this.checkIfIsTopLevelVar(currentStmt); + if (gvName) { + const globalDefs = topLevelVarMap.get(gvName); + globalDefs?.forEach(d => { + worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene)); + }); + } 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 => { @@ -201,39 +213,36 @@ export class ObjectLiteralCheck implements BaseChecker { DVFGHelper.buildSingleDVFG(declaringMtd, scene); this.visited.add(declaringMtd); } - declaringMtd - .getReturnStmt() - .forEach(r => this.checkFromStmt(r, scene, res, topLevelVarMap, checkAll, visited, depth + 1)); + 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() - ); + 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) - ); + 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 { + private checkIfIsTopLevelVar(stmt: Stmt): string | undefined { if (!(stmt instanceof ArkAssignStmt)) { return undefined; } const rightOp = stmt.getRightOp(); if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { - return rightOp; + return rightOp.getName(); + } + if (rightOp instanceof ArkInstanceFieldRef && rightOp.getBase() instanceof Local) { + return `${rightOp.getBase().getName()}.${rightOp.getFieldSignature().getFieldName()}`; } if (!(rightOp instanceof ArkInstanceOfExpr)) { return undefined; } const obj = rightOp.getOp(); if (obj instanceof Local && !obj.getDeclaringStmt()) { - return obj; + return obj.getName(); } return undefined; } @@ -271,9 +280,6 @@ export class ObjectLiteralCheck implements BaseChecker { 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)) { @@ -359,11 +365,17 @@ export class ObjectLiteralCheck implements BaseChecker { }); } - private addIssueReport(stmt: Stmt, operand: Value): void { + private addIssueReport(stmt: Stmt, operand: Value, checkAll: boolean = true): 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 desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + if (!checkAll) { + desc = `Can not check when function call chain depth exceeds ${CALL_DEPTH_LIMIT}, please check it manually (${this.rule.ruleId.replace( + '@migration/', + '' + )})`; + } let defects = new Defects( warnInfo.line, warnInfo.startCol, @@ -382,7 +394,7 @@ export class ObjectLiteralCheck implements BaseChecker { } private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { const originPath = arkFile.getFilePath(); diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts index a6a56e9b4d2ef3d9d95783a0f6d5e03f4fd5004e..b492f1fcc66e5171900eb786c6bc49ba9f2d3216 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts @@ -31,7 +31,7 @@ import { 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 { ClassMatcher, Defects, MatcherCallback, MatcherTypes, Rule } from '../../Index'; import { IssueReport } from '../../model/Defects'; import { RuleFix } from '../../model/Fix'; import { FixUtils } from '../../utils/common/FixUtils'; @@ -78,21 +78,34 @@ export class ObservedDecoratorCheck implements BaseChecker { public check = (arkClass: ArkClass): void => { const scene = arkClass.getDeclaringArkFile().getScene(); + const projectName = arkClass.getDeclaringArkFile().getProjectName(); 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(); + // 此处仅对field为class类型进行检查,包含class和interface,非class类型不在本规则检查范围之内 + if (!(fieldType instanceof ClassType)) { + continue; + } const initializers = field.getInitializer(); - let canFindAllTargets = true; - let locals: Set = new Set(); + // field无初始化的场景,对field的类型进行检查 + if (initializers.length === 0) { + const fieldTypeClass = scene.getClass(fieldType.getClassSignature()); + if (fieldTypeClass === null || fieldTypeClass.getCategory() !== ClassCategory.CLASS) { + continue; + } + usedClasses.add(fieldTypeClass); + this.handleAllUsedClasses(field, usedClasses); + continue; + } + let canFindAllTargets = true; + let locals: Set = new Set(); // field的初始化语句的最后一句,一定是将右边的value赋值给field,此处仍然判断一次,排除其他场景或者初始化语句为空的场景 const lastStmt = initializers[initializers.length - 1]; if (!(lastStmt instanceof ArkAssignStmt)) { @@ -121,33 +134,16 @@ export class ObservedDecoratorCheck implements BaseChecker { locals.add(rightOp); } else if (rightOp instanceof ArkNewExpr) { // 此处需要区分field = new cls()和field = {}两种场景,查找完毕需继续遍历stmts以解析条件表达式造成的多赋值场景 - canFindAllTargets = canFindAllTargets && this.handleNewExpr(scene, fieldType, rightOp, usedClasses); + canFindAllTargets = canFindAllTargets && this.handleNewExpr(scene, fieldType, rightOp, usedClasses, projectName); } else if (rightOp instanceof AbstractInvokeExpr) { - canFindAllTargets = - canFindAllTargets && this.handleInvokeExpr(scene, fieldType, rightOp, usedClasses); + canFindAllTargets = canFindAllTargets && this.handleInvokeExpr(scene, fieldType, rightOp, usedClasses, projectName); } 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); - } + this.handleAllUsedClasses(field, usedClasses); if (!canFindAllTargets) { const pos = this.getFieldPos(field); @@ -157,15 +153,39 @@ export class ObservedDecoratorCheck implements BaseChecker { } }; + private handleAllUsedClasses(field: ArkField, usedClasses: Set): void { + // issueClasses用于记录usedClasses以及他们的所有父类 + let issueClasses: Set = new Set(); + 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); + } + } + // 此处需要区分field = new cls()和field = {}两种场景 // 对于field = new cls()场景,需要查找此右边class的所有父class // 对于field = {}场景,需要查找左边field类型为class时的所有父class - private handleNewExpr(scene: Scene, fieldType: Type, rightOp: ArkNewExpr, targets: Set): boolean { + private handleNewExpr(scene: Scene, fieldType: Type, rightOp: ArkNewExpr, targets: Set, projectName: string): boolean { const target = scene.getClass(rightOp.getClassType().getClassSignature()); if (target === null) { return false; } + // class为非本项目的内容时,表示调用到三方库、SDK等内容,不再继续进行查找 + if (target.getDeclaringArkFile().getProjectName() !== projectName) { + return true; + } + if (!target.isAnonymousClass()) { // 理论上来说ArkNewExpr中的class一定ClassCategory.CLASS,此处仍然显式的检查一次 if (target.getCategory() !== ClassCategory.CLASS) { @@ -186,6 +206,10 @@ export class ObservedDecoratorCheck implements BaseChecker { if (fieldClass === null) { return false; } + // fieldClass为非本项目的内容时,表示调用到三方库、SDK等内容,不再继续进行查找 + if (fieldClass.getDeclaringArkFile().getProjectName() !== projectName) { + return true; + } if (fieldClass.getCategory() !== ClassCategory.CLASS) { return true; } @@ -197,17 +221,16 @@ export class ObservedDecoratorCheck implements BaseChecker { // 此处需要区分返回值为class和object literal两种场景 // 对于返回值为class的场景,需要查找此class的所有父class // 对于存在返回值为object literal的场景,需要查找左边field类型为class时的所有父class - private handleInvokeExpr( - scene: Scene, - fieldType: Type, - invokeExpr: AbstractInvokeExpr, - targets: Set - ): boolean { + private handleInvokeExpr(scene: Scene, fieldType: Type, invokeExpr: AbstractInvokeExpr, targets: Set, projectName: string): boolean { let canFindAllTargets = true; const callMethod = scene.getMethod(invokeExpr.getMethodSignature()); if (callMethod === null) { return false; } + // callMethod为非本项目的内容时,表示调用到三方库、SDK等内容,不再继续进行查找 + if (callMethod.getDeclaringArkFile().getProjectName() !== projectName) { + return true; + } const stmts = callMethod.getBody()?.getCfg().getStmts(); if (stmts === undefined) { return false; @@ -260,13 +283,9 @@ export class ObservedDecoratorCheck implements BaseChecker { } } - private generateIssueDescription( - field: ArkField, - issueClass: ArkClass | null, - canFindAllTargets: boolean = true - ): string { + 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`; + return `can not find all classes, please check this field manually (arkui-data-observation)`; } const fieldLine = field.getOriginPosition().getLineNo(); const fieldColumn = field.getOriginPosition().getColNo(); @@ -275,10 +294,10 @@ export class ObservedDecoratorCheck implements BaseChecker { 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; + res = `Class ${issueClass.getName()} 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; + res = `Class ${issueClass.getName()} is used by state property in file ${filePath} [${fieldLine}, ${fieldColumn}], ` + res; } return res; } diff --git a/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts index d7496fca0a4763ba96f27fc036c85bed179f9959..62a43d0c37bbca88d74a1eea1c329f356770b660 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts @@ -29,6 +29,7 @@ import { ArkNewExpr, ArkClass, ClassSignature, + ArkReturnStmt, } from 'arkanalyzer'; import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { BaseChecker, BaseMetaData } from '../BaseChecker'; @@ -49,8 +50,10 @@ 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', + 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; @@ -100,11 +103,12 @@ export class ThisBindCheck implements BaseChecker { if (!method || !method.getCfg() || !this.useThisInBody(method)) { continue; } - const isBuilder = method.hasBuilderDecorator() || method.hasDecorator('LocalBuilder'); + 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, base, scene); + this.addIssueReport(stmt, isBuilder, isLocalBuilder, base, scene); } } } @@ -112,7 +116,18 @@ export class ThisBindCheck implements BaseChecker { private useThisInBody(method: ArkMethod): boolean { const thisInstance = (method.getThisInstance() as Local)!; - return thisInstance.getUsedStmts().length > 0; + const usedStmts = thisInstance.getUsedStmts(); + if (method.getName() !== 'constructor') { + return usedStmts.length > 0; + } + // constructor方法一定会有return this语句,此句若为ArkAnalyzer为constructor方法自动生成,则不在检查范围内 + for (const stmt of usedStmts) { + if (stmt instanceof ArkReturnStmt && stmt.getOriginPositionInfo().getLineNo() <= 0) { + continue; + } + return true; + } + return false; } private isSafeUse(v: Value): boolean { @@ -158,9 +173,9 @@ export class ThisBindCheck implements BaseChecker { return true; } - private addIssueReport(stmt: ArkAssignStmt, isBuilder: boolean, operand: Value, scene: Scene): void { - if (isBuilder && this.isAssignToBuilderParam(stmt, scene)) { - this.reportArkUIIssue(stmt, operand); + 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); } @@ -257,10 +272,7 @@ export class ThisBindCheck implements BaseChecker { return arkField.hasBuilderParamDecorator(); } - private findDefinitionOfAnonymousClass( - declaringClass: ArkClass, - anonymousClassSig: ClassSignature - ): ClassSignature | undefined { + 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) { @@ -325,11 +337,11 @@ export class ThisBindCheck implements BaseChecker { this.issues.push(new IssueReport(defects, undefined)); } - private reportArkUIIssue(stmt: ArkAssignStmt, operand: Value): void { + 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 = `${arkuiMetaData.description} (${ARKUI_RULE_ID.replace('@migration/', '')})`; + const desc = `${isLocalBuilder ? LOCAL_BUILDER_PREFIX : ''}${arkuiMetaData.description} (${ARKUI_RULE_ID.replace('@migration/', '')})`; let defects = new Defects( warnInfo.line, warnInfo.startCol, @@ -348,7 +360,7 @@ export class ThisBindCheck implements BaseChecker { } private getLineAndColumn(stmt: ArkAssignStmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); const originPosition = stmt.getOperandOriginalPosition(operand); if (arkFile && originPosition) { const originPath = arkFile.getFilePath(); diff --git a/ets2panda/linter/homecheck/src/checker/migration/Utils.ts b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts index 0992bcbe88d2748a8d25a3b7b12b9c8b6492578c..d50b210d9c5523a7c5debe75ac229ad9729e8322 100644 --- a/ets2panda/linter/homecheck/src/checker/migration/Utils.ts +++ b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts @@ -25,6 +25,10 @@ export const CALL_DEPTH_LIMIT = 2; export class CallGraphHelper { private static cgInstance: CallGraph | null = null; + public static dispose(): void { + this.cgInstance = null; + } + public static getCGInstance(scene: Scene): CallGraph { if (!this.cgInstance) { this.cgInstance = new CallGraph(scene); @@ -36,6 +40,10 @@ export class CallGraphHelper { export class GlobalCallGraphHelper { private static cgInstance: CallGraph | null = null; + public static dispose(): void { + this.cgInstance = null; + } + public static getCGInstance(scene: Scene): CallGraph { if (!this.cgInstance) { this.cgInstance = new CallGraph(scene); @@ -51,6 +59,14 @@ export class DVFGHelper { private static dvfgBuilder: DVFGBuilder; private static built: Set = new Set(); + public static dispose(): void { + // @ts-ignore + this.dvfgInstance = null; + // @ts-ignore + this.dvfgBuilder = null; + this.built.clear(); + } + private static createDVFGInstance(scene: Scene): void { if (!this.dvfgInstance) { this.dvfgInstance = new DVFG(GlobalCallGraphHelper.getCGInstance(scene)); @@ -93,6 +109,7 @@ export const CALLBACK_METHOD_NAME: string[] = [ 'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发 'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发 'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 + 'onChange', ]; export function getLanguageStr(language: Language): string { @@ -116,17 +133,22 @@ export function getLanguageStr(language: Language): string { return targetLan; } -export function getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { - const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); +export function getLineAndColumn(stmt: Stmt, operand: Value, exactEndInfo: boolean = false): 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 }; + if (exactEndInfo) { + const endLine = originPosition.getLastLine(); + const endCol = originPosition.getLastCol(); + return { line, startCol, endLine: endLine, endCol: endCol, filePath: originPath }; + } else { + return { line, startCol, endCol: startCol, filePath: originPath }; + } } else { - logger.debug('ArkFile is null.'); + logger.debug('ArkFile or operand position is null.'); } return { line: -1, startCol: -1, endCol: -1, filePath: '' }; } @@ -150,3 +172,23 @@ export function getGlobalsDefineInDefaultMethod(defaultMethod: ArkMethod): Map { + const globals: 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; + } + globals.set(leftOp.getName(), leftOp); + } + return globals; +} diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts index 1e1565a7c11baa8e3724136b4dbf4440a6161f89..d80c6a094fab957fe2c4b7be98d074762bf7371a 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts @@ -15,6 +15,9 @@ import { ArkClass, ArkFile } from 'arkanalyzer'; import { ClassMatcher, isMatchedFile, isMatchedNamespace, isMatchedClass } from '../Matchers'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'matchClass'); export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: Function): void { for (let arkFile of arkFiles) { @@ -34,7 +37,11 @@ export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: function matchClassProcess(matcher: ClassMatcher, classes: ArkClass[], callback: Function): void { for (const arkClass of classes) { if (isMatchedClass(arkClass, [matcher])) { - callback(arkClass); + try { + callback(arkClass); + } catch (error) { + logger.error('Error in class callback: ', error); + } } } } diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts index f42fd5d7031c4764bedf8cb9a7d68bfc4606cf79..359b3aa728d27cc546f518af8c26b154c2cae642 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts @@ -15,7 +15,9 @@ import { ArkClass, ArkFile } from 'arkanalyzer'; import { isMatchedFile, isMatchedNamespace, isMatchedClass, FieldMatcher, isMatchedField } from '../Matchers'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'matchFields'); export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback: Function): void { for (let arkFile of arkFiles) { @@ -26,20 +28,22 @@ export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback if (matcher.namespace && !isMatchedNamespace(ns, matcher.namespace)) { continue; } - matchFieldsInClasses(matcher, ns.getClasses(), callback); + ns.getClasses().forEach(cls => matchFieldsInClass(matcher, cls, callback)); } - matchFieldsInClasses(matcher, arkFile.getClasses(), callback); + arkFile.getClasses().forEach(cls => matchFieldsInClass(matcher, cls, 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])) { +function matchFieldsInClass(matcher: FieldMatcher, arkClass: ArkClass, callback: Function): void { + if (matcher.class && !isMatchedClass(arkClass, matcher.class)) { + return; + } + for (const arkField of arkClass.getFields()) { + if (isMatchedField(arkField, [matcher])) { + try { callback(arkField); + } catch (error) { + logger.error('Error in field callback: ', error); } } } diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts index 560fa54470b8a7becc532bc7b8d19410ad9aad55..522c96873f2e64174b1500b8d7199accf5d1ae15 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts @@ -15,11 +15,18 @@ import { ArkFile } from 'arkanalyzer'; import { FileMatcher, isMatchedFile } from '../Matchers'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'matchFiles'); export function matchFiles(arkFiles: ArkFile[], matcher: FileMatcher, callback: Function): void { for (let arkFile of arkFiles) { if (isMatchedFile(arkFile, [matcher])) { - callback(arkFile); + try { + callback(arkFile); + } catch (error) { + logger.error('Error in file callback: ', error); + } } } } \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts index 82b42d2ad657e52a7fed48627ea98a31605c8321..3e14f4ff98e131a9f5325d38dd298cf4baf5de1c 100644 --- a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts @@ -15,6 +15,10 @@ import { ArkFile } from 'arkanalyzer'; import { NamespaceMatcher, isMatchedFile, isMatchedNamespace } from '../Matchers'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { ArkNamespace } from 'arkanalyzer/lib'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'matchNameSpaces'); export function matchNameSpaces(arkFiles: ArkFile[], matcher: NamespaceMatcher, callback: Function): void { for (let arkFile of arkFiles) { @@ -22,9 +26,17 @@ export function matchNameSpaces(arkFiles: ArkFile[], matcher: NamespaceMatcher, continue; } for (const ns of arkFile.getAllNamespacesUnderThisFile()) { - if (isMatchedNamespace(ns, [matcher])) { - callback(ns); - } + matchNamespace(ns, matcher, callback); + } + } +} + +function matchNamespace(ns: ArkNamespace, matcher: NamespaceMatcher, callback: Function): void { + if (isMatchedNamespace(ns, [matcher])) { + try { + callback(ns); + } catch (error) { + logger.error('Error in namespace callback: ', error); } } } \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/File2Check.ts b/ets2panda/linter/homecheck/src/model/File2Check.ts index ecfc86270a7f9738fe6afd6ca45319a27f073504..f34f7e142014c745c4a44a142d450f6c92b2aeac 100644 --- a/ets2panda/linter/homecheck/src/model/File2Check.ts +++ b/ets2panda/linter/homecheck/src/model/File2Check.ts @@ -105,8 +105,12 @@ export class File2Check { } public async checkDisable(): Promise { - const fileLineList = await FileUtils.readLinesFromFile(this.arkFile.getFilePath()); - this.issues = await filterDisableIssue(fileLineList, this.issues, this.arkFile.getFilePath()); + try { + const fileLineList = await FileUtils.readLinesFromFile(this.arkFile.getFilePath()); + this.issues = await filterDisableIssue(fileLineList, this.issues, this.arkFile.getFilePath()); + } catch (e) { + logger.error(e); + } } public async run(): Promise { diff --git a/ets2panda/linter/homecheck/src/model/Project2Check.ts b/ets2panda/linter/homecheck/src/model/Project2Check.ts index 3e9c1bf9ed811aeca8b3a79474ba520156a057d6..47bd6995466e10f5274f5b3149c8975186817832 100644 --- a/ets2panda/linter/homecheck/src/model/Project2Check.ts +++ b/ets2panda/linter/homecheck/src/model/Project2Check.ts @@ -85,40 +85,34 @@ export class Project2Check { } 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); - } - })); + 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); + }); } private processSceneCallbacks(): void { - try { - this.sceneCallBacks.forEach((callback) => { - if (this.arkFiles.length !== 0) { + this.sceneCallBacks.forEach((callback) => { + if (this.arkFiles.length !== 0) { + try { callback(this.arkFiles[0].getScene()); + } catch (error) { + logger.error(`Error in scene callback: `, error); } - }); - } catch (error) { - logger.error(`Error in scene callbacks: `, error); - } + } + }); } public collectIssues(): void { @@ -167,10 +161,14 @@ export class Project2Check { 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]); + try { + const fileLineList = await FileUtils.readLinesFromFile(filePath); + const filtedResult = await filterDisableIssue(fileLineList, [issue], filePath); + if (filtedResult.length > 0) { + filtedIssues = filtedIssues.concat(filtedResult[0]); + } + } catch (e) { + logger.error(e); } } this.issues = filtedIssues; @@ -182,4 +180,4 @@ export class Project2Check { this.collectIssues(); await this.checkDisable(); } -} \ No newline at end of file +} diff --git a/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts index 5c3f6478eda979502d63bbb9e1cd817ead03cd0e..7be52a159ab6906519aff74c6c3634d503716c0e 100644 --- a/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts +++ b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts @@ -21,7 +21,8 @@ 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"; +import { FileIssues } from '../../model/Defects'; +import { CallGraphHelper, DVFGHelper, GlobalCallGraphHelper } from '../../checker/migration/Utils'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'MigrationTool'); @@ -68,7 +69,16 @@ export class MigrationTool { await this.checkEntry.runAll(); let result = this.checkEntry.sortIssues(); + this.dispose(); logger.info(`MigrationTool run end`); return result; } + + private dispose(): void { + CallGraphHelper.dispose(); + GlobalCallGraphHelper.dispose(); + DVFGHelper.dispose(); + CheckerStorage.dispose(); + this.checkEntry.scene.dispose(); + } } \ 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 index e08dbb90f7327a8e624256650a80fbfc70c3d4fb..728844baeaaea42d6556040d245f98a5af88d886 100644 --- a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts +++ b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts @@ -98,7 +98,7 @@ export class CheckEntry { /** * 按规则维度统计并输出告警信息,按文件维度汇总并返回告警信息。 - * + * * @returns FileReport[] 文件报告数组,每个元素包含文件名、缺陷列表和输出信息 */ public sortIssues(): FileIssues[] { @@ -235,7 +235,7 @@ export async function checkEntryBuilder(checkEntry: CheckEntry): 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)) { + try { + 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; } - 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); + const text = lineList[issue.defect.reportLine - 2]; + if (!isDisableIssue(text, issue.defect.ruleId)) { + filtedIssues.push(issue); + } } + } catch (e) { + logger.error(e); } return filtedIssues; } diff --git a/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts index 48b06a414dc94e9e5474890f8a89dd32be5116fd..a69df56e6afb4c77b4338e97aefb530e8d505f6f 100644 --- a/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts @@ -67,12 +67,16 @@ export class FileUtils { 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; + try { + // 读取file文件内容首行,若为屏蔽行则跳过 + const firstLineText = await this.readLinesFromFile(filePath, 1); + if (firstLineText.includes(DisableText.FILE_DISABLE_TEXT)) { + continue; + } + result.push(filePath); + } catch (e) { + logger.error(e); } - result.push(filePath); } } return result; @@ -232,7 +236,7 @@ export class FileUtils { } private static shouldSkipFile(fileName: string): boolean { - return ['oh_modules', 'node_modules', 'hvigorfile.ts', 'ohosTest'].includes(fileName); + return ['oh_modules', 'node_modules', 'hvigorfile.ts', 'hvigorfile.js', 'hvigor-wrapper.js', 'ohosTest'].includes(fileName); } private static shouldAddFile(filePath: string, exts: string[]): boolean { diff --git a/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts index 3dc2fc66733fdae58cb1bfce65f1c6f142202226..3ed7f79a2561d7ad1835ab680058b72b5649b652 100644 --- a/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts @@ -62,7 +62,10 @@ export class FixUtils { } // 根据输入的代码片段的起始、结束行列号信息,计算此代码片段在该文件中的起始偏移量、结束偏移量数据 - public static getRangeWithAst(sourceFile: ts.SourceFile, fixPosition: FixPosition): Range { + public static getRangeWithAst(sourceFile: ts.SourceFile, fixPosition: FixPosition): Range | null { + if (fixPosition.startLine < 1 || fixPosition.startCol < 1 || fixPosition.endLine < 1 || fixPosition.endCol < 1) { + return null; + } 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]; @@ -89,6 +92,19 @@ export class FixUtils { return [startPos, endPos]; } + public static getLineRangeWithStartCol(sourceFile: ts.SourceFile, lineNumber: number, startCol: number): Range | null { + const lineRange = this.getLineRange(sourceFile, lineNumber); + if (lineRange === null) { + return null; + } + const newStartPos = lineRange[0] + startCol - 1; + const endPos = lineRange[1]; + if (newStartPos <= endPos) { + return [newStartPos, endPos]; + } + return null; + } + // 根据给定的起始、结束偏移量数据,获取此段代码片段的源码字符串,位置信息不合法则返回null public static getSourceWithRange(sourceFile: ts.SourceFile, range: Range): string | null { const start = range[0]; diff --git a/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts b/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..f094b9e1327426275a874aba963e1eae4002b8ca --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/SDKUtils.ts @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Sdk } from 'arkanalyzer/lib/Config'; +import fs from 'fs'; +import { AnyType, ArkField, ArkFile, ArkMethod, ClassSignature, EnumValueType, Local, MethodSignature, UnionType, Value } from 'arkanalyzer'; +import { Utils } from './Utils'; +import { AbstractFieldRef, ArkNamespace, NamespaceSignature } from 'arkanalyzer/lib'; + +export class SdkUtils { + static OhosSdkName = 'ohosSdk'; + static HmsSdkName = 'hmsSdk'; + + static getEts2SdksWithSdkRelativePath(sdkMap: Map): Sdk[] | null { + const Ets1DirName = 'ets1.1'; + const Ets2DirName = 'ets1.2'; + const ets1OhosSdk = sdkMap.get(this.OhosSdkName); + const ets1HmsSdk = sdkMap.get(this.HmsSdkName); + let sdks: Sdk[] = []; + if (ets1OhosSdk !== undefined) { + const sdkPath = ets1OhosSdk.path; + if (sdkPath.includes(Ets1DirName)) { + const ets2SdkPath = sdkPath.replace(Ets1DirName, Ets2DirName); + if (fs.existsSync(ets2SdkPath)) { + sdks.push({ name: this.OhosSdkName, path: ets2SdkPath, moduleName: ets1OhosSdk.moduleName }); + } + } + } + if (ets1HmsSdk !== undefined) { + const sdkPath = ets1HmsSdk.path; + if (sdkPath.includes(Ets1DirName)) { + const ets2SdkPath = sdkPath.replace(Ets1DirName, Ets2DirName); + if (fs.existsSync(ets2SdkPath)) { + sdks.push({ name: this.HmsSdkName, path: ets2SdkPath, moduleName: ets1HmsSdk.moduleName }); + } + } + } + if (sdks.length > 0) { + return sdks; + } + return null; + } + + static isMethodFromSdk(method: ArkMethod): boolean { + const projectName = method.getDeclaringArkFile().getProjectName(); + return projectName === this.OhosSdkName || projectName === this.HmsSdkName; + } + + static isFieldFromSdk(fieldRef: AbstractFieldRef): boolean { + const projectName = fieldRef.getFieldSignature().getDeclaringSignature().getDeclaringFileSignature().getProjectName(); + return projectName === this.OhosSdkName || projectName === this.HmsSdkName; + } + + static getSdkMatchedSignature(ets1SDK: ArkMethod, args: Value[]): MethodSignature | null { + const declareSigs = ets1SDK.getDeclareSignatures(); + if (declareSigs === null) { + return null; + } + if (declareSigs.length === 1) { + return declareSigs[0]; + } + + let ets1SigMatched: MethodSignature | null = null; + for (const sig of declareSigs) { + const params = sig.getMethodSubSignature().getParameters(); + if (params.length < args.length) { + continue; + } + let matched = true; + for (let i = 0; i < args.length; i++) { + const argType = args[i].getType(); + const paramType = params[i].getType(); + if (argType === paramType) { + continue; + } + if (argType instanceof AnyType || argType instanceof EnumValueType) { + continue; + } + if (!(argType instanceof UnionType) || !Utils.isUnionTypeContainsType(argType, paramType)) { + matched = false; + break; + } + } + if (matched) { + ets1SigMatched = sig; + break; + } + } + return ets1SigMatched; + } + + static getSdkField(etsFile: ArkFile, fieldRef: AbstractFieldRef): ArkField | Local | null { + const declaringSig = fieldRef.getFieldSignature().getDeclaringSignature(); + if (declaringSig instanceof ClassSignature) { + const declaringNS = declaringSig.getDeclaringNamespaceSignature(); + if (!declaringNS) { + return etsFile?.getClassWithName(declaringSig.getClassName())?.getFieldWithName(fieldRef.getFieldName()) ?? null; + } + const namespace = this.getSdkNamespace(etsFile, declaringNS); + if (!namespace) { + return null; + } + return namespace.getClassWithName(declaringSig.getClassName())?.getFieldWithName(fieldRef.getFieldName()) ?? null; + } + const namespace = this.getSdkNamespace(etsFile, declaringSig); + if (!namespace) { + return null; + } + return namespace.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals().get(fieldRef.getFieldName()) ?? null; + } + + static getSdkNamespace(etsFile: ArkFile, namespaceSig: NamespaceSignature): ArkNamespace | null { + const declaringNsSig = namespaceSig.getDeclaringNamespaceSignature(); + if (!declaringNsSig) { + return etsFile.getNamespace(namespaceSig); + } + const declaringNS = this.getSdkNamespace(etsFile, declaringNsSig); + if (!declaringNS) { + return null; + } + return declaringNS.getNamespace(namespaceSig); + } +} diff --git a/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts index 4c481600dd009dad67fafa8ca5b435c070501d5d..461709e972e03af3f9ed3dbbd348a40167003a21 100644 --- a/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts +++ b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts @@ -226,7 +226,7 @@ export class ScopeHelper { 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)) { + } else if (predBlocks.length === 1 && this.gTernaryConditionLines.has(predBlocks[0].getTail()?.getOriginPositionInfo().getLineNo() ?? 0)) { return true; } else { return false; diff --git a/ets2panda/linter/homecheck/src/utils/common/Utils.ts b/ets2panda/linter/homecheck/src/utils/common/Utils.ts index 3dcd8e695dd64f97ac29613b27d93040d7bcabc1..987fdba5b16442c70c964ec3887ce3cd4f30a003 100644 --- a/ets2panda/linter/homecheck/src/utils/common/Utils.ts +++ b/ets2panda/linter/homecheck/src/utils/common/Utils.ts @@ -14,6 +14,9 @@ */ import Logger, { LOG_LEVEL, LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; import { Command, OptionValues } from 'commander'; +import { SceneConfig, Sdk } from 'arkanalyzer/lib/Config'; +import { NullType, NumberType, Scene, Type, UndefinedType } from 'arkanalyzer'; +import { PrimitiveType, UnionType } from 'arkanalyzer/lib'; const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils'); @@ -84,11 +87,81 @@ export class Utils { } return colA - colB; } + + public static generateSceneForEts2SDK(sdks: Sdk[]): Scene { + const sceneConfig: SceneConfig = new SceneConfig(); + sceneConfig.buildConfig('ets2SDK', '', sdks); + sceneConfig.getOptions().enableBuiltIn = false; + + const scene = new Scene(); + scene.buildSceneFromProjectDir(sceneConfig); + return scene; + } + + static isUnionTypeContainsType(unionType: UnionType, targetType: Type): boolean { + for (const t of unionType.getTypes()) { + if (t === targetType) { + return true; + } + } + return false; + } + + /** + * 检查给出的类型是否是NumberType,或numberType与null、undefined的联合类型 + */ + static isNearlyNumberType(checkType: Type): boolean { + if (checkType instanceof NumberType) { + return true; + } + if (checkType instanceof UnionType) { + for (const t of checkType.getTypes()) { + if (t instanceof NumberType || t instanceof UndefinedType || t instanceof NullType) { + continue; + } + if (t instanceof UnionType) { + if (!this.isNearlyNumberType(t)) { + return false; + } + continue; + } + return false; + } + return true; + } + return false; + } + + /** + * 检查给出的类型是否是内置类型,或内置类型与null、undefined的联合类型 + */ + static isNearlyPrimitiveType(checkType: Type): boolean { + if (checkType instanceof PrimitiveType) { + return true; + } + if (checkType instanceof UnionType) { + for (const t of checkType.getTypes()) { + if (t instanceof PrimitiveType || t instanceof UndefinedType || t instanceof NullType) { + continue; + } + if (t instanceof UnionType) { + if (!this.isNearlyPrimitiveType(t)) { + return false; + } + continue; + } + return false; + } + return true; + } + return false; + } } export type WarnInfo = { - line: number, - startCol: number, - endCol: number, - filePath: string + line: number; + startCol: number; + endLine?: number; + endCol: number; + filePath: string; }; diff --git a/ets2panda/linter/package-lock.json b/ets2panda/linter/package-lock.json new file mode 100755 index 0000000000000000000000000000000000000000..7aa01b6307942bef25e8d18f9aead78ea2c60ffc --- /dev/null +++ b/ets2panda/linter/package-lock.json @@ -0,0 +1,5657 @@ +{ + "name": "@panda/tslinter", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@panda/tslinter", + "version": "1.0.0", + "bundleDependencies": [ + "log4js", + "commander", + "homecheck" + ], + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "commander": "^9.4.0", + "fs-extra": "11.2.0", + "homecheck": "file:./homecheck", + "json5": "2.2.3", + "log4js": "^6.4.0", + "yup": "^1.4.0" + }, + "bin": { + "tslinter": "bin/tslinter.js" + }, + "devDependencies": { + "@eslint/compat": "latest", + "@eslint/js": "latest", + "@stylistic/eslint-plugin": "latest", + "@types/node": "18.11.7", + "brace-expansion": "2.0.1", + "eslint": "latest", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsdoc": "^48.0.6", + "eslint-plugin-n": "^17.9.0", + "eslint-plugin-no-null": "^1.0.2", + "glob": "^11.0.0", + "path-scurry": "^2.0.0", + "prettier": "latest", + "rimraf": "^5.0.10", + "shelljs": "^0.8.5", + "typescript-eslint": "latest", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1" + } + }, + "arkanalyzer": { + "version": "1.0.8", + "dependencies": { + "commander": "^9.4.0", + "json5": "2.2.3", + "log4js": "^6.4.0" + } + }, + "homecheck": { + "version": "0.9.11-arkts1.2", + "license": "ISC", + "dependencies": { + "arkanalyzer": "file:../arkanalyzer", + "commander": "^9.4.0", + "fs-extra": "11.2.0", + "json5": "2.2.3", + "log4js": "^6.4.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.46.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", + "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", + "dev": true, + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/compat": { + "version": "1.2.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/compat/-/compat-1.2.9.tgz", + "integrity": "sha512-gCdSY54n7k+driCadyMNv8JSPzYLeDVM/ikZRtvtROBpRdFSkS8W9A82MqsaY7lZuwL0wiapgD0NT1xT0hyJsA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@pkgr/core/-/core-0.1.2.tgz", + "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "4.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@stylistic/eslint-plugin/-/eslint-plugin-4.4.1.tgz", + "integrity": "sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^8.32.1", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/node/-/node-18.11.7.tgz", + "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.33.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "dev": true, + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/arkanalyzer": { + "resolved": "arkanalyzer", + "link": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001721", + "resolved": "https://repo.huaweicloud.com/repository/npm/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://repo.huaweicloud.com/repository/npm/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "inBundle": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://repo.huaweicloud.com/repository/npm/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "inBundle": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "inBundle": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.165", + "resolved": "https://repo.huaweicloud.com/repository/npm/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", + "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.14.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.28.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "48.11.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.11.0.tgz", + "integrity": "sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.46.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.5", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "17.19.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-n/-/eslint-plugin-n-17.19.0.tgz", + "integrity": "sha512-qxn1NaDHtizbhVAPpbMT8wWFaLtPnwhfN/e+chdu2i6Vgzmo/tGM62tcJ1Hf7J5Ie4dhse3DOPMmDxduzfifzw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "@typescript-eslint/utils": "^8.26.1", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "ignore": "^5.3.2", + "minimatch": "^9.0.5", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-no-null": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz", + "integrity": "sha512-uRDiz88zCO/2rzGfgG15DBjNsgwWtWiSo4Ezy7zzajUgpnFIqd1TjepKeRmJZHEfBGu58o2a8S0D7vglvvhkVA==", + "dev": true, + "engines": { + "node": ">=5.0.0" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://repo.huaweicloud.com/repository/npm/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "inBundle": true + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "11.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-11.0.2.tgz", + "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "inBundle": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/homecheck": { + "resolved": "homecheck", + "link": true + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "inBundle": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "dev": true, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://repo.huaweicloud.com/repository/npm/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "inBundle": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://repo.huaweicloud.com/repository/npm/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.5.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "inBundle": true + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://repo.huaweicloud.com/repository/npm/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "inBundle": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "inBundle": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "inBundle": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "inBundle": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/synckit/-/synckit-0.9.3.tgz", + "integrity": "sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.42.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/terser/-/terser-5.42.0.tgz", + "integrity": "sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://repo.huaweicloud.com/repository/npm/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.33.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/typescript-eslint/-/typescript-eslint-8.33.1.tgz", + "integrity": "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.33.1", + "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/utils": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.99.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-cli/node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-sources/-/webpack-sources-3.3.2.tgz", + "integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://repo.huaweicloud.com/repository/npm/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.6.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/yup/-/yup-1.6.1.tgz", + "integrity": "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + } + } +} diff --git a/ets2panda/linter/package.json b/ets2panda/linter/package.json index 73dd2a41801b56968d0cb0ccc2a58ec9b46110bb..8005b794863ea5fcef055cbca09374af90ebd62a 100644 --- a/ets2panda/linter/package.json +++ b/ets2panda/linter/package.json @@ -4,7 +4,7 @@ "main": "dist/tslinter.js", "bin": "bin/tslinter.js", "files": [ - "dist/*" + "dist/*","rule-config.json","docs/rules-cn/*" ], "private": true, "license": "Apache-2.0", @@ -17,13 +17,17 @@ "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-and-homecheck.mjs", - "pack:linter": "rimraf bundle && mkdir bundle && npm pack --pack-destination bundle", + "pack:linter": "rimraf bundle && mkdir bundle && npm pack && mv panda-tslinter-*.tgz 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/migration,test/ohmurl,test/interop,test/sdkwhite,test/concurrent,test/builtin", + "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/deprecatedapi, test/taskpool,test/sdkcommonapi", "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_deprecatedapi": "npm run testrunner -- -d test/deprecatedapi", + "test_taskpool": "npm run testrunner -- -d test/taskpool", + "test_sdkcommonapi": "npm run testrunner -- -d test/sdkcommonapi", "test_concurrent": "npm run testrunner -- -d test/concurrent", "test_rules": "npm run testrunner -- -d test/rules", "test_regression": "npm run testrunner -- -d test/regression", @@ -35,19 +39,27 @@ "test_ts_import_ets": "npm run testrunner -- -d test/ts_import_ets/ts --sdk --interop-mode", "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 test/migration test/ohmurl test/interop test/sdkwhite test/concurrent test/builtin", + "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 test/deprecatedapi test/sdkcommonapi test/taskpool", "eslint-check": "npx eslint .", "eslint-fix": "npm run eslint-check -- --fix", "prettier-fix": "npx prettier --write .", - "fix": "npm run prettier-fix && npm run eslint-fix" + "fix": "npm run prettier-fix && npm run eslint-fix", + "coverage": "npm run coverage-prepare && npm run coverage-instrument && npm run coverage-test && npm run coverage-collect && npm run coverage-report", + "coverage-prepare": "npm run build && node scripts/testRunner/coverage_prepare.js", + "coverage-instrument": "nyc --compact false instrument build coverage/build_instrument", + "coverage-test": "node coverage/build_instrument/testRunner/TestRunner.js -d test/main,test/rules,test/regression,test/extended_features,test/migration,test/ohmurl,test/interop,test/sdkwhite,test/concurrent,test/builtin,test/deprecatedapi,test/sdkcommonapi", + "coverage-collect": "node scripts/testRunner/coverage_collect.js", + "coverage-report": "node scripts/testRunner/coverage_report.js" }, "dependencies": { + "cli-progress": "^3.12.0", "commander": "^9.4.0", + "fs-extra": "11.2.0", "homecheck": "file:./homecheck", + "json5": "2.2.3", "log4js": "^6.4.0", - "yup": "^1.4.0", - "fs-extra": "11.2.0", - "json5": "2.2.3" + "readline-sync": "^1.4.10", + "yup": "^1.4.0" }, "devDependencies": { "@eslint/compat": "latest", @@ -60,10 +72,12 @@ "eslint-plugin-n": "^17.9.0", "eslint-plugin-no-null": "^1.0.2", "glob": "^11.0.0", + "nyc": "^15.1.0", "path-scurry": "^2.0.0", "prettier": "latest", "rimraf": "^5.0.10", "shelljs": "^0.8.5", + "source-map": "^0.7.4", "typescript-eslint": "latest", "webpack": "^5.75.0", "webpack-cli": "^5.0.1" diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json new file mode 100644 index 0000000000000000000000000000000000000000..0c613f3a2f533822cdcd66546a4178ca2ce4e214 --- /dev/null +++ b/ets2panda/linter/rule-config.json @@ -0,0 +1,196 @@ +{ + "ArkTS": [ + "arkts-identifiers-as-prop-names", + "arkts-no-ctor-prop-decls", + "arkts-no-structural-typing", + "arkts-no-inferred-generic-params", + "arkts-no-regexp-literals", + "arkts-no-props-by-index", + "arkts-no-enum-mixed-types", + "arkts-no-definite-assignment", + "arkts-no-globalthis", + "arkts-no-func-props", + "arkts-no-func-bind", + "arkts-no-function-return-this", + "arkts-limited-stdlib", + "arkts-no-class-add-super-prop-with-readonly", + "arkts-concurrent-deprecated-apis", + "arkts-no-classes-as-obj", + "arkts-obj-literal-props", + "arkts-no-template-string-type", + "arkts-obj-literal-key-type", + "arkts-optional-methods", + "arkts-use-long-for-large-numeric-literal", + "arkts-numeric-semantic", + "arkts-limited-tuple-index-type", + "arkts-incompatible-function-types", + "arkts-limited-void-type", + "arkts-distinct-infinity-bitwise-inversion", + "arkts-no-void-operator", + "arkts-no-local-class", + "arkts-no-ts-overload", + "arkts-limited-literal-types", + "arkts-no-exponent-op", + "arkts-no-debugger", + "arkts-no-arguments-obj", + "arkts-no-tagged-templates", + "arkts-switch-expr", + "arkts-case-expr", + "arkts-array-index-negative", + "arkts-class-lazy-import", + "arkts-obj-no-constructor", + "arkts-runtime-array-check", + "arkts-no-side-effect-import", + "arkts-no-lazy-import", + "arkts-no-dynamic-import", + "arkts-no-ts-decorators", + "arkts-common-union-member-access", + "arkts-no-method-overriding-field", + "arkts-no-tuples-arrays", + "arkts-class-static-initialization", + "arkts-invalid-identifier", + "arkts-no-import-json-file", + "arkts-no-import-namespace-with-star-as-var", + "arkts-no-extends-expression", + "arkts-no-ts-like-function-call", + "arkts-method-inherit-rule", + "arkts-default-args-behind-required-args", + "arkts-enum-no-props-by-index", + "arkts-limited-stdlib-no-setCloneList", + "arkts-limited-stdlib-no-setTransferList", + "arkts-builtin-object-getOwnPropertyNames", + "arkts-no-class-omit-interface-optional-prop", + "arkts-distinct-abstract-method-default-return-type", + "arkts-class-no-signature-distinct-with-object-public-api", + "arkts-union-assignment-with-obj-literal-ambiguity", + "arkts-no-sparse-array", + "arkts-no-enum-prop-as-type", + "arkts-no-ts-like-smart-type", + "arkts-distinct-unsigned-right-shift-negative-number", + "arkts-array-type-immutable", + "arkts-primitive-type-normalization", + "arkts-no-ts-like-catch-type", + "arkts-numeric-bigint-compare", + "arkts-only-support-decimal-bigint-literal", + "arkts-unsupport-operator", + "arkts-no-duplicate-function-name", + "arkts-require-func-arg-type", + "arkts-subclass-must-call-super-constructor-with-args", + "arkts-no-esobject-support", + "arkts-not-support-tuple-generic-validation", + "arkts-no-optional-tuple-type", + "arkts-no-large-numeric-literal", + "arkts-no-instanceof-func", + "arkts-no-unfixed-len-tuple", + "arkts-no-super-call-in-static-context" + ], + "interop": [ + "arkts-interop-js2s-inherit-js-class", + "arkts-interop-js2s-traverse-js-instance", + "arkts-interop-js2s-js-call-static-function", + "arkts-interop-js2s-condition-judgment", + "arkts-interop-js2s-js-expand-static-instance", + "arkts-interop-js2s-js-exception", + "arkts-interop-d2s-static-object-on-dynamic-instance", + "arkts-interop-d2s-static-reflect-on-dynamic-instance", + "arkts-interop-ts2s-static-access-ts-type", + "arkts-interop-ts2s-ts-exception", + "arkts-interop-js2s-export-js", + "arkts-interop-d2s-export-entity", + "arkts-interop-s2d-object-literal", + "arkts-interop-d2s-object-literal-no-ambiguity", + "arkts-interop-d2s-object-literal-no-args-constructor", + "arkts-interop-js2s-import-js", + "arkts-interop-js2s-call-js-func", + "arkts-interop-js2s-access-js-prop", + "arkts-interop-js2s-convert-js-type", + "arkts-interop-js2s-typeof-js-type", + "arkts-interop-js2s-unary-op", + "arkts-interop-js2s-binary-op", + "arkts-interop-js2s-compare-js-data", + "arkts-interop-js2s-equality-judgment", + "arkts-interop-js2s-access-js-index", + "arkts-interop-js2s-await-js-promise", + "arkts-interop-js2s-create-js-instance", + "arkts-interop-js2s-call-js-method", + "arkts-interop-js2s-instanceof-js-type", + "arkts-interop-js2s-self-addtion-reduction", + "arkts-promise-with-void-type-need-undefined-as-resolve-arg", + "arkts-class-same-type-prop-with-super" + ], + "ArkUI": [ + "arkui-no-!!-bidirectional-data-binding", + "arkui-no-$$-bidirectional-data-binding", + "arkui-link-decorator-passing", + "arkui-no-extend-decorator", + "arkui-no-styles-decorator", + "arkui-animatableextend-use-receiver", + "arkui-data-observation", + "arkui-modular-interface", + "arkui-entry-annotation-parameters", + "arkui-makeobserved-cannot-observe-custom-class", + "arkui-provide-annotation-parameters", + "arkui-custom-layout-need-add-decorator", + "arkui-no-prop-decorator", + "arkui-no-storageprop-decorator", + "arkui-no-localstorageprop-decorator", + "arkui-no-prop-function", + "arkui-no-setandprop-function", + "arkui-prop-need-call-method-for-deep-copy", + "arkui-no-localbuilder-decorator", + "arkui-statestyles-block-need-arrow-func", + "arkui-repeat-disable-default-virtualscroll", + "arkui-wrappedbuilder-require-arrow-func-generic", + "arkui-wrapbuilder-require-arrow-func-generic", + "arkui-no-deprecated-api", + "arkui-buildernode-generic-no-tuple", + "arkui-buildernode-update-no-literal", + "arkui-buildernode-no-nestingbuildersupported", + "arkui-sdk-common-deprecated-api", + "arkui-sdk-common-whitelist-api", + "arkui-sdk-common-behaviorchange-api", + "arkui-persistent-prop-serialization", + "arkui-persistent-props-serialization", + "arkui-persistencev2-connect-serialization" + ], + "builtin": [ + "arkts-builtin-thisArgs", + "arkts-builtin-symbol-iterator", + "arkts-builtin-no-property-descriptor", + "arkts-builtin-cotr", + "arkts-builtin-new-cotr", + "arkts-builtin-uninitialized-element", + "arkts-builtin-final-class", + "arkts-builtin-narrow-types", + "arkts-builtin-disable-api", + "arkts-builtin-iterator-result-value" + ], + "OHMURL": [ + "arkts-require-fullpath-name" + ], + "sdk": [ + "sdk-limited-void-type", + "sdk-optional-methods", + "sdk-no-sendable-prop-types", + "sdk-ctor-signatures-iface", + "sdk-no-props-by-index", + "sdk-constructor-funcs", + "sdk-no-literal-as-property-name", + "sdk-no-decl-with-duplicate-name", + "sdk-type-query", + "sdk-ability-asynchronous-lifecycle", + "sdk-ability-lifecycle-monitor" + ], + "concurrent": [ + "arkts-no-need-stdlib-ason", + "arkts-no-need-stdlib-sendable-containers", + "arkts-limited-stdlib-no-use-shared", + "arkts-limited-stdlib-no-use-concurrent", + "arkts-limited-stdlib-no-import-concurrency", + "arkts-limited-stdlib-no-support-isConcurrent", + "arkts-no-need-stdlib-sharedArrayBuffer", + "arkts-limited-stdlib-no-sendable-decorator", + "arkts-limited-stdlib-no-concurrent-decorator", + "arkts-no-need-stdlib-worker" + ] +} diff --git a/ets2panda/linter/scripts/testRunner/coverage_collect.js b/ets2panda/linter/scripts/testRunner/coverage_collect.js new file mode 100644 index 0000000000000000000000000000000000000000..4bb11762d49dcd6d539027e7e3efacea4c4f9326 --- /dev/null +++ b/ets2panda/linter/scripts/testRunner/coverage_collect.js @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 fs = require('fs'); +const sourceMap = require('source-map'); +const path = require('path'); + +const PROJECT_ROOT = path.join(__dirname, '..', '..'); +const COVERAGE_DIR = path.join(PROJECT_ROOT, 'coverage'); +const COVERAGE_FILE = path.join(COVERAGE_DIR, 'coverage.json'); +const NEW_COVERAGE_FILE = path.join(COVERAGE_DIR, 'newCoverage.json'); + +/** + * Processes statement map data using source map consumer + * @param {Object} statementMap - Statement map data + * @param {Object} consumer - Source map consumer + */ +function processStatementMap(statementMap, consumer) { + for (const id in statementMap) { + const statement = statementMap[id]; + const startPos = consumer.originalPositionFor(statement.start); + const endPos = consumer.originalPositionFor(statement.end); + + statement.start = { + line: startPos.line, + column: 0 + }; + statement.end = { + line: endPos.line, + column: Number.MAX_SAFE_INTEGER + }; + } +} + +/** + * Processes function map data using source map consumer + * @param {Object} functionMap - Function map data + * @param {Object} consumer - Source map consumer + */ +function processFunctionMap(functionMap, consumer) { + for (const id in functionMap) { + const func = functionMap[id]; + + const declStart = consumer.originalPositionFor(func.decl.start); + const declEnd = consumer.originalPositionFor(func.decl.end); + + func.decl = { + start: { + line: declStart.line, + column: 0 + }, + end: { + line: declEnd.line, + column: Number.MAX_SAFE_INTEGER + } + }; + + func.loc = { + start: { line: declStart.line, column: 0 }, + end: { line: declEnd.line, column: Number.MAX_SAFE_INTEGER } + }; + + func.line = declStart.line; + } +} + +/** + * Processes branch map data using source map consumer + * @param {Object} branchMap - Branch map data + * @param {Object} consumer - Source map consumer + */ +function processBranchMap(branchMap, consumer) { + for (const id in branchMap) { + const branch = branchMap[id]; + + // Process locations + branch.locations.forEach(location => { + const startPos = consumer.originalPositionFor(location.start); + const endPos = consumer.originalPositionFor(location.end); + + location.start = { line: startPos.line, column: startPos.column }; + location.end = { line: endPos.line, column: endPos.column }; + }); + + // Process loc + const locStart = consumer.originalPositionFor(branch.loc.start); + const locEnd = consumer.originalPositionFor(branch.loc.end); + + branch.loc = { + start: { line: locStart.line, column: locStart.column }, + end: { line: locEnd.line, column: locEnd.column } + }; + + branch.line = locStart.line; + } +} + + +/** + * Filter out coverage data before line 16 and remove function declaration coverage + * @param {Object} newCoverageData Original coverage data + * @returns {Object} Filtered coverage data + */ +function filterCoverageByLine(newCoverageData) { + const filteredCoverage = {}; + for (const filePath in newCoverageData) { + const fileCoverage = newCoverageData[filePath]; + const filteredFileCoverage = { + ...fileCoverage, + statementMap: {}, + fnMap: {}, + branchMap: {}, + s: {}, + f: {}, + b: {} + }; + for (const stmtId in fileCoverage.statementMap) { + const stmt = fileCoverage.statementMap[stmtId]; + if (stmt.start.line >= 16) { + filteredFileCoverage.statementMap[stmtId] = stmt; + filteredFileCoverage.s[stmtId] = fileCoverage.s[stmtId]; + } + } + for (const fnId in fileCoverage.fnMap) { + const fn = fileCoverage.fnMap[fnId]; + if (fn.decl.start.line >= 16) { + const newFn = { + ...fn, + decl: null, + loc: { + start: { + line: fn.decl.end.line + 1, + column: 0 + }, + end: fn.loc.end + }, + line: fn.decl.end.line + 1 + }; + filteredFileCoverage.fnMap[fnId] = newFn; + filteredFileCoverage.f[fnId] = fileCoverage.f[fnId]; + } + } + for (const branchId in fileCoverage.branchMap) { + const branch = fileCoverage.branchMap[branchId]; + if (branch.loc.start.line >= 16) { + filteredFileCoverage.branchMap[branchId] = branch; + filteredFileCoverage.b[branchId] = fileCoverage.b[branchId]; + } + } + if (Object.keys(filteredFileCoverage.statementMap).length > 0 || + Object.keys(filteredFileCoverage.fnMap).length > 0 || + Object.keys(filteredFileCoverage.branchMap).length > 0) { + filteredCoverage[filePath] = filteredFileCoverage; + } + } + return filteredCoverage; +} + + +/** + * Collects and processes coverage data using source maps + */ +async function collectCoverage() { + if (!fs.existsSync(COVERAGE_FILE)) { + throw new Error(`Coverage file not found: ${COVERAGE_FILE}`); + } + + const coverageData = JSON.parse(fs.readFileSync(COVERAGE_FILE, 'utf8')); + const newCoverageData = {}; + + for (const file in coverageData) { + const mapFile = `${file}.map`; + + if (!fs.existsSync(mapFile)) { + console.warn(`Source map not found for: ${file}`); + continue; + } + + const sourceMapData = JSON.parse(fs.readFileSync(mapFile, 'utf8')); + const sources = sourceMapData.sources; + const newFile = path.join(path.dirname(mapFile), sources[0]); + + await sourceMap.SourceMapConsumer.with(sourceMapData, null, (consumer) => { + const fileCoverage = { ...coverageData[file] }; + fileCoverage.path = newFile; + + processStatementMap(fileCoverage.statementMap, consumer); + processFunctionMap(fileCoverage.functionMap, consumer); + processBranchMap(fileCoverage.branchMap, consumer); + + newCoverageData[newFile] = fileCoverage; + }); + } + + const filteredCoverage = filterCoverageByLine(newCoverageData); + + fs.writeFileSync( + NEW_COVERAGE_FILE, + JSON.stringify(filteredCoverage, null, 4) + ); +} + +// Execute and handle errors +collectCoverage() + .then(() => console.log('Coverage collection completed successfully')) + .catch(error => { + console.error('Error collecting coverage:', error); + process.exit(1); + }); \ No newline at end of file diff --git a/ets2panda/linter/scripts/testRunner/coverage_prepare.js b/ets2panda/linter/scripts/testRunner/coverage_prepare.js new file mode 100644 index 0000000000000000000000000000000000000000..fddbdb846680f9cdbb21b3af5d55cd4b974794b1 --- /dev/null +++ b/ets2panda/linter/scripts/testRunner/coverage_prepare.js @@ -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. + */ + +const fs = require('fs'); +const path = require('path'); + +const projectRoot = path.join(__dirname, '..', '..'); +const buildDir = path.join(projectRoot, 'build'); +const coverageDir = path.join(projectRoot, 'coverage'); +const buildInstrumentDir = path.join(coverageDir, 'build_instrument'); + +function copyDirectory(srcDirectory, destDirectory) { + fs.mkdirSync(destDirectory, { recursive: true }); + + const directoryEntries = fs.readdirSync(srcDirectory, { withFileTypes: true }); + + for (const dirent of directoryEntries) { + const srcFilepath = path.join(srcDirectory, dirent.name); + const destFilepath = path.join(destDirectory, dirent.name); + + if (dirent.isDirectory()) { + copyDirectory(srcFilepath, destFilepath); + } else { + fs.copyFileSync(srcFilepath, destFilepath); + } + } +} + +function prepareCoverage() { + try { + if (fs.existsSync(coverageDir)) { + fs.rmSync(coverageDir, { recursive: true, force: true }); + } + + fs.mkdirSync(coverageDir, { recursive: true }); + fs.mkdirSync(buildInstrumentDir, { recursive: true }); + + copyDirectory(buildDir, buildInstrumentDir); + + const dataDir = path.join(projectRoot, 'src', 'data'); + const instrumentDataDir = path.join(buildInstrumentDir, 'data'); + + if (fs.existsSync(dataDir)) { + copyDirectory(dataDir, instrumentDataDir); + } + } catch (error) { + console.error('Error during coverage preparation:', error); + process.exit(1); + } +} + +prepareCoverage(); \ No newline at end of file diff --git a/ets2panda/linter/scripts/testRunner/coverage_report.js b/ets2panda/linter/scripts/testRunner/coverage_report.js new file mode 100644 index 0000000000000000000000000000000000000000..134a0f3e81677c89e06c51ab08a186fa5b92223b --- /dev/null +++ b/ets2panda/linter/scripts/testRunner/coverage_report.js @@ -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 fs = require('fs'); +const path = require('path'); +const libCoverage = require('istanbul-lib-coverage'); +const libReport = require('istanbul-lib-report'); +const reports = require('istanbul-reports'); + +const projectRoot = path.resolve(__dirname, '../..'); +const coverageDir = path.join(projectRoot, 'coverage'); +const reportDir = path.join(coverageDir, 'arkcompiler/ets_frontend/ets2panda/linter/src'); +const ABS_REPORT_DIR = 'arkcompiler/ets_frontend/ets2panda/linter/src'; + +const coverageFile = path.join(coverageDir, 'newCoverage.json'); +if (!fs.existsSync(coverageFile)) { + throw new Error(`Coverage file not found: ${coverageFile}`); +} + +const coverageData = JSON.parse(fs.readFileSync(coverageFile, 'utf8')); + +Object.keys(coverageData).forEach(filePath => { + coverageData[filePath].fullPath = path.resolve(projectRoot, filePath); +}); + +const coverageMap = libCoverage.createCoverageMap(coverageData); +console.log(coverageMap); +const context = libReport.createContext({ + dir: reportDir, + watermarks: { + statements: [50, 80], + branches: [50, 80], + functions: [50, 80], + lines: [50, 80] + }, + coverageMap +}); + +reports.create('html', {}).execute(context); + +function enhanceHtmlReports() { + const indexPath = path.join(reportDir, 'index.html'); + if (!fs.existsSync(indexPath)) + { + return; + } + + let html = fs.readFileSync(indexPath, 'utf8'); + + html = html.replace( + /(.+?)<\/a>/g, + (match, link, name) => { + const absPath = path.join(ABS_REPORT_DIR, link.replace('/index.html', '')); + return `${absPath}`; + } + ); + + fs.writeFileSync(indexPath, html); + console.log(`Added full paths to: ${indexPath}`); +} + +enhanceHtmlReports(); +console.log(`View coverage at: file://${reportDir}/index.html`); \ No newline at end of file diff --git a/ets2panda/linter/src/cli/CommandLineParser.ts b/ets2panda/linter/src/cli/CommandLineParser.ts index d7af2c1be3d1a9287db9411d448923deb2566b28..e84fb2a7ad4ca2886f82256cdceebf4f7b746278 100644 --- a/ets2panda/linter/src/cli/CommandLineParser.ts +++ b/ets2panda/linter/src/cli/CommandLineParser.ts @@ -13,15 +13,22 @@ * limitations under the License. */ -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'; import * as fs from 'node:fs'; import * as path from 'node:path'; +import * as ts from 'typescript'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { cookBookTag } from '../lib/CookBookMsg'; +import { Logger } from '../lib/Logger'; +import { ARKTS_IGNORE_DIRS_OH_MODULES } from '../lib/utils/consts/ArktsIgnorePaths'; +import { + getConfiguredRuleTags, + getConfigureRulePath, + getRulesFromConfig +} from '../lib/utils/functions/ConfiguredRulesProcess'; +import { extractRuleTags } from '../lib/utils/functions/CookBookUtils'; +import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; const TS_EXT = '.ts'; const TSX_EXT = '.tsx'; @@ -124,9 +131,44 @@ function formMigrateOptions(cmdOptions: CommandLineOptions, commanderOpts: Optio } } +function formIdeInteractive(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.ideInteractive) { + cmdOptions.linterOptions.ideInteractive = true; + } + if (commanderOpts.checkTsAndJs) { + cmdOptions.linterOptions.checkTsAndJs = true; + } + if (commanderOpts.autofixCheck) { + cmdOptions.linterOptions.autofixCheck = 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; + } + if (commanderOpts.enableInterop) { + cmdOptions.scanWholeProjectInHomecheck = true; + } +} + function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { const opts: CommandLineOptions = { - inputFiles: parsedCmd.args.inputFiles, + inputFiles: parsedCmd.args.inputFiles.map((file) => { + return path.normalize(file); + }), linterOptions: { useRtLogic: true, interopCheckMode: false @@ -144,6 +186,7 @@ function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { } if (options.projectFolder) { doProjectFolderArg(options.projectFolder, opts); + opts.linterOptions.projectFolderList = options.projectFolder; } if (options.project) { doProjectArg(options.project, opts); @@ -151,29 +194,46 @@ 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.checkTsAndJs) { - opts.linterOptions.checkTsAndJs = true; - } - if (options.homecheck) { - opts.homecheck = true; - } + processRuleConfig(opts, options); + processAutofixRuleConfig(opts, options); + formIdeInteractive(opts, options); formSdkOptions(opts, options); formMigrateOptions(opts, options); + formArkts2Options(opts, options); return opts; } +function processRuleConfig(commandLineOptions: CommandLineOptions, options: OptionValues): void { + const configureRulePath = getConfigureRulePath(options); + const configuredRulesMap = getRulesFromConfig(configureRulePath); + const arkTSRulesMap = extractRuleTags(cookBookTag); + commandLineOptions.linterOptions.ruleConfigTags = getConfiguredRuleTags(arkTSRulesMap, configuredRulesMap); +} + +function processAutofixRuleConfig(commandLineOptions: CommandLineOptions, options: OptionValues): void { + if (options.ruleConfig) { + return; + } + const autofixConfigureRulePath = options.autofixRuleConfig; + if (!autofixConfigureRulePath || autofixConfigureRulePath.length === 0) { + return; + } + const stats = fs.statSync(path.normalize(options.autofixRuleConfig)); + if (!stats.isFile()) { + Logger.error(`The file at ${options.autofixRuleConfig} path does not exist!`); + return; + } + const configuredRulesMap = getRulesFromConfig(autofixConfigureRulePath); + const arkTSRulesMap = extractRuleTags(cookBookTag); + commandLineOptions.linterOptions.autofixRuleConfigTags = getConfiguredRuleTags(arkTSRulesMap, configuredRulesMap); +} + function createCommand(): Command { const program = new Command(); program. @@ -200,11 +260,19 @@ 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'). + option('-o, --output-file-path ', 'path to store all log and result files'). + option('--verbose', 'set log level to see debug messages'). + option('--enable-interop', 'scan whole project to report 1.1 import 1.2'). + option('--rule-config ', 'Path to the rule configuration file'). + option('--autofix-check', 'confirm whether the user needs automatic repair'). + option('--autofix-rule-config ', 'Path to the autofix rule configuration file'). 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 b97aacc9249c7146e71fdc6d97a43a0e7d2106b8..be7e4cdaaa633e0441d49d7d9fb98d34281deaa5 100644 --- a/ets2panda/linter/src/cli/LinterCLI.ts +++ b/ets2panda/linter/src/cli/LinterCLI.ts @@ -13,18 +13,26 @@ * limitations under the License. */ +import { MigrationTool } from 'homecheck'; import * as fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; +import * as readlineSync from 'readline-sync'; import * as readline from 'node:readline'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { getHomeCheckConfigInfo, transferIssues2ProblemInfo } from '../lib/HomeCheck'; import { lint } from '../lib/LinterRunner'; import { Logger } from '../lib/Logger'; import type { ProblemInfo } from '../lib/ProblemInfo'; -import { parseCommandLine } from './CommandLineParser'; -import { compileLintOptions, getEtsLoaderPath } from '../lib/ts-compiler/Compiler'; +import * as statistic from '../lib/statistics/scan/ProblemStatisticsCommonFunction'; +import type { ScanTaskRelatedInfo } from '../lib/statistics/scan/ScanTaskRelatedInfo'; +import { StatisticsReportInPutInfo } from '../lib/statistics/scan/StatisticsReportInPutInfo'; +import { TimeRecorder } from '../lib/statistics/scan/TimeRecorder'; import { logStatistics } from '../lib/statistics/StatisticsLogger'; -import { arkts2Rules } from '../lib/utils/consts/ArkTS2Rules'; +import { compileLintOptions, getEtsLoaderPath } from '../lib/ts-compiler/Compiler'; +import { processSyncErr, processSyncOut } from '../lib/utils/functions/ProcessWrite'; +import { parseCommandLine } from './CommandLineParser'; +import { getAllLinterRules } from '../lib/utils/functions/ConfiguredRulesProcess'; export function run(): void { const commandLineArgs = process.argv.slice(2); @@ -34,6 +42,13 @@ export function run(): void { } const cmdOptions = parseCommandLine(commandLineArgs); + if (cmdOptions.linterOptions.migratorMode && cmdOptions.linterOptions.autofixCheck) { + const shouldRun = readlineSync.question('Do you want to run the linter and apply migration? (y/n): ').toLowerCase(); + if (shouldRun !== 'y') { + console.log('Linting canceled by user.'); + process.exit(0); + } + } if (cmdOptions.devecoPluginModeDeprecated) { runIdeModeDeprecated(cmdOptions); @@ -41,7 +56,7 @@ export function run(): void { runIdeInteractiveMode(cmdOptions); } else { const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions); + const result = lint(compileOptions, new TimeRecorder()); logStatistics(result.projectStats); process.exit(result.hasErrors ? 1 : 0); } @@ -50,27 +65,29 @@ export function run(): void { async function runIdeInteractiveMode(cmdOptions: CommandLineOptions): Promise { cmdOptions.followSdkSettings = true; cmdOptions.disableStrictDiagnostics = true; + const timeRecorder = new TimeRecorder(); + const scanTaskRelatedInfo = {} as ScanTaskRelatedInfo; const compileOptions = compileLintOptions(cmdOptions); - let homeCheckResult = new Map(); - const mergedProblems = new Map(); - - const result = lint(compileOptions, getEtsLoaderPath(compileOptions), homeCheckResult); + scanTaskRelatedInfo.cmdOptions = cmdOptions; + scanTaskRelatedInfo.timeRecorder = timeRecorder; + scanTaskRelatedInfo.compileOptions = compileOptions; + await executeScanTask(scanTaskRelatedInfo); - for (const [filePath, problems] of result.problemsInfos) { - if (!mergedProblems.has(filePath)) { - mergedProblems.set(filePath, []); - } - let filteredProblems = problems; - if (cmdOptions.linterOptions.arkts2) { - filteredProblems = problems.filter((problem) => { - return arkts2Rules.includes(problem.ruleTag); - }); - } - mergedProblems.get(filePath)!.push(...filteredProblems); + const statisticsReportInPutInfo = scanTaskRelatedInfo.statisticsReportInPutInfo; + statisticsReportInPutInfo.statisticsReportName = 'scan-problems-statistics.json'; + statisticsReportInPutInfo.totalProblemNumbers = getTotalProblemNumbers(scanTaskRelatedInfo.mergedProblems); + statisticsReportInPutInfo.cmdOptions = cmdOptions; + statisticsReportInPutInfo.timeRecorder = timeRecorder; + statisticsReportInPutInfo.allLinterRules = getAllLinterRules(); + + if (!cmdOptions.linterOptions.migratorMode && statisticsReportInPutInfo.cmdOptions.linterOptions.projectFolderList) { + await statistic.generateScanProbelemStatisticsReport(statisticsReportInPutInfo); } - const reportData = Object.fromEntries(mergedProblems); - await generateReportFile(reportData); + const mergedProblems = scanTaskRelatedInfo.mergedProblems; + const reportData = Object.fromEntries(mergedProblems); + const reportName: string = 'scan-report.json'; + await statistic.generateReportFile(reportName, reportData, cmdOptions.outputFilePath); for (const [filePath, problems] of mergedProblems) { const reportLine = JSON.stringify({ filePath, problems }) + '\n'; await processSyncOut(reportLine); @@ -79,29 +96,116 @@ async function runIdeInteractiveMode(cmdOptions: CommandLineOptions): Promise { - const reportFilePath = path.join('scan-report.json'); - try { - await fs.promises.writeFile(reportFilePath, JSON.stringify(reportData, null, 2)); - } catch (error) { - console.error('Error generating report file:', error); +function getTotalProblemNumbers(mergedProblems: Map): number { + let totalProblemNumbers: number = 0; + for (const problems of mergedProblems.values()) { + totalProblemNumbers += problems.length; } + return totalProblemNumbers; } -async function processSyncOut(message: string): Promise { - await new Promise((resolve) => { - process.stdout.write(message, () => { - resolve('success'); - }); - }); +async function executeScanTask(scanTaskRelatedInfo: ScanTaskRelatedInfo): Promise { + const cmdOptions = scanTaskRelatedInfo.cmdOptions; + scanTaskRelatedInfo.statisticsReportInPutInfo = new StatisticsReportInPutInfo(); + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToNumbersMap = new Map(); + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToAutoFixedNumbersMap = new Map(); + scanTaskRelatedInfo.mergedProblems = new Map(); + if (cmdOptions.linterOptions.arkts2 && cmdOptions.homecheck) { + await executeHomeCheckTask(scanTaskRelatedInfo); + } + + if (!cmdOptions.skipLinter) { + executeLintTask(scanTaskRelatedInfo); + } } -async function processSyncErr(message: string): Promise { - await new Promise((resolve) => { - process.stderr.write(message, () => { - resolve('success'); - }); - }); +async function executeHomeCheckTask(scanTaskRelatedInfo: ScanTaskRelatedInfo): Promise { + const cmdOptions = scanTaskRelatedInfo.cmdOptions; + const { ruleConfigInfo, projectConfigInfo } = getHomeCheckConfigInfo(cmdOptions); + let migrationTool: MigrationTool | null = new MigrationTool(ruleConfigInfo, projectConfigInfo); + await migrationTool.buildCheckEntry(); + scanTaskRelatedInfo.timeRecorder.startScan(); + scanTaskRelatedInfo.timeRecorder.setHomeCheckCountStatus(true); + const result = await migrationTool.start(); + migrationTool = null; + scanTaskRelatedInfo.homeCheckResult = transferIssues2ProblemInfo(result); + for (const [filePath, problems] of scanTaskRelatedInfo.homeCheckResult) { + if ( + !scanTaskRelatedInfo.cmdOptions.scanWholeProjectInHomecheck && + !scanTaskRelatedInfo.cmdOptions.inputFiles.includes(filePath) + ) { + continue; + } + if (!scanTaskRelatedInfo.mergedProblems.has(filePath)) { + scanTaskRelatedInfo.mergedProblems.set(filePath, []); + } + statistic.accumulateRuleNumbers( + problems, + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToNumbersMap, + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToAutoFixedNumbersMap + ); + scanTaskRelatedInfo.statisticsReportInPutInfo.arkOnePointOneProblemNumbers += + statistic.getArktsOnePointOneProlemNumbers(problems); + scanTaskRelatedInfo.mergedProblems.get(filePath)!.push(...problems); + } +} + +function executeLintTask(scanTaskRelatedInfo: ScanTaskRelatedInfo): void { + const cmdOptions = scanTaskRelatedInfo.cmdOptions; + const compileOptions = scanTaskRelatedInfo.compileOptions; + const homeCheckResult = scanTaskRelatedInfo.homeCheckResult; + if (!scanTaskRelatedInfo.timeRecorder.getHomeCheckCountStatus()) { + scanTaskRelatedInfo.timeRecorder.startScan(); + } + const result = lint( + compileOptions, + scanTaskRelatedInfo.timeRecorder, + getEtsLoaderPath(compileOptions), + homeCheckResult + ); + for (const [filePath, problems] of result.problemsInfos) { + statistic.accumulateRuleNumbers( + problems, + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToNumbersMap, + scanTaskRelatedInfo.statisticsReportInPutInfo.ruleToAutoFixedNumbersMap + ); + scanTaskRelatedInfo.statisticsReportInPutInfo.arkOnePointOneProblemNumbers += + statistic.getArktsOnePointOneProlemNumbers(problems); + mergeLintProblems(filePath, problems, scanTaskRelatedInfo.mergedProblems, cmdOptions); + } +} + +function mergeLintProblems( + filePath: string, + problems: ProblemInfo[], + mergedProblems: Map, + cmdOptions: CommandLineOptions +): void { + if (!mergedProblems.has(filePath)) { + mergedProblems.set(filePath, []); + } + let filteredProblems = problems; + mergedProblems.get(filePath)!.push(...filteredProblems); + + if (cmdOptions.scanWholeProjectInHomecheck) { + for (const file of mergedProblems.keys()) { + if (cmdOptions.inputFiles.includes(file)) { + continue; + } + const totalProblems = mergedProblems.get(file); + if (totalProblems === undefined) { + continue; + } + filteredProblems = totalProblems.filter((problem) => { + return problem.rule.includes('s2d'); + }); + if (filteredProblems.length > 0) { + mergedProblems.set(file, filteredProblems); + } else { + mergedProblems.delete(file); + } + } + } } function getTempFileName(): string { @@ -146,7 +250,7 @@ function runIdeModeDeprecated(cmdOptions: CommandLineOptions): void { cmdOptions.parsedConfigFile.fileNames.push(tmpFileName); } const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions); + const result = lint(compileOptions, new TimeRecorder()); const problems = Array.from(result.problemsInfos.values()); if (problems.length === 1) { showJSONMessage(problems); diff --git a/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts index 82bf349ba604f6c291540d90ddbdf5d52cd3fea3..25569706eef482e73634b435170ff7f88d2c4eb5 100644 --- a/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts @@ -14,18 +14,18 @@ */ 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 { faultsAttrs } from './FaultAttrs'; +import { faultDesc } from './FaultDesc'; +import type { LinterOptions } from './LinterOptions'; +import type { ProblemInfo } from './ProblemInfo'; import { FaultID } from './Problems'; import { ProblemSeverity } from './ProblemSeverity'; +import { FileStatistics } from './statistics/FileStatistics'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; +import { TsUtils } from './utils/TsUtils'; export abstract class BaseTypeScriptLinter { problemsInfos: ProblemInfo[] = []; @@ -69,19 +69,42 @@ export abstract class BaseTypeScriptLinter { }); } - protected incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { + protected incrementCounters( + node: ts.Node | ts.CommentRange, + faultId: number, + autofix?: Autofix[], + errorMsg?: string + ): void { + const badNodeInfo = this.getbadNodeInfo(node, faultId, autofix, errorMsg); + + if (this.shouldSkipRule(badNodeInfo)) { + return; + } + + 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); + } + } + + private getbadNodeInfo( + node: ts.Node | ts.CommentRange, + faultId: number, + autofix?: Autofix[], + errorMsg?: string + ): ProblemInfo { 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 cookBookTg = errorMsg ? errorMsg : cookBookTag[cookBookMsgNum]; const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; const isMsgNumValid = cookBookMsgNum > 0; - autofix = autofix ? BaseTypeScriptLinter.addLineColumnInfoInAutofix(autofix, startPos, endPos) : autofix; + autofix = BaseTypeScriptLinter.processAutofix(autofix, startPos, endPos); const badNodeInfo: ProblemInfo = { line: startPos.line + 1, column: startPos.character + 1, @@ -101,12 +124,24 @@ export abstract class BaseTypeScriptLinter { autofix: autofix, autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined }; - this.problemsInfos.push(badNodeInfo); - this.updateFileStats(faultId, badNodeInfo.line); + return badNodeInfo; + } - // problems with autofixes might be collected separately - if (this.options.reportAutofixCb && badNodeInfo.autofix) { - this.options.reportAutofixCb(badNodeInfo); + private static processAutofix( + autofix: Autofix[] | undefined, + startPos: ts.LineAndCharacter, + endPos: ts.LineAndCharacter + ): Autofix[] | undefined { + return autofix ? BaseTypeScriptLinter.addLineColumnInfoInAutofix(autofix, startPos, endPos) : autofix; + } + + private shouldSkipRule(badNodeInfo: ProblemInfo): boolean { + if (this.options?.ideInteractive) { + const ruleConfigTags = this.options.ruleConfigTags; + if (ruleConfigTags && !ruleConfigTags.has(badNodeInfo.ruleTag)) { + return true; + } } + return false; } } diff --git a/ets2panda/linter/src/lib/CommandLineOptions.ts b/ets2panda/linter/src/lib/CommandLineOptions.ts index 2e959dff1a4ead96afe8fe18c8546e7c3d976296..21ab3de9735a08c9a45c25bd360868f970668a81 100644 --- a/ets2panda/linter/src/lib/CommandLineOptions.ts +++ b/ets2panda/linter/src/lib/CommandLineOptions.ts @@ -25,8 +25,14 @@ export interface CommandLineOptions { sdkDefaultApiPath?: string; sdkExternalApiPath?: string[]; arktsWholeProjectPath?: string; + skipLinter?: boolean; homecheck?: boolean; followSdkSettings?: boolean; devecoPluginModeDeprecated?: boolean; disableStrictDiagnostics?: boolean; + outputFilePath?: string; + verbose?: boolean; + scanWholeProjectInHomecheck?: boolean; + ruleConfig?: string; + autofixCheck?: boolean; } diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index cd0f7e6fc99b9292cb3fac84fab3903415d3a8d2..7a3f6d455229041772d2fadc12bbd38376047304 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -16,6 +16,16 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; +/** + * @note If the value contains multiple parentheses groups, + * the rule name must be placed in the last group. + * + * @example + * // Correct (rule name in last parentheses): + * 'cookBookTag[352] = "1.2 Void conflict...(sdk-ability-asynchronous-lifecycle)"' + * + */ + cookBookTag[1] = 'Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)'; cookBookTag[2] = '"Symbol()" API is not supported (arkts-no-symbol)'; @@ -78,8 +88,9 @@ cookBookTag[57] = ''; cookBookTag[58] = ''; cookBookTag[59] = '"delete" operator is not supported (arkts-no-delete)'; cookBookTag[60] = '"typeof" operator is allowed only in expression contexts (arkts-no-type-query)'; -cookBookTag[61] = ''; -cookBookTag[62] = ''; +cookBookTag[61] = + 'The bitwise inversion gives different result for "Infinity" (arkts-distinct-infinity-bitwise-inversion)'; +cookBookTag[62] = 'Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)'; cookBookTag[63] = ''; cookBookTag[64] = ''; cookBookTag[65] = '"instanceof" operator is partially supported (arkts-instanceof-ref-types)'; @@ -92,10 +103,11 @@ cookBookTag[71] = 'The comma operator "," is supported only in "for" loops (arkt cookBookTag[72] = ''; cookBookTag[73] = ''; cookBookTag[74] = 'Destructuring variable declarations are not supported (arkts-no-destruct-decls)'; -cookBookTag[75] = ''; -cookBookTag[76] = ''; -cookBookTag[77] = ''; -cookBookTag[78] = ''; +cookBookTag[75] = 'Use string-literal keys with Record (arkts-obj-literal-key-type)'; +cookBookTag[76] = 'Type of parameter must be defined explicitly (arkts-require-func-arg-type)'; +cookBookTag[77] = 'Template string type is not supported (arkts-no-template-string-type)'; +cookBookTag[78] = + 'Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)'; cookBookTag[79] = 'Type annotation in catch clause is not supported (arkts-no-types-in-catch)'; cookBookTag[80] = '"for .. in" is not supported (arkts-no-for-in)'; cookBookTag[81] = ''; @@ -161,17 +173,18 @@ cookBookTag[137] = '"globalThis" is not supported (arkts-no-globalthis)'; cookBookTag[138] = 'Some of utility types are not supported (arkts-no-utility-types)'; cookBookTag[139] = 'Declaring properties on functions is not supported (arkts-no-func-props)'; cookBookTag[140] = '\'Function.bind\' is not supported (arkts-no-func-bind)'; -cookBookTag[141] = ''; +cookBookTag[141] = 'Function("return this") is not supported (arkts-no-function-return-this)'; cookBookTag[142] = '"as const" assertions are not supported (arkts-no-as-const)'; cookBookTag[143] = 'Import assertions are not supported (arkts-no-import-assertions)'; cookBookTag[144] = 'Usage of standard library is restricted (arkts-limited-stdlib)'; cookBookTag[145] = 'Strict type checking is enforced (arkts-strict-typing)'; cookBookTag[146] = 'Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)'; cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (arkts-no-ts-deps)'; -cookBookTag[148] = ''; +cookBookTag[148] = + 'Overriding with "readonly" field is not allowed when base field is not "readonly" (arkts-no-class-add-super-prop-with-readonly)'; 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] = @@ -227,6 +240,8 @@ cookBookTag[185] = 'syntax for import type is disabled (arkts-import-types)'; cookBookTag[186] = '"new" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)'; cookBookTag[187] = 'function "Math.pow()" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)'; +cookBookTag[188] = + 'In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)'; 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)'; @@ -236,17 +251,18 @@ 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[206] = '"debugger" is not supported (arkts-no-debugger)'; 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 char, byte, short, int, long, string or enum (arkts-switch-expr)'; +cookBookTag[210] = 'The switch expression type must be of type number, 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[214] = 'Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)'; cookBookTag[215] = 'Array bound not checked. (arkts-runtime-array-check)'; +cookBookTag[216] = + 'The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)'; 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)'; @@ -256,6 +272,9 @@ cookBookTag[236] = 'Method can\'t override filed in interface implemented (arkts 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)'; +cookBookTag[245] = 'JSON files cannot be imported (arkts-no-import-json-file)'; +cookBookTag[249] = + 'The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)'; cookBookTag[251] = '"!!" for bidirectional data binding is not supported (arkui-no-!!-bidirectional-data-binding)'; 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)'; @@ -265,30 +284,44 @@ cookBookTag[256] = '"@Styles" decorator is not supported (arkui-no-styles-decora 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[259] = 'The ArkUI interface should be imported before it is used (arkui-modular-interface)'; cookBookTag[260] = 'The "@Entry" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)'; cookBookTag[261] = - 'The "Prop", "StorageProp", and "LocalStorageProp" decorators, as well as the "prop" and "setAndProp" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)'; -cookBookTag[262] = 'The makeObserved function is not supported (arkui-no-makeobserved-function)'; + 'The UIAbility of 1.2 needs to be listened by the new StaticAbilityLifecycleCallback. The original AbilityLifecycleCallback can only listen to the UIAbility of 1.1 (sdk-ability-lifecycle-monitor)'; +cookBookTag[262] = + 'The "makeObserved" function cannot observe custom class (arkui-makeobserved-cannot-observe-custom-class)'; 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[264] = + 'The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)'; 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[271] = 'No support for static dynamic import (arkts-interop-d2s-dynamic-import)'; -cookBookTag[272] = 'No support for static dynamic import (arkts-interop-ts2s-dynamic-import-ts)'; -cookBookTag[273] = 'No support for static dynamic import (arkts-interop-js2s-dynamic-import-js)'; +cookBookTag[270] = 'ArkTS1.2 cannot catch a non Error instance thrown from JS code (arkts-interop-js2s-js-exception)'; +cookBookTag[272] = + 'This API of process is obsolete in ArkTS 1.1. It\'s no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)'; +cookBookTag[273] = + 'Unsigned right shift on negative number yields different results in ArkTS versions. (arkts-distinct-unsigned-right-shift-negative-number)'; 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)'; + 'The Custom component with custom layout capability needs to add the "@CustomLayout" decorator (arkui-custom-layout-need-add-decorator)'; +cookBookTag[276] = + 'ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)'; +cookBookTag[277] = 'Creating local classes is not supported (arkts-no-local-class)'; +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[286] = + 'Parameters decorated with "@Prop" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)'; +cookBookTag[290] = 'Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)'; cookBookTag[300] = 'The function type should be explicit (arkts-no-ts-like-function-call)'; -cookBookTag[301] = 'Importing from "oh module" requires specifying full path (arkts-ohmurl-full-path)'; +cookBookTag[301] = 'Importing from "oh module" requires specifying full path (arkts-require-fullpath-name)'; cookBookTag[302] = 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)'; cookBookTag[303] = @@ -314,7 +347,6 @@ cookBookTag[319] = 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)'; @@ -322,7 +354,7 @@ 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[329] = 'Enum cannot get member name by member value (arkts-enum-no-props-by-index)'; 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)'; @@ -351,23 +383,64 @@ 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[352] = + '1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)'; +cookBookTag[353] = + 'Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)'; 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 are not supported (arkts-no-sparse-array)'; -cookBookTag[371] = 'Enum prop as type are not supported (arkts-no-enum-prop-as-type)'; +cookBookTag[360] = + '"Repeat" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)'; +cookBookTag[361] = + 'When using "WrappedBuilder", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)'; +cookBookTag[362] = + 'When using "wrapBuilder", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)'; +cookBookTag[363] = 'The generic of "BuilderNode" does not accept tuple (arkui-buildernode-generic-no-tuple)'; +cookBookTag[364] = + 'The "update" interface of "BuilderNode" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new "BuilderNode", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)'; +cookBookTag[365] = 'Property "nestingBuilderSupported" is not supported (arkui-buildernode-no-nestingbuildersupported)'; +cookBookTag[366] = 'ESObject type cannot be used (arkts-no-esobject-support)'; +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 types follow the principle of invariance (arkts-array-type-immutable)'; -cookBookTag[374] = 'ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)'; +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)'; +cookBookTag[381] = + 'The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)'; +cookBookTag[382] = + 'Promiseconstructor only supports using resolve (undefined) (arkts-promise-with-void-type-need-undefined-as-resolve-arg)'; +cookBookTag[391] = + 'The class of the second parameter passed to the "persistProp" method must be a primitive type or Date type, or implement the "toJson" and "fromJson" methods (arkui-persistent-prop-serialization)'; +cookBookTag[392] = + 'The class of the "defaultValue" parameter in the literal passed to the "persistProps" method must be a primitive type or Date type, or implement the "toJson" and "fromJson" methods (arkui-persistent-props-serialization)'; +cookBookTag[393] = + 'When calling the "globalConnect" and "connect" methods, the parameter list of the methods needs to include "toJson" and "fromJson" (arkui-persistencev2-connect-serialization)'; +cookBookTag[399] = 'ArkUI deprecated api check (arkui-no-deprecated-api)'; +cookBookTag[400] = 'ArkUI sdk common deprecated api check (arkui-sdk-common-deprecated-api)'; +cookBookTag[401] = 'ArkUI sdk common whitelist api check (arkui-sdk-common-whitelist-api)'; +cookBookTag[402] = 'ArkUI sdk common behavior change api check (arkui-sdk-common-behaviorchange-api)'; +cookBookTag[403] = 'API is not support initial ctor signature (arkts-builtin-new-cotr)'; +cookBookTag[404] = + 'Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)'; +cookBookTag[405] = 'API is not support use class in this API (arkts-builtin-final-class)'; +cookBookTag[406] = 'Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)'; +cookBookTag[407] = 'API has been disabled (arkts-builtin-disable-api)'; +cookBookTag[408] = 'The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)'; +cookBookTag[409] = 'No optional tuple type (arkts-no-optional-tuple-type)'; +cookBookTag[410] = 'Numeric literal exceeds allowed range (arkts-no-large-numeric-literal)'; +cookBookTag[411] = '"instanceof" operator can\'t be applied to function (arkts-no-instanceof-func)'; +cookBookTag[412] = 'No unfixed length tuple support (arkts-no-unfixed-len-tuple)'; +cookBookTag[413] = 'Subclass can\'t call members of super class in static context (arkts-no-super-call-in-static-context)'; 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 cc8cb7c2181545288c1c5ee733640c852ebf5c09..7de7999b99c15a54a6d371fd3e98382d482ca24c 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -59,11 +59,17 @@ faultsAttrs[FaultID.JsxElement] = new FaultAttributes(54); faultsAttrs[FaultID.UnaryArithmNotNumber] = new FaultAttributes(55); faultsAttrs[FaultID.DeleteOperator] = new FaultAttributes(59); faultsAttrs[FaultID.TypeQuery] = new FaultAttributes(60); +faultsAttrs[FaultID.PrefixUnaryInfinity] = new FaultAttributes(61); +faultsAttrs[FaultID.TupleIndex] = new FaultAttributes(62); faultsAttrs[FaultID.InstanceofUnsupported] = new FaultAttributes(65); faultsAttrs[FaultID.InOperator] = new FaultAttributes(66); faultsAttrs[FaultID.DestructuringAssignment] = new FaultAttributes(69); faultsAttrs[FaultID.CommaOperator] = new FaultAttributes(71); faultsAttrs[FaultID.DestructuringDeclaration] = new FaultAttributes(74); +faultsAttrs[FaultID.LongNumeric] = new FaultAttributes(78); +faultsAttrs[FaultID.ObjectLiteralKeyType] = new FaultAttributes(75); +faultsAttrs[FaultID.ParameterType] = new FaultAttributes(76); +faultsAttrs[FaultID.TemplateStringType] = new FaultAttributes(77); faultsAttrs[FaultID.CatchWithUnsupportedType] = new FaultAttributes(79); faultsAttrs[FaultID.ForInStatement] = new FaultAttributes(80); faultsAttrs[FaultID.MappedType] = new FaultAttributes(83); @@ -100,16 +106,18 @@ faultsAttrs[FaultID.UtilityType] = new FaultAttributes(138); faultsAttrs[FaultID.PropertyDeclOnFunction] = new FaultAttributes(139); faultsAttrs[FaultID.FunctionBind] = new FaultAttributes(140, ProblemSeverity.WARNING); faultsAttrs[FaultID.FunctionBindError] = new FaultAttributes(140); +faultsAttrs[FaultID.NoFunctionReturnThis] = new FaultAttributes(141); faultsAttrs[FaultID.ConstAssertion] = new FaultAttributes(142); faultsAttrs[FaultID.ImportAssertion] = new FaultAttributes(143); faultsAttrs[FaultID.LimitedStdLibApi] = new FaultAttributes(144); faultsAttrs[FaultID.StrictDiagnostic] = new FaultAttributes(145); faultsAttrs[FaultID.ErrorSuppression] = new FaultAttributes(146); +faultsAttrs[FaultID.NoClassSuperPropReadonly] = new FaultAttributes(148); 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); @@ -146,6 +154,7 @@ faultsAttrs[FaultID.OptionalMethod] = new FaultAttributes(184); faultsAttrs[FaultID.ImportType] = new FaultAttributes(185); faultsAttrs[FaultID.DynamicCtorCall] = new FaultAttributes(186); faultsAttrs[FaultID.MathPow] = new FaultAttributes(187); +faultsAttrs[FaultID.InvalidAbstractOverrideReturnType] = new FaultAttributes(188); faultsAttrs[FaultID.NumericSemantics] = new FaultAttributes(189); faultsAttrs[FaultID.IncompationbleFunctionType] = new FaultAttributes(190); faultsAttrs[FaultID.LimitedStdLibNoASON] = new FaultAttributes(191); @@ -165,6 +174,7 @@ 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.NoSignatureDistinctWithObjectPublicApi] = new FaultAttributes(216); faultsAttrs[FaultID.NoSideEffectImport] = new FaultAttributes(222); faultsAttrs[FaultID.ImportLazyIdentifier] = new FaultAttributes(232); faultsAttrs[FaultID.DynamicImport] = new FaultAttributes(233); @@ -174,6 +184,8 @@ faultsAttrs[FaultID.MethodOverridingField] = new FaultAttributes(236); faultsAttrs[FaultID.NoTuplesArrays] = new FaultAttributes(237); faultsAttrs[FaultID.ClassstaticInitialization] = new FaultAttributes(238); faultsAttrs[FaultID.InvalidIdentifier] = new FaultAttributes(239); +faultsAttrs[FaultID.NoImportJsonFile] = new FaultAttributes(245); +faultsAttrs[FaultID.NoImportNamespaceStarAsVar] = new FaultAttributes(249); faultsAttrs[FaultID.DoubleExclaBindingNotSupported] = new FaultAttributes(251); faultsAttrs[FaultID.DoubleDollarBindingNotSupported] = new FaultAttributes(252); faultsAttrs[FaultID.DollarBindingNotSupported] = new FaultAttributes(253); @@ -184,21 +196,29 @@ faultsAttrs[FaultID.AnimatableExtendDecoratorTransform] = new FaultAttributes(25 faultsAttrs[FaultID.DataObservation] = new FaultAttributes(258); faultsAttrs[FaultID.UIInterfaceImport] = new FaultAttributes(259); faultsAttrs[FaultID.EntryAnnotation] = new FaultAttributes(260); -faultsAttrs[FaultID.PropDecoratorsAndInterfacesAreNotSupported] = new FaultAttributes(261); -faultsAttrs[FaultID.MakeObservedIsNotSupported] = new FaultAttributes(262); +faultsAttrs[FaultID.SdkAbilityLifecycleMonitor] = new FaultAttributes(261); +faultsAttrs[FaultID.MakeObservedCannotObserveCustomClass] = new FaultAttributes(262); faultsAttrs[FaultID.ProvideAnnotation] = new FaultAttributes(263); -faultsAttrs[FaultID.InteropJsObjectUsage] = new FaultAttributes(264); +faultsAttrs[FaultID.FieldTypeMismatch] = new FaultAttributes(264); faultsAttrs[FaultID.InteropJsObjectInheritance] = new FaultAttributes(265); faultsAttrs[FaultID.InteropJsObjectTraverseJsInstance] = new FaultAttributes(266); -faultsAttrs[FaultID.InteropJsObjectCallStaticFunc] = new FaultAttributes(267); +faultsAttrs[FaultID.InteropJsObjectCallStaticFunc] = new FaultAttributes(267, ProblemSeverity.WARNING); faultsAttrs[FaultID.InteropJsObjectConditionJudgment] = new FaultAttributes(268); faultsAttrs[FaultID.InteropJsObjectExpandStaticInstance] = new FaultAttributes(269); faultsAttrs[FaultID.InteropJSFunctionInvoke] = new FaultAttributes(270); -faultsAttrs[FaultID.InteropDynamicImport] = new FaultAttributes(271); -faultsAttrs[FaultID.InteropDynamicImportTs] = new FaultAttributes(272); -faultsAttrs[FaultID.InteropDynamicImportJs] = new FaultAttributes(273); +faultsAttrs[FaultID.DeprecatedProcessApi] = new FaultAttributes(272); +faultsAttrs[FaultID.NumericUnsignedShiftBehaviorChange] = new FaultAttributes(273); faultsAttrs[FaultID.MissingSuperCall] = new FaultAttributes(274); faultsAttrs[FaultID.CustomLayoutNeedAddDecorator] = new FaultAttributes(275); +faultsAttrs[FaultID.InterfaceFieldNotImplemented] = new FaultAttributes(276); +faultsAttrs[FaultID.NoLocalClass] = new FaultAttributes(277); +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.PropNeedCallMethodForDeepCopy] = new FaultAttributes(286); +faultsAttrs[FaultID.NotSupportTupleGenericValidation] = new FaultAttributes(290); faultsAttrs[FaultID.ExplicitFunctionType] = new FaultAttributes(300); faultsAttrs[FaultID.OhmUrlFullPath] = new FaultAttributes(301); faultsAttrs[FaultID.InteropCallObjectParam] = new FaultAttributes(302); @@ -221,7 +241,6 @@ 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); @@ -249,11 +268,20 @@ 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.SdkAbilityAsynchronousLifecycle] = new FaultAttributes(352); +faultsAttrs[FaultID.ObjectLiteralUnionNeedsCast] = new FaultAttributes(353); 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.RepeatDisableVirtualScroll] = new FaultAttributes(360); +faultsAttrs[FaultID.WrappedBuilderGenericNeedArrowFunc] = new FaultAttributes(361); +faultsAttrs[FaultID.WrapBuilderGenericNeedArrowFunc] = new FaultAttributes(362); +faultsAttrs[FaultID.BuilderNodeGenericNoTuple] = new FaultAttributes(363); +faultsAttrs[FaultID.BuilderNodeUpdateNoLiteral] = new FaultAttributes(364); +faultsAttrs[FaultID.BuilderNodeNoNestingBuilderSupported] = new FaultAttributes(365); +faultsAttrs[FaultID.NoESObjectSupport] = new FaultAttributes(366); faultsAttrs[FaultID.NosparseArray] = new FaultAttributes(370); faultsAttrs[FaultID.NoEnumPropAsType] = new FaultAttributes(371); faultsAttrs[FaultID.NoTsLikeSmartType] = new FaultAttributes(372); @@ -263,3 +291,23 @@ faultsAttrs[FaultID.TsLikeCatchType] = new FaultAttributes(375); faultsAttrs[FaultID.NumericBigintCompare] = new FaultAttributes(376); faultsAttrs[FaultID.NondecimalBigint] = new FaultAttributes(377); faultsAttrs[FaultID.UnsupportOperator] = new FaultAttributes(378); +faultsAttrs[FaultID.StateStylesBlockNeedArrowFunc] = new FaultAttributes(381); +faultsAttrs[FaultID.PromiseVoidNeedResolveArg] = new FaultAttributes(382); +faultsAttrs[FaultID.PersistentPropNeedImplementMethod] = new FaultAttributes(391); +faultsAttrs[FaultID.PersistentPropsNeedImplementMethod] = new FaultAttributes(392); +faultsAttrs[FaultID.PersistenceV2ConnectNeedAddParam] = new FaultAttributes(393); +faultsAttrs[FaultID.NoDeprecatedApi] = new FaultAttributes(399); +faultsAttrs[FaultID.SdkCommonApiDeprecated] = new FaultAttributes(400); +faultsAttrs[FaultID.SdkCommonApiWhiteList] = new FaultAttributes(401); +faultsAttrs[FaultID.SdkCommonApiBehaviorChange] = new FaultAttributes(402); +faultsAttrs[FaultID.BuiltinNewCtor] = new FaultAttributes(403); +faultsAttrs[FaultID.UninitializedArrayElements] = new FaultAttributes(404, ProblemSeverity.WARNING); +faultsAttrs[FaultID.BuiltinFinalClass] = new FaultAttributes(405); +faultsAttrs[FaultID.BuiltinNarrowTypes] = new FaultAttributes(406); +faultsAttrs[FaultID.BuiltinDisableApi] = new FaultAttributes(407); +faultsAttrs[FaultID.BuiltinIteratorResultValue] = new FaultAttributes(408); +faultsAttrs[FaultID.OptionalTupleType] = new FaultAttributes(409); +faultsAttrs[FaultID.LargeNumericLiteral] = new FaultAttributes(410); +faultsAttrs[FaultID.InstanceOfFunction] = new FaultAttributes(411); +faultsAttrs[FaultID.unfixedTuple] = new FaultAttributes(412); +faultsAttrs[FaultID.SuperInStaticContext] = new FaultAttributes(413); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 820afd8a222f4ad4e5bcace6d3b68e9815899ce7..5b39e917f8fa448eebe1afc379af4bdc98388996 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -38,8 +38,10 @@ faultDesc[FaultID.UnknownType] = '"unknown" type'; faultDesc[FaultID.ForInStatement] = '"for-In" statements'; faultDesc[FaultID.InOperator] = '"in" operations'; faultDesc[FaultID.FunctionExpression] = 'function expressions'; +faultDesc[FaultID.ParameterType] = 'parameter type'; faultDesc[FaultID.IntersectionType] = 'intersection types and type literals'; faultDesc[FaultID.ObjectTypeLiteral] = 'Object type literals'; +faultDesc[FaultID.ObjectLiteralKeyType] = 'Object literal key types'; faultDesc[FaultID.CommaOperator] = 'comma operator'; faultDesc[FaultID.LimitedReturnTypeInference] = 'Functions with limited return type inference'; faultDesc[FaultID.ClassExpression] = 'Class expressions'; @@ -59,6 +61,7 @@ faultDesc[FaultID.PrivateIdentifier] = 'Private identifiers (with "#" prefix)'; faultDesc[FaultID.LocalFunction] = 'Local function declarations'; faultDesc[FaultID.ConditionalType] = 'Conditional type'; faultDesc[FaultID.MappedType] = 'Mapped type'; +faultDesc[FaultID.NoClassSuperPropReadonly] = 'Readonly property overrides non-readonly parent property'; faultDesc[FaultID.NamespaceAsObject] = 'Namespaces used as objects'; faultDesc[FaultID.ClassAsObject] = faultDesc[FaultID.ClassAsObjectError] = 'Class used as object'; faultDesc[FaultID.NonDeclarationInNamespace] = 'Non-declaration statements in namespaces'; @@ -68,6 +71,8 @@ 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.NoSignatureDistinctWithObjectPublicApi] = + 'Method’s signature in a class/interface must match the public interface of the object.'; faultDesc[FaultID.JsxElement] = 'JSX Elements'; faultDesc[FaultID.EnumMemberNonConstInit] = 'Enum members with non-constant initializer'; faultDesc[FaultID.ImplementsClass] = 'Class type mentioned in "implements" clause'; @@ -79,10 +84,14 @@ faultDesc[FaultID.StructuralIdentity] = 'Use of type structural identity'; faultDesc[FaultID.ExportAssignment] = 'Export assignments (export = ..)'; faultDesc[FaultID.ImportAssignment] = 'Import assignments (import = ..)'; faultDesc[FaultID.GenericCallNoTypeArgs] = 'Generic calls without type arguments'; +faultDesc[FaultID.PrefixUnaryInfinity] = 'Prefix unary infinity'; faultDesc[FaultID.ParameterProperties] = 'Parameter properties in constructor'; faultDesc[FaultID.InstanceofUnsupported] = 'Left-hand side of "instanceof" is wrong'; +faultDesc[FaultID.TemplateStringType] = 'Template string type'; faultDesc[FaultID.ShorthandAmbientModuleDecl] = 'Shorthand ambient module declaration'; +faultDesc[FaultID.LongNumeric] = 'Use long for big numbers'; faultDesc[FaultID.WildcardsInModuleName] = 'Wildcards in module name'; +faultDesc[FaultID.TupleIndex] = 'Non-negative integer index for tuples'; faultDesc[FaultID.UMDModuleDefinition] = 'UMD module definition'; faultDesc[FaultID.NewTarget] = '"new.target" meta-property'; faultDesc[FaultID.DefiniteAssignment] = faultDesc[FaultID.DefiniteAssignmentError] = 'Definite assignment assertion'; @@ -92,6 +101,7 @@ faultDesc[FaultID.UtilityType] = 'Standard Utility types'; faultDesc[FaultID.PropertyDeclOnFunction] = 'Property declaration on function'; faultDesc[FaultID.FunctionApplyCall] = 'Invoking methods of function objects'; faultDesc[FaultID.FunctionBind] = faultDesc[FaultID.FunctionBindError] = 'Invoking methods of function objects'; +faultDesc[FaultID.NoFunctionReturnThis] = 'no function return this'; faultDesc[FaultID.ConstAssertion] = '"as const" assertion'; faultDesc[FaultID.ImportAssertion] = 'Import assertion'; faultDesc[FaultID.SpreadOperator] = 'Spread operation'; @@ -101,7 +111,7 @@ faultDesc[FaultID.NoNeedStdLibSendableContainer] = 'Sendable Containers not supp 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'; @@ -138,6 +148,7 @@ faultDesc[FaultID.OptionalMethod] = 'Optional method'; faultDesc[FaultID.ImportType] = 'Import type syntax'; faultDesc[FaultID.DynamicCtorCall] = 'Dynamic constructor call'; faultDesc[FaultID.MathPow] = 'Exponent call'; +faultDesc[FaultID.InvalidAbstractOverrideReturnType] = 'Missing return type on abstract method'; faultDesc[FaultID.IncompationbleFunctionType] = 'Incompationble function type'; faultDesc[FaultID.VoidOperator] = 'Void operator'; faultDesc[FaultID.ExponentOp] = 'Exponent operation'; @@ -164,16 +175,19 @@ faultDesc[FaultID.MethodOverridingField] = '"Method overriding field" to keep st 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.NotSupportTupleGenericValidation] = 'No Tuple type in Generic'; +faultDesc[FaultID.DeprecatedProcessApi] = 'This process Api no longer supported in ArkTS 1.2'; 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'; faultDesc[FaultID.TaggedTemplates] = 'Tagged template'; faultDesc[FaultID.InvalidIdentifier] = 'Invalid identifiers'; +faultDesc[FaultID.NoImportJsonFile] = 'No import JSON file'; +faultDesc[FaultID.NoImportNamespaceStarAsVar] = 'No import namespace star as var'; 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'; @@ -189,8 +203,10 @@ 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.SdkAbilityLifecycleMonitor] = + 'UIAbility of 1.2 needs to be listened by the new StaticAbilityLifecycleCallback'; faultDesc[FaultID.ProvideAnnotation] = '"@Provide" decorator parameter'; -faultDesc[FaultID.InteropJsObjectUsage] = 'Interop JS object usage'; +faultDesc[FaultID.FieldTypeMismatch] = 'Mismatch field types'; faultDesc[FaultID.InteropJsObjectInheritance] = 'Interop JS class inheritance'; faultDesc[FaultID.InteropJsObjectTraverseJsInstance] = 'Interop JS object traverse usage'; faultDesc[FaultID.InteropJsObjectCallStaticFunc] = 'Interop JS function usage'; @@ -205,9 +221,6 @@ 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.InteropDynamicImport] = 'Interop import await is not allowed'; -faultDesc[FaultID.InteropDynamicImportTs] = 'Interop import await is not allowed'; -faultDesc[FaultID.InteropDynamicImportJs] = 'Interop import await is not allowed'; faultDesc[FaultID.MissingSuperCall] = 'Missing super call with args'; faultDesc[FaultID.InterOpImportJs] = 'No JS import'; faultDesc[FaultID.InteropObjectLiteralAmbiguity] = 'Interop Object Literal ambiguity'; @@ -233,13 +246,14 @@ faultDesc[FaultID.BuiltinNoCtorFunc] = 'Api is not support ctor-signature and ca faultDesc[FaultID.SharedArrayBufferDeprecated] = 'SharedArrayBuffer is not supported'; faultDesc[FaultID.SetCloneListDeprecated] = 'setCloneList is not supported'; faultDesc[FaultID.SetTransferListDeprecated] = 'setTransferList is not supported'; +faultDesc[FaultID.SdkAbilityAsynchronousLifecycle] = '1.2 Void cannot be combined'; +faultDesc[FaultID.ObjectLiteralUnionNeedsCast] = 'Object literals require union member assertion'; 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.PropDecoratorsAndInterfacesAreNotSupported] = 'Prop decorators and interfaces are not supported'; +faultDesc[FaultID.MakeObservedCannotObserveCustomClass] = 'MakeObserved cannot observe custom class'; faultDesc[FaultID.NoEnumPropAsType] = 'No enum prop as type'; faultDesc[FaultID.NoAwaitJsPromise] = 'No await js promise'; faultDesc[FaultID.NosparseArray] = 'No sparse array'; @@ -251,3 +265,37 @@ 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.InterfaceFieldNotImplemented] = 'All fields must be implemented'; +faultDesc[FaultID.NoLocalClass] = 'No local classes'; +faultDesc[FaultID.NumericUnsignedShiftBehaviorChange] = 'No right shift on negative numbers'; +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'; +faultDesc[FaultID.PropNeedCallMethodForDeepCopy] = 'Deep copy needs to call the specific method'; +faultDesc[FaultID.StateStylesBlockNeedArrowFunc] = 'StateStyles needs arrow function block'; +faultDesc[FaultID.PromiseVoidNeedResolveArg] = 'Promiseconstructor only supports using resolve (undefined)'; +faultDesc[FaultID.RepeatDisableVirtualScroll] = '"Repeat" disable default "virtualScroll"'; +faultDesc[FaultID.WrappedBuilderGenericNeedArrowFunc] = 'Generic of "WrappedBuilder" does not support parameter list'; +faultDesc[FaultID.WrapBuilderGenericNeedArrowFunc] = 'Generic of "wrappBuilder" does not support parameter list'; +faultDesc[FaultID.NoDeprecatedApi] = 'ArkUI deprecated api check'; +faultDesc[FaultID.BuilderNodeGenericNoTuple] = 'Generic of "BuilderNode" does not support tuple"'; +faultDesc[FaultID.BuilderNodeUpdateNoLiteral] = '"update" interface of "BuilderNode" cannot pass an object literal'; +faultDesc[FaultID.BuilderNodeNoNestingBuilderSupported] = '"nestingBuilderSupported" is not supported'; +faultDesc[FaultID.NoESObjectSupport] = 'ESObject type cannot be used'; +faultDesc[FaultID.SdkCommonApiDeprecated] = 'ArkUI sdk common deprecated api check'; +faultDesc[FaultID.SdkCommonApiWhiteList] = 'ArkUI sdk common whiteList api check'; +faultDesc[FaultID.SdkCommonApiBehaviorChange] = 'ArkUI sdk common behavior change api check'; +faultDesc[FaultID.PersistentPropNeedImplementMethod] = 'Serialization needs class to implement the specific methods'; +faultDesc[FaultID.PersistentPropsNeedImplementMethod] = 'Serialization needs class to implement the specific methods'; +faultDesc[FaultID.PersistenceV2ConnectNeedAddParam] = 'Serialization needs class to implement the specific methods'; +faultDesc[FaultID.BuiltinNewCtor] = 'Api is not support ctor-signature in builtin'; +faultDesc[FaultID.UninitializedArrayElements] = 'Uninitialized array elements'; +faultDesc[FaultID.BuiltinFinalClass] = 'Not support use class in this APIe'; +faultDesc[FaultID.BuiltinNarrowTypes] = 'Using narrowing of types is not allowed'; +faultDesc[FaultID.BuiltinDisableApi] = 'Disable Api'; +faultDesc[FaultID.BuiltinIteratorResultValue] = 'IteratorResult.value is not supported'; +faultDesc[FaultID.OptionalTupleType] = 'No optional tuple type'; +faultDesc[FaultID.LargeNumericLiteral] = 'Numeric literal exceeds allowed range'; +faultDesc[FaultID.unfixedTuple] = 'No unfixed tuple'; diff --git a/ets2panda/linter/src/lib/HomeCheck.ts b/ets2panda/linter/src/lib/HomeCheck.ts index a60106beda2fe72d28537698cf22b3c781e1575b..6ad5e01ad9d6fa2a490d11c40dbf30f46871eaf6 100644 --- a/ets2panda/linter/src/lib/HomeCheck.ts +++ b/ets2panda/linter/src/lib/HomeCheck.ts @@ -12,3 +12,100 @@ * 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'; +import { shouldProcessFile } from './LinterRunner'; + +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; +} { + let inputFiles = cmdOptions.inputFiles; + let fliesTocheck: string[] = inputFiles; + if (cmdOptions.scanWholeProjectInHomecheck === true) { + fliesTocheck = []; + } + inputFiles = inputFiles.filter((input) => { + return shouldProcessFile(cmdOptions, input); + }); + const languageTags = new Map(); + inputFiles.forEach((file) => { + languageTags.set(path.normalize(file), 2); + }); + 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: fliesTocheck, + 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/LintRunResult.ts b/ets2panda/linter/src/lib/LintRunResult.ts index 3397a3941a433ce685b7daca2e52ca52e2b2d678..9c1519d077c3a1140e0aa1df077ae0a1d205ea7f 100644 --- a/ets2panda/linter/src/lib/LintRunResult.ts +++ b/ets2panda/linter/src/lib/LintRunResult.ts @@ -15,9 +15,11 @@ import type { ProblemInfo } from './ProblemInfo'; import type { ProjectStatistics } from './statistics/ProjectStatistics'; +import type { TimeRecorder } from './statistics/scan/TimeRecorder'; export interface LintRunResult { hasErrors: boolean; problemsInfos: Map; projectStats: ProjectStatistics; + timeRecorder?: TimeRecorder; } diff --git a/ets2panda/linter/src/lib/LinterInputInfo.ts b/ets2panda/linter/src/lib/LinterInputInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..1cfe8f05ff1c4fe5f7a25a8ba3ccd2ee2e963627 --- /dev/null +++ b/ets2panda/linter/src/lib/LinterInputInfo.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 type * as ts from 'typescript'; +import type { LinterOptions } from './LinterOptions'; +import type { MigrationInfo } from './progress/MigrationInfo'; +import type { CmdProgressInfo } from './progress/CmdProgressInfo'; + +export interface LinterInputInfo { + tsProgram: ts.Program; + srcFiles: ts.SourceFile[]; + options: LinterOptions; + tscStrictDiagnostics: Map; + migrationInfo?: MigrationInfo; + cmdProgressInfo: CmdProgressInfo; +} diff --git a/ets2panda/linter/src/lib/LinterOptions.ts b/ets2panda/linter/src/lib/LinterOptions.ts index f6124ac4ab079343ddac9223baed63f1b58d53ca..8c23b2cc48c88ccd3446bd93f0e1c25079f243af 100644 --- a/ets2panda/linter/src/lib/LinterOptions.ts +++ b/ets2panda/linter/src/lib/LinterOptions.ts @@ -44,5 +44,10 @@ export interface LinterOptions { noMigrationBackupFile?: boolean; migrationReport?: boolean; wholeProjectPath?: string; + projectFolderList?: string[]; checkTsAndJs?: boolean; + inputFiles?: string[]; + ruleConfigTags?: Set; + autofixCheck?: boolean; + autofixRuleConfigTags?: Set; } diff --git a/ets2panda/linter/src/lib/LinterRunner.ts b/ets2panda/linter/src/lib/LinterRunner.ts index 532cea2ccadd4e48799cd479f582637d1040d9f5..cab8af9115e7430133fbe2ebee4ba1d1327e9d9a 100644 --- a/ets2panda/linter/src/lib/LinterRunner.ts +++ b/ets2panda/linter/src/lib/LinterRunner.ts @@ -16,6 +16,8 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; +import * as qEd from './autofixes/QuasiEditor'; +import type { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; import type { CommandLineOptions } from './CommandLineOptions'; import { InteropTypescriptLinter } from './InteropTypescriptLinter'; import type { LinterConfig } from './LinterConfig'; @@ -23,26 +25,41 @@ import type { LinterOptions } from './LinterOptions'; import type { LintRunResult } from './LintRunResult'; import { Logger } from './Logger'; import type { ProblemInfo } from './ProblemInfo'; -import { TypeScriptLinter } from './TypeScriptLinter'; +import type { CmdProgressInfo } from './progress/CmdProgressInfo'; +import { + FixedLineProgressBar, + postProcessCmdProgressBar, + preProcessCmdProgressBar, + processCmdProgressBar +} from './progress/FixedLineProgressBar'; +import type { MigrationInfo } from './progress/MigrationInfo'; +import type { ProgressBarInfo } from './progress/ProgressBarInfo'; +import { ProjectStatistics } from './statistics/ProjectStatistics'; +import { generateMigrationStatisicsReport } from './statistics/scan/ProblemStatisticsCommonFunction'; +import type { TimeRecorder } from './statistics/scan/TimeRecorder'; +import type { createProgramCallback } from './ts-compiler/Compiler'; +import { compileLintOptions } from './ts-compiler/Compiler'; import { getTscDiagnostics } from './ts-diagnostics/GetTscDiagnostics'; import { transformTscDiagnostics } from './ts-diagnostics/TransformTscDiagnostics'; +import { TypeScriptLinter } from './TypeScriptLinter'; import { ARKTS_IGNORE_DIRS_NO_OH_MODULES, ARKTS_IGNORE_DIRS_OH_MODULES, ARKTS_IGNORE_FILES } from './utils/consts/ArktsIgnorePaths'; -import { EXTNAME_TS, EXTNAME_JS } from './utils/consts/ExtensionName'; +import { EXTNAME_JS, EXTNAME_TS } from './utils/consts/ExtensionName'; +import { USE_STATIC } from './utils/consts/InteropAPI'; +import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { clearPathHelperCache, pathContainsDirectory } from './utils/functions/PathHelper'; -import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; -import type { createProgramCallback } from './ts-compiler/Compiler'; -import { compileLintOptions } from './ts-compiler/Compiler'; -import * as qEd from './autofixes/QuasiEditor'; -import { ProjectStatistics } from './statistics/ProjectStatistics'; -import type { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; +import { processSyncErr } from './utils/functions/ProcessWrite'; +import type { LinterInputInfo } from './LinterInputInfo'; +import { collectCommonApiInfo } from './utils/functions/CommonApiInfo'; function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { - let inputFiles = cmdOptions.inputFiles; + let inputFiles = cmdOptions.inputFiles.map((x) => { + return path.normalize(x); + }); if (!cmdOptions.parsedConfigFile) { return inputFiles; } @@ -73,6 +90,7 @@ function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { export function lint( config: LinterConfig, + timeRecorder: TimeRecorder, etsLoaderPath?: string, hcResults?: Map ): LintRunResult { @@ -80,10 +98,13 @@ export function lint( config.cmdOptions.linterOptions.etsLoaderPath = etsLoaderPath; } const lintResult = lintImpl(config); - return config.cmdOptions.linterOptions.migratorMode ? migrate(config, lintResult, hcResults) : lintResult; + timeRecorder.endScan(); + return config.cmdOptions.linterOptions.migratorMode ? + migrate(config, lintResult, timeRecorder, hcResults) : + lintResult; } -function lintImpl(config: LinterConfig): LintRunResult { +function lintImpl(config: LinterConfig, migrationInfo?: MigrationInfo): LintRunResult { const { cmdOptions, tscCompiledProgram } = config; const tsProgram = tscCompiledProgram.getProgram(); const options = cmdOptions.linterOptions; @@ -93,17 +114,19 @@ function lintImpl(config: LinterConfig): LintRunResult { inputFiles = inputFiles.filter((input) => { return shouldProcessFile(options, input); }); + options.inputFiles = inputFiles; const srcFiles: ts.SourceFile[] = []; for (const inputFile of inputFiles) { const srcFile = tsProgram.getSourceFile(inputFile); if (srcFile) { srcFiles.push(srcFile); } + collectCommonApiInfo(tsProgram); } const tscStrictDiagnostics = getTscDiagnostics(tscCompiledProgram, srcFiles); LibraryTypeCallDiagnosticChecker.instance.rebuildTscDiagnostics(tscStrictDiagnostics); - const lintResult = lintFiles(tsProgram, srcFiles, options, tscStrictDiagnostics); + const lintResult = lintFiles(tsProgram, srcFiles, options, tscStrictDiagnostics, migrationInfo); LibraryTypeCallDiagnosticChecker.instance.clear(); if (!options.ideInteractive) { @@ -118,43 +141,108 @@ function lintFiles( tsProgram: ts.Program, srcFiles: ts.SourceFile[], options: LinterOptions, - tscStrictDiagnostics: Map + tscStrictDiagnostics: Map, + migrationInfo?: MigrationInfo ): LintRunResult { - const projectStats: ProjectStatistics = new ProjectStatistics(); - const problemsInfos: Map = new Map(); - TypeScriptLinter.initGlobals(); InteropTypescriptLinter.initGlobals(); + const cmdProgressBar = new FixedLineProgressBar(); + const cmdProgressInfo: CmdProgressInfo = { + cmdProgressBar: cmdProgressBar, + migrationInfo: migrationInfo, + srcFiles: srcFiles, + options: options + }; + + if (options.ideInteractive) { + process.stderr.write('\n'); + preProcessCmdProgressBar(cmdProgressInfo); + } + const linterInputInfo: LinterInputInfo = { + tsProgram: tsProgram, + srcFiles: srcFiles, + options: options, + tscStrictDiagnostics: tscStrictDiagnostics, + migrationInfo: migrationInfo, + cmdProgressInfo: cmdProgressInfo + }; + + const lintResult = executeLinter(linterInputInfo); + if (options.ideInteractive) { + postProcessCmdProgressBar(cmdProgressInfo); + } + return lintResult; +} +function executeLinter(linterInputInfo: LinterInputInfo): LintRunResult { + const { tsProgram, srcFiles, options, tscStrictDiagnostics, migrationInfo, cmdProgressInfo } = linterInputInfo; + const projectStats: ProjectStatistics = new ProjectStatistics(); + const problemsInfos: Map = new Map(); + let fileCount: number = 0; for (const srcFile of srcFiles) { const linter: BaseTypeScriptLinter = !options.interopCheckMode ? new TypeScriptLinter(tsProgram.getTypeChecker(), options, srcFile, tscStrictDiagnostics) : new InteropTypescriptLinter(tsProgram.getTypeChecker(), tsProgram.getCompilerOptions(), options, srcFile); + linter.lint(); const problems = linter.problemsInfos; problemsInfos.set(path.normalize(srcFile.fileName), [...problems]); projectStats.fileStats.push(linter.fileStats); + fileCount += 1; + if (options.ideInteractive) { + processCmdProgressBar(cmdProgressInfo, fileCount); + processIdeProgressBar( + { migrationInfo: migrationInfo, currentSrcFile: srcFile, srcFiles: srcFiles, options: options }, + fileCount + ); + } } - return { hasErrors: projectStats.hasError(), - problemsInfos, - projectStats + problemsInfos: problemsInfos, + projectStats: projectStats }; } +export function processIdeProgressBar(progressBarInfo: ProgressBarInfo, fileCount: number): void { + const { currentSrcFile, srcFiles, options } = progressBarInfo; + + const isMigrationStep = options.migratorMode && progressBarInfo.migrationInfo; + const phasePrefix = isMigrationStep ? 'Migration Phase' : 'Scan Phase'; + + const migrationPhase = isMigrationStep ? + ` ${progressBarInfo.migrationInfo!.currentPass + 1} / ${progressBarInfo.migrationInfo!.maxPasses}` : + ''; + + const progressRatio = fileCount / srcFiles.length; + const displayContent = `currentFile: ${currentSrcFile.fileName}, ${phasePrefix}${migrationPhase}`; + process.stderr.write('\x1B[1F\x1B[0G'); + process.stderr.write('\x1B[2K'); + processSyncErr( + JSON.stringify({ + content: displayContent, + messageType: 1, + indicator: progressRatio + }) + '\n' + ); + process.stderr.write('\x1B[1E'); +} + function migrate( initialConfig: LinterConfig, initialLintResult: LintRunResult, + timeRecorder: TimeRecorder, hcResults?: Map ): LintRunResult { + timeRecorder.startMigration(); 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 migrationMaxPass = cmdOptions.linterOptions.migrationMaxPass ?? qEd.DEFAULT_MAX_AUTOFIX_PASSES; + for (let pass = 0; pass < migrationMaxPass; pass++) { const appliedFix = fix(linterConfig, lintResult, updatedSourceTexts, hcResults); hcResults = undefined; @@ -165,10 +253,44 @@ function migrate( // Re-compile and re-lint project after applying the fixes. linterConfig = compileLintOptions(cmdOptions, getMigrationCreateProgramCallback(updatedSourceTexts)); - lintResult = lintImpl(linterConfig); + lintResult = lintImpl(linterConfig, { currentPass: pass, maxPasses: migrationMaxPass }); } // Write new text for updated source files. + updateSourceFiles(updatedSourceTexts, cmdOptions); + + timeRecorder.endMigration(); + generateMigrationStatisicsReport(lintResult, timeRecorder, cmdOptions.outputFilePath); + + if (cmdOptions.linterOptions.ideInteractive) { + lintResult.problemsInfos = problemsInfosBeforeMigrate; + } + + return lintResult; +} + +function filterLinterProblemsWithAutofixConfig( + cmdOptions: CommandLineOptions, + problemsInfos: Map +): Map { + const autofixRuleConfigTags = cmdOptions.linterOptions.autofixRuleConfigTags; + if (!cmdOptions.linterOptions.ideInteractive || !autofixRuleConfigTags) { + return problemsInfos; + } + + const needToBeFixedProblemsInfos = new Map(); + for (const [filePath, problems] of problemsInfos) { + const needToFix: ProblemInfo[] = problems.filter((problem) => { + return autofixRuleConfigTags.has(problem.ruleTag); + }); + if (needToFix.length > 0) { + needToBeFixedProblemsInfos.set(filePath, needToFix); + } + } + return needToBeFixedProblemsInfos; +} + +function updateSourceFiles(updatedSourceTexts: Map, cmdOptions: CommandLineOptions): void { updatedSourceTexts.forEach((newText, fileName) => { if (!cmdOptions.linterOptions.noMigrationBackupFile) { qEd.QuasiEditor.backupSrcFile(fileName); @@ -177,12 +299,18 @@ function migrate( const writeFileName = filePathMap?.get(fileName) ?? fileName; fs.writeFileSync(writeFileName, newText); }); +} - if (cmdOptions.linterOptions.ideInteractive) { - lintResult.problemsInfos = problemsInfosBeforeMigrate; +function hasUseStaticDirective(srcFile: ts.SourceFile): boolean { + if (!srcFile?.statements.length) { + return false; } - - return lintResult; + const statements = srcFile.statements; + return ( + ts.isExpressionStatement(statements[0]) && + ts.isStringLiteral(statements[0].expression) && + statements[0].expression.getText() === USE_STATIC + ); } function fix( @@ -193,31 +321,41 @@ function fix( ): 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); - } - } - } + // Apply homecheck fixes first to avoid them being skipped due to conflict with linter autofixes + let mergedProblems: Map = hcResults ?? new Map(); + mergedProblems = mergeArrayMaps( + mergedProblems, + filterLinterProblemsWithAutofixConfig(linterConfig.cmdOptions, lintResult.problemsInfos) + ); mergedProblems.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}`); + if (!linterConfig.cmdOptions.homecheck) { + Logger.error(`Failed to retrieve source file: ${fileName}`); + } return; } - - const qe: qEd.QuasiEditor = new qEd.QuasiEditor(fileName, srcFile.text, linterConfig.cmdOptions.linterOptions); - updatedSourceTexts.set(fileName, qe.fix(problemInfos)); - appliedFix = true; + const needToAddUseStatic = + linterConfig.cmdOptions.linterOptions.arkts2 && + linterConfig.cmdOptions.inputFiles.includes(fileName) && + !hasUseStaticDirective(srcFile) && + linterConfig.cmdOptions.linterOptions.ideInteractive && + !qEd.QuasiEditor.hasAnyAutofixes(problemInfos); + // If nothing to fix or don't need to add 'use static', then skip file + if (!qEd.QuasiEditor.hasAnyAutofixes(problemInfos) && !needToAddUseStatic) { + return; + } + const qe: qEd.QuasiEditor = new qEd.QuasiEditor( + fileName, + srcFile.text, + linterConfig.cmdOptions.linterOptions, + undefined, + linterConfig.cmdOptions.outputFilePath + ); + updatedSourceTexts.set(fileName, qe.fix(problemInfos, needToAddUseStatic)); + if (!needToAddUseStatic) { + appliedFix = true; + } }); return appliedFix; @@ -236,7 +374,7 @@ function getMigrationCreateProgramCallback(updatedSourceTexts: Map; -} -interface InterfaceSymbolTypePropertyNames { - propertyNames: string[]; - typeNames: string[]; -} +import type { ArrayAccess, UncheckedIdentifier } from './utils/consts/RuntimeCheckAPI'; +import { NUMBER_LITERAL, LENGTH_IDENTIFIER } from './utils/consts/RuntimeCheckAPI'; +import { globalApiAssociatedInfo } from './utils/consts/AssociatedInfo'; +import { ARRAY_API_LIST } from './utils/consts/ArraysAPI'; +import { + ABILITY_KIT, + ASYNC_LIFECYCLE_SDK_LIST, + ON_DESTROY, + ON_DISCONNECT, + PROMISE, + SERVICE_EXTENSION_ABILITY, + VOID, + ABILITY_LIFECYCLE_SDK +} from './utils/consts/AsyncLifecycleSDK'; +import { ERROR_PROP_LIST } from './utils/consts/ErrorProp'; +import { ETS, D_ETS, D_TS } from './utils/consts/TsSuffix'; +import { arkTsBuiltInTypeName } from './utils/consts/ArkuiImportList'; +import { ERROR_TASKPOOL_PROP_LIST } from './utils/consts/ErrorProp'; +import { COMMON_UNION_MEMBER_ACCESS_WHITELIST } from './utils/consts/ArktsWhiteApiPaths'; +import type { BaseClassConstructorInfo, ConstructorParameter, ExtendedIdentifierInfo } from './utils/consts/Types'; +import { ExtendedIdentifierType } from './utils/consts/Types'; +import { COMPONENT_DECORATOR, SELECT_IDENTIFIER, SELECT_OPTIONS, STRING_ERROR_LITERAL } from './utils/consts/Literals'; +import { ES_OBJECT } from './utils/consts/ESObject'; +import { cookBookMsg } from './CookBookMsg'; +import { getCommonApiInfoMap } from './utils/functions/CommonApiInfo'; export class TypeScriptLinter extends BaseTypeScriptLinter { supportedStdCallApiChecker: SupportedStdCallApiChecker; @@ -157,26 +240,48 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { static nameSpaceFunctionCache: Map>; private readonly constVariableInitCache: Map = new Map(); static funcMap: Map>> = new Map>>(); + static sdkCommonFuncMap: Map>>; private interfaceMap: Map> = new Map>(); static pathMap: Map>; static indexedTypeSet: Set; static globalApiInfo: Map>; + static builtApiInfo: Set; + static builtinNewCtorSet: Set; + static builtinFinalClassSet: Set; + static deprecatedApiInfo: Set; + static sdkCommonApiInfo: Set; + static sdkCommonSymbotIterSet: Set; + static sdkCommonAllDeprecatedTypeNameSet: Set; + static sdkCommonIndexClassSet: Map; static symbotIterSet: Set; static missingAttributeSet: Set; static literalAsPropertyNameTypeSet: Set; private localApiListItem: ApiListItem | undefined = undefined; + static constructorFuncsSet: Set; + static ConstructorIfaceSet: Set; static initGlobals(): void { TypeScriptLinter.sharedModulesCache = new Map(); TypeScriptLinter.nameSpaceFunctionCache = new Map>(); TypeScriptLinter.pathMap = new Map>(); TypeScriptLinter.globalApiInfo = new Map>(); + TypeScriptLinter.builtApiInfo = new Set(); + TypeScriptLinter.builtinNewCtorSet = new Set(); + TypeScriptLinter.builtinFinalClassSet = new Set(); + TypeScriptLinter.deprecatedApiInfo = new Set(); + TypeScriptLinter.sdkCommonApiInfo = new Set(); TypeScriptLinter.funcMap = new Map>>(); + TypeScriptLinter.sdkCommonFuncMap = new Map>>(); TypeScriptLinter.symbotIterSet = new Set(); + TypeScriptLinter.sdkCommonSymbotIterSet = new Set(); + TypeScriptLinter.sdkCommonAllDeprecatedTypeNameSet = new Set(); + TypeScriptLinter.sdkCommonIndexClassSet = new Map(); TypeScriptLinter.missingAttributeSet = new Set(); TypeScriptLinter.initSdkWhitelist(); TypeScriptLinter.initSdkBuiltinInfo(); TypeScriptLinter.initBuiltinlist(); + TypeScriptLinter.initDeprecatedApiList(); + TypeScriptLinter.initSdkCommonApilist(); } initSdkInfo(): void { @@ -197,6 +302,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { case BuiltinProblem.LimitedThisArg: TypeScriptLinter.initSdkBuiltinThisArgsWhitelist(item); break; + case BuiltinProblem.BuiltinNewCtor: + TypeScriptLinter.builtinNewCtorSet.add(item); + break; + case BuiltinProblem.BuiltinFinalClass: + TypeScriptLinter.builtinFinalClassSet.add(item); + break; default: } } @@ -240,6 +351,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private static addSdkConstructorFuncsSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.ConstructorFuncs) { + TypeScriptLinter.constructorFuncsSet.add(item); + } + } + private static addGlobalApiInfosCollocetionData(item: ApiListItem): void { const problemType = item.api_info.problem; const isGlobal = item.is_global; @@ -252,10 +369,18 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private static addSdkConstructorIfaceSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.ConstructorIface) { + TypeScriptLinter.ConstructorIfaceSet.add(item); + } + } + private static initSdkWhitelist(): void { TypeScriptLinter.indexedTypeSet = new Set(); TypeScriptLinter.literalAsPropertyNameTypeSet = new Set(); + TypeScriptLinter.constructorFuncsSet = new Set(); const list: ApiList = new ApiList(apiWhiteList); + TypeScriptLinter.ConstructorIfaceSet = new Set(); if (list?.api_list?.length > 0) { for (const item of list.api_list) { if (item.file_path !== '') { @@ -266,7 +391,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); TypeScriptLinter.addSdkIndexedTypeSetData(item); TypeScriptLinter.addSdkliteralAsPropertyNameTypeSetData(item); + TypeScriptLinter.addSdkConstructorFuncsSetData(item); TypeScriptLinter.addGlobalApiInfosCollocetionData(item); + TypeScriptLinter.addSdkConstructorIfaceSetData(item); } } } @@ -275,11 +402,56 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const list: ApiList = new ApiList(builtinWhiteList); if (list?.api_list?.length > 0) { for (const item of list.api_list) { + this.builtApiInfo.add(item); TypeScriptLinter.addGlobalApiInfosCollocetionData(item); } } } + private static initSdkCommonApilist(): void { + const list: ApiList = new ApiList(sdkCommonList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + const parent_api_name = item.api_info.parent_api[0].api_name; + if (item.api_info.problem === BuiltinProblem.LimitedThisArg) { + TypeScriptLinter.initSdkCommonThisArgsWhitelist(item); + } else if (item.api_info.api_name === SDK_COMMON_SYMBOL_ITERATOR_APINAME) { + TypeScriptLinter.sdkCommonSymbotIterSet.add(item); + } else if (sdkCommonAllDeprecatedTypeName.has(parent_api_name)) { + TypeScriptLinter.sdkCommonAllDeprecatedTypeNameSet.add(item); + } else { + this.sdkCommonApiInfo.add(item); + if (SDK_COMMON_INDEX_CLASS.has(parent_api_name)) { + const combinedPaths = [...item.import_path, item.file_path]; + TypeScriptLinter.sdkCommonIndexClassSet.set(parent_api_name, combinedPaths); + } + } + } + } + } + + static initSdkCommonThisArgsWhitelist(item: ApiListItem): void { + if (item.file_path === '' || !item.api_info.api_name || item.api_info.parent_api?.length <= 0) { + return; + } + const key = item.api_info.api_name + '_' + item.api_info.parent_api[0].api_name; + let funcApiInfos: Map> | undefined = TypeScriptLinter.sdkCommonFuncMap.get(key); + if (!funcApiInfos) { + funcApiInfos = new Map>(); + TypeScriptLinter.sdkCommonFuncMap.set(key, funcApiInfos); + } + TypeScriptLinter.addOrUpdateData(funcApiInfos, path.basename(item.file_path), item.api_info); + } + + private static initDeprecatedApiList(): void { + const list: ApiList = new ApiList(deprecatedApiList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + this.deprecatedApiInfo.add(item); + } + } + } + private static addOrUpdateData(map: Map>, path: string, data: ApiInfo): void { let apiInfos = map.get(path); if (!apiInfos) { @@ -315,7 +487,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { [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], @@ -337,6 +508,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { [ts.SyntaxKind.TypeAssertionExpression, this.handleTypeAssertionExpression], [ts.SyntaxKind.MethodDeclaration, this.handleMethodDeclaration], [ts.SyntaxKind.TupleType, this.handleTupleType], + [ts.SyntaxKind.TemplateLiteralType, this.handleTemplateType], [ts.SyntaxKind.MethodSignature, this.handleMethodSignature], [ts.SyntaxKind.ClassStaticBlockDeclaration, this.handleClassStaticBlockDeclaration], [ts.SyntaxKind.Identifier, this.handleIdentifier], @@ -381,7 +553,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { [ts.SyntaxKind.TypeOfExpression, this.handleInterOpImportJsOnTypeOfNode], [ts.SyntaxKind.AwaitExpression, this.handleAwaitExpression], [ts.SyntaxKind.PostfixUnaryExpression, this.handlePostfixUnaryExpression], - [ts.SyntaxKind.BigIntLiteral, this.handleBigIntLiteral] + [ts.SyntaxKind.BigIntLiteral, this.handleBigIntLiteral], + [ts.SyntaxKind.NumericLiteral, this.handleNumericLiteral], + [ts.SyntaxKind.RestType, this.handleRestType], + [ts.SyntaxKind.SuperKeyword, this.handleSuperKeyword] ]); lint(): void { @@ -389,7 +564,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.autofixer = new Autofixer(this.tsTypeChecker, this.tsUtils, this.sourceFile, this.options.cancellationToken); } - this.useStatic = TsUtils.isArkts12File(this.sourceFile); + this.useStatic = this.tsUtils.isArkts12File(this.sourceFile); this.fileExportDeclCaches = undefined; this.extractImportedNames(this.sourceFile); this.visitSourceFile(this.sourceFile); @@ -565,6 +740,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const objectLiteralType = this.tsTypeChecker.getContextualType(objectLiteralExpr); + if (objectLiteralType && this.options.arkts2) { + this.isObjectLiteralKeyTypeValid(objectLiteralExpr, objectLiteralType); + } + if (objectLiteralType && this.tsUtils.typeContainsSendableClassOrInterface(objectLiteralType)) { this.incrementCounters(node, FaultID.SendableObjectInitialization); } else if ( @@ -582,13 +761,24 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + static ifValidObjectLiteralProperty( + prop: ts.ObjectLiteralElementLike, + objLitExpr: ts.ObjectLiteralExpression + ): boolean { + return ( + ts.isPropertyAssignment(prop) || + ts.isShorthandPropertyAssignment(prop) && + (ts.isCallExpression(objLitExpr.parent) || ts.isNewExpression(objLitExpr.parent)) + ); + } + private handleObjectLiteralProperties( objectLiteralType: ts.Type | undefined, objectLiteralExpr: ts.ObjectLiteralExpression ): void { let objLiteralAutofix: Autofix[] | undefined; const invalidProps = objectLiteralExpr.properties.filter((prop) => { - return !ts.isPropertyAssignment(prop); + return !TypeScriptLinter.ifValidObjectLiteralProperty(prop, objectLiteralExpr); }); if ( @@ -600,11 +790,43 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } for (const prop of invalidProps) { - const autofix = ts.isShorthandPropertyAssignment(prop) ? - this.autofixer?.fixShorthandPropertyAssignment(prop) : - objLiteralAutofix; - this.incrementCounters(prop, FaultID.ObjectLiteralProperty, autofix); + if (objectLiteralType) { + const typeDecl = TsUtils.getDeclaration(objectLiteralType.getSymbol()); + if (typeDecl && ts.isInterfaceDeclaration(typeDecl) && ts.isMethodDeclaration(prop)) { + continue; + } + } + if (ts.isShorthandPropertyAssignment(prop)) { + if (this.checkShorthandInObjectLiteral(prop, objectLiteralType)) { + const autofix = this.autofixer?.fixShorthandPropertyAssignment(prop); + this.incrementCounters(prop, FaultID.ObjectLiteralProperty, autofix); + } + } else { + this.incrementCounters(prop, FaultID.ObjectLiteralProperty, objLiteralAutofix); + } + } + } + + private checkShorthandInObjectLiteral(prop: ts.ShorthandPropertyAssignment, type: ts.Type | undefined): boolean { + if (!type) { + return true; } + const propName = prop.name.text; + const expectedProp = type.getProperty(propName); + if (!expectedProp) { + return false; + } + const expectedPropType = this.tsTypeChecker.getTypeOfSymbolAtLocation(expectedProp, prop.name); + const symbol = this.tsTypeChecker.getSymbolAtLocation(prop.name); + const varDecl = symbol?.valueDeclaration; + if (!varDecl) { + return false; + } + const actualType = this.tsTypeChecker.getTypeAtLocation(varDecl); + if (!this.isTypeAssignable(actualType, expectedPropType)) { + return true; + } + return false; } private handleArrayLiteralExpression(node: ts.Node): void { @@ -617,19 +839,40 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } const arrayLitNode = node as ts.ArrayLiteralExpression; - let emptyContextTypeForArrayLiteral = false; - const arrayLitType = this.tsTypeChecker.getContextualType(arrayLitNode); if (arrayLitType && this.tsUtils.typeContainsSendableClassOrInterface(arrayLitType)) { this.incrementCounters(node, FaultID.SendableObjectInitialization); return; } + this.checkArrayElementsAndReportErrors(node, arrayLitNode, arrayLitType); + this.handleObjectLiteralAssignmentToClass(arrayLitNode); + } + + private checkArrayElementsAndReportErrors( + node: ts.Node, + arrayLitNode: ts.ArrayLiteralExpression, + arrayLitType: undefined | ts.Type + ): void { + const parent = arrayLitNode.parent; + const arrayLitElements = arrayLitNode.elements; + const arrayElementIsEmpty = arrayLitElements.length === 0; + /* * check that array literal consists of inferrable types * e.g. there is no element which is untyped object literals */ - const arrayLitElements = arrayLitNode.elements; + const isCallExpression = this.checkMethodCallForSparseArray(parent); + const isTypedArrayOrBuiltInConstructor = TypeScriptLinter.checkTypedArrayOrBuiltInConstructor(parent); + if (this.options.arkts2 && arrayElementIsEmpty) { + if (!arrayLitType) { + this.incrementCounters(node, FaultID.NosparseArray); + } else if (isCallExpression || isTypedArrayOrBuiltInConstructor) { + this.incrementCounters(arrayLitNode, FaultID.NosparseArray); + } + } + + let emptyContextTypeForArrayLiteral = false; for (const element of arrayLitElements) { const elementContextType = this.tsTypeChecker.getContextualType(element); if (ts.isObjectLiteralExpression(element)) { @@ -653,6 +896,59 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private static checkTypedArrayOrBuiltInConstructor(parent: ts.Node): boolean { + if (!ts.isNewExpression(parent)) { + return false; + } + const newExpr = parent; + const typeName = newExpr.expression.getText(); + + return TYPED_ARRAYS.includes(typeName) || BUILTIN_CONSTRUCTORS.includes(typeName); + } + + private checkMethodCallForSparseArray(parent: ts.Node): boolean { + if (!ts.isCallExpression(parent)) { + return false; + } + + const callExpr = parent; + const promiseMethodName = TypeScriptLinter.getPromiseMethodName(callExpr.expression); + if (promiseMethodName && PROMISE_METHODS.has(promiseMethodName)) { + return true; + } + + const collectionMethodName = this.getCollectionMethodName(callExpr.expression); + if (collectionMethodName && COLLECTION_METHODS.has(collectionMethodName)) { + return true; + } + + return false; + } + + private getCollectionMethodName(node: ts.Expression): string | undefined { + if (!ts.isPropertyAccessExpression(node)) { + return undefined; + } + + const expr = node.expression; + if (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr)) { + const type = this.tsTypeChecker.getTypeAtLocation(expr); + const typeName = type.symbol?.getName(); + if (typeName && COLLECTION_TYPES.has(typeName)) { + return node.name.text; + } + } + + return undefined; + } + + private static getPromiseMethodName(node: ts.Expression): string | undefined { + if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'Promise') { + return node.name.text; + } + return undefined; + } + private handleStructDeclaration(node: ts.StructDeclaration): void { if (!this.options.arkts2) { return; @@ -668,10 +964,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); this.handleDeclarationDestructuring(tsParam); this.handleDeclarationInferredType(tsParam); - this.handleInvalidIdentifier(tsParam); - this.handleSdkDuplicateDeclName(tsParam); + if (!ts.isArrowFunction(node.parent)) { + this.handleInvalidIdentifier(tsParam); + } + this.handleSdkGlobalApi(tsParam); const typeNode = tsParam.type; - if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { + if (this.options.arkts2 && typeNode && TsUtils.typeContainsVoid(typeNode)) { this.incrementCounters(typeNode, FaultID.LimitedVoidType); } this.handlePropertyDescriptorInScenarios(tsParam); @@ -750,6 +1048,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.interfaceInheritanceLint(node, interfaceNode.heritageClauses); } this.countDeclarationsWithDuplicateName(interfaceNode.name, interfaceNode); + this.handleLocalDeclarationOfClassAndIface(interfaceNode); + this.checkObjectPublicApiMethods(interfaceNode); } private handleTryStatement(node: ts.TryStatement): void { @@ -899,78 +1199,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const tsForStmt = node as ts.ForStatement; const tsForInit = tsForStmt.initializer; if (tsForInit) { - this.checkStaticArrayControl(tsForStmt); this.checkForLoopDestructuring(tsForInit); } } - private checkStaticArrayControl(tsForStmt: ts.ForStatement): void { - if (!this.options.arkts2 || !this.useStatic) { - return; - } - - if (!ts.isBlock(tsForStmt.statement)) { - return; - } - - const loopBody = tsForStmt.statement; - const arrayAccessInfo = this.checkBodyHasArrayAccess(loopBody); - const loopCondition = tsForStmt.condition; - - if (!arrayAccessInfo) { - return; - } - if (!loopCondition) { - this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); - return; - } - const arraySymbol = this.tsUtils.trueSymbolAtLocation(arrayAccessInfo.arrayIdent); - if (!arraySymbol) { - return; - } - - const arrayCheckedAgainst = this.checkConditionForArrayAccess(loopCondition, arraySymbol); - if (!arrayCheckedAgainst) { - this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); - return; - } - - this.checkIfAccessAndCheckVariablesMatch(arrayAccessInfo, arrayCheckedAgainst); - } - - 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; - } - - if (checkedAgainst === NUMBER_LITERAL) { - this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); - return; - } - - const checkedAgainstSym = this.tsUtils.trueSymbolAtLocation(checkedAgainst); - if (!checkedAgainstSym) { - return; - } - - const accessingIdentSym = this.tsUtils.trueSymbolAtLocation(accessingIdentifier); - - if (checkedAgainstSym !== accessingIdentSym) { - this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); - return; - } - - if (this.isChangedAfterCheck(arrayIdent.getSourceFile(), checkedAgainstSym)) { - this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); - } - } - private checkConditionForArrayAccess(condition: ts.Expression, arraySymbol: ts.Symbol): UncheckedIdentifier { if (!ts.isBinaryExpression(condition)) { return undefined; @@ -1034,81 +1266,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return arrayAccessResult; } - private checkArrayUsageWithoutBound(accessExpr: ts.ElementAccessExpression): void { - if (!this.options.arkts2 || !this.useStatic) { - return; - } - - const arrayAccessInfo = this.isElementAccessOfArray(accessExpr); - if (!arrayAccessInfo) { - return; - } - - const { arrayIdent } = arrayAccessInfo; - const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); - if (!arraySym) { - return; - } - const sourceFile = arrayIdent.getSourceFile(); - - for (const statement of sourceFile.statements) { - if (this.checkStatementForArrayAccess(statement, arrayAccessInfo, arraySym) === CheckResult.SKIP) { - continue; - } - } - } - - private checkStatementForArrayAccess( - statement: ts.Statement, - accessInfo: ArrayAccess, - arraySym: ts.Symbol - ): CheckResult { - if (!ts.isIfStatement(statement)) { - return CheckResult.SKIP; - } - - if (this.checkBodyHasArrayAccess(statement.thenStatement as ts.Block) !== undefined) { - return CheckResult.SKIP; - } - - const checkedAgainst = this.checkConditionForArrayAccess(statement.expression, arraySym); - if (!checkedAgainst) { - return CheckResult.SKIP; - } - - this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); - return CheckResult.CHECKED; - } - - private isChangedAfterCheck(sourceFile: ts.SourceFile, sym: ts.Symbol): boolean { - for (const statement of sourceFile.statements) { - if (!ts.isExpressionStatement(statement)) { - continue; - } - if (!ts.isBinaryExpression(statement.expression)) { - continue; - } - if (!ts.isIdentifier(statement.expression.left)) { - continue; - } - if (statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { - continue; - } - - const leftSym = this.tsUtils.trueSymbolAtLocation(statement.expression.left); - if (!leftSym) { - continue; - } - - if (leftSym === sym) { - return true; - } - continue; - } - - return false; - } - private handleForInStatement(node: ts.Node): void { const tsForInStmt = node as ts.ForInStatement; const tsForInInit = tsForInStmt.initializer; @@ -1120,41 +1277,21 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const tsForOfStmt = node as ts.ForOfStatement; const tsForOfInit = tsForOfStmt.initializer; this.checkForLoopDestructuring(tsForOfInit); + this.handleForOfJsArray(tsForOfStmt); } - private handleIfStatement(ifStatement: ts.IfStatement): void { - if (this.options.arkts2 && this.useStatic) { - this.checkIfStatementForArrayUsage(ifStatement); - } - } - - 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) { + private updateDataSdkJsonInfo(importDeclNode: ts.ImportDeclaration, importClause: ts.ImportClause): void { + const sdkInfo = TypeScriptLinter.pathMap.get(importDeclNode.moduleSpecifier.getText()); + if (!sdkInfo) { return; } - - const checkedAgainst = this.checkConditionForArrayAccess(ifStatement.expression, arraySymbol); - if (!checkedAgainst) { - return; + if (importClause.name) { + const importClauseName = importClause.name.text; + sdkInfo.forEach((info) => { + TypeScriptLinter.addOrUpdateData(this.interfaceMap, importClauseName, info); + }); } - - this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); - } - - private updateDataSdkJsonInfo(importDeclNode: ts.ImportDeclaration, importClause: ts.ImportClause): void { - const sdkInfo = TypeScriptLinter.pathMap.get(importDeclNode.moduleSpecifier.getText()); - if (sdkInfo && importClause.namedBindings) { + if (importClause.namedBindings) { const namedImports = importClause.namedBindings as ts.NamedImports; if (!namedImports.elements) { return; @@ -1176,7 +1313,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (this.options.arkts2) { const importClause = importDeclNode.importClause; if (!importClause || !importClause.name && !importClause.namedBindings) { - this.incrementCounters(node, FaultID.NoSideEffectImport); + const autofix = this.autofixer?.fixSideEffectImport(importDeclNode); + this.incrementCounters(node, FaultID.NoSideEffectImport, autofix); } else { this.updateDataSdkJsonInfo(importDeclNode, importClause); } @@ -1208,6 +1346,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkStdLibConcurrencyImport(importDeclNode); this.handleInterOpImportJs(importDeclNode); this.checkForDeprecatedModules(node); + this.checkImportJsonFile(importDeclNode); } private checkForDeprecatedModules(node: ts.Node): void { @@ -1306,45 +1445,35 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } 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); - - if (ts.isCallExpression(node.parent) && node === node.parent.expression) { + const propertyAccessNode = node as ts.PropertyAccessExpression; + this.handlePropertyAccessExpressionForUI(propertyAccessNode); + this.handleQuotedHyphenPropsDeprecated(propertyAccessNode); + this.handleSdkTypeQuery(propertyAccessNode); + this.checkUnionTypes(propertyAccessNode); + this.handleLimitedVoidTypeFromSdkOnPropertyAccessExpression(propertyAccessNode); + this.checkDepricatedIsConcurrent(propertyAccessNode); + this.propertyAccessExpressionForBuiltin(propertyAccessNode); + this.checkConstrutorAccess(propertyAccessNode); + this.handleTaskPoolDeprecatedUsages(propertyAccessNode); + this.handleNoTuplesArraysForPropertyAccessExpression(propertyAccessNode); + this.handleUnsafeOptionalCallComparison(propertyAccessNode); + this.handleNoDeprecatedApi(node as ts.PropertyAccessExpression); + if (ts.isCallExpression(propertyAccessNode.parent) && propertyAccessNode === propertyAccessNode.parent.expression) { return; } - - 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(exprSym, propertyAccessNode); + this.propertyAccessExpressionForInterop(propertyAccessNode); if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } - if ( - !this.options.arkts2 && - !!exprSym && - this.tsUtils.isStdSymbolAPI(exprSym) && - !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName()) - ) { - this.incrementCounters(propertyAccessNode, FaultID.SymbolType); - } + this.checkSymbolAPI(propertyAccessNode, exprSym); if (this.options.advancedClassChecks && this.tsUtils.isClassObjectExpression(propertyAccessNode.expression)) { this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } - if (!!baseExprSym && TsUtils.symbolHasEsObjectType(baseExprSym)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; this.incrementCounters(propertyAccessNode, faultId); } if (TsUtils.isSendableFunction(baseExprType) || this.tsUtils.hasSendableTypeAlias(baseExprType)) { @@ -1353,35 +1482,100 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkFunctionProperty(propertyAccessNode, baseExprSym, baseExprType); this.handleSdkForConstructorFuncs(propertyAccessNode); this.fixJsImportPropertyAccessExpression(node); - this.handleArkTSPropertyAccess(propertyAccessNode); + this.handleBuiltinIteratorResult(propertyAccessNode); } - propertyAccessExpressionForBuiltin(decl: ts.PropertyAccessExpression): void { - if (this.options.arkts2) { - this.handleSymbolIterator(decl); - this.handleGetOwnPropertyNames(decl); - } + private handlePropertyAccessExpressionForUI(node: ts.PropertyAccessExpression): void { + this.handleMakeObserved(node); + this.handleStateStyles(node); + this.handleDoubleDollar(node); + this.handlePropertyAccessExprForBuilderNode(node); } - propertyAccessExpressionForInterop( - exprSym: ts.Symbol | undefined, - propertyAccessNode: ts.PropertyAccessExpression - ): void { - if (this.useStatic && this.options.arkts2) { - const declaration = exprSym?.declarations?.[0]; - if (declaration?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - 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); + private checkSymbolAPI(node: ts.PropertyAccessExpression, exprSym: ts.Symbol | undefined): void { + if ( + !this.options.arkts2 && + !!exprSym && + this.tsUtils.isStdSymbolAPI(exprSym) && + !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName()) + ) { + this.incrementCounters(node, FaultID.SymbolType); + } + } + + propertyAccessExpressionForBuiltin(decl: ts.PropertyAccessExpression): void { + if (this.options.arkts2) { + this.handleSymbolIterator(decl); + this.handleGetOwnPropertyNames(decl); + this.handlePropertyDescriptorInScenarios(decl); + } + } + + private isJsRelated(node: ts.Expression): boolean { + if (this.tsUtils.isJsImport(node)) { + return true; + } + + if (ts.isNewExpression(node)) { + return this.tsUtils.isJsImport(node.expression); + } + + if (ts.isIdentifier(node)) { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + if (!symbol) { + return false; + } + + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return false; + } + + for (const declaration of declarations) { + if (ts.isVariableDeclaration(declaration) && declaration.initializer) { + return this.isJsRelated(declaration.initializer); } } } + + return false; + } + + propertyAccessExpressionForInterop(propertyAccessNode: ts.PropertyAccessExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + + const getFirstObjectNode = (propertyAccessNode: ts.PropertyAccessExpression): ts.Expression => { + let current: ts.Expression = propertyAccessNode.expression; + while (ts.isPropertyAccessExpression(current)) { + current = current.expression; + } + + return current; + }; + + const firstObjNode = getFirstObjectNode(propertyAccessNode); + const isJsObject = this.isJsRelated(firstObjNode); + if (!isJsObject) { + return; + } + + if (ts.isBinaryExpression(propertyAccessNode.parent)) { + const isAssignment = propertyAccessNode.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken; + const autofix = isAssignment ? + this.autofixer?.fixInteropBinaryExpression(propertyAccessNode.parent) : + this.autofixer?.fixInteropPropertyAccessExpression(propertyAccessNode); + + this.incrementCounters( + isAssignment ? propertyAccessNode.parent : propertyAccessNode, + FaultID.InteropObjectProperty, + autofix + ); + } else { + const autofix = this.autofixer?.fixInteropPropertyAccessExpression(propertyAccessNode); + this.incrementCounters(propertyAccessNode, FaultID.InteropObjectProperty, autofix); + } } private checkDepricatedIsConcurrent(node: ts.PropertyAccessExpression): void { @@ -1391,18 +1585,15 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!ts.isCallExpression(node.parent)) { return; } - const methodName = node.name.getText(); if (methodName !== ISCONCURRENT) { return; } - const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); if (!symbol) { return; } - if (symbol.name === TASKPOOL) { const decl = TsUtils.getDeclaration(symbol); @@ -1415,7 +1606,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if ( TASKPOOL_MODULES.some((moduleName) => { - return fileName.startsWith(moduleName); + return fileName.startsWith(moduleName) && (fileName.endsWith(D_TS) || fileName.endsWith(D_ETS)); }) ) { this.incrementCounters(node.name, FaultID.IsConcurrentDeprecated); @@ -1441,76 +1632,247 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private checkInteropForPropertyAccess(pan: ts.PropertyAccessExpression): void { - if (!this.options.arkts2) { - return; + private checkUsageOfTsTypes(baseType: ts.Type, node: ts.Node): void { + const typeString = this.tsTypeChecker.typeToString(baseType); + if ( + TsUtils.isAnyType(baseType) || + TsUtils.isUnknownType(baseType) || + this.tsUtils.isStdFunctionType(baseType) || + typeString === 'symbol' || + this.isMixedEnum(baseType) || + this.isSpecialType(baseType, node) || + this.isStdUtilityTools(node) + ) { + this.incrementCounters(node, FaultID.InteropDirectAccessToTSTypes); } + } - if (!ts.isBinaryExpression(pan.parent)) { - return; + private isSpecialType(baseType: ts.Type, node: ts.Node): boolean { + const baseTypeStr = this.tsTypeChecker.typeToString(baseType); + if (TypeScriptLinter.extractKeyofFromString(baseTypeStr)) { + return true; + } + let symbol = baseType.getSymbol(); + if (!symbol) { + symbol = this.tsUtils.trueSymbolAtLocation(node); + } + const decl = TsUtils.getDeclaration(symbol); + if (!decl) { + return false; + } + if ( + ts.isTypeAliasDeclaration(decl) && this.checkSpecialTypeNode(decl.type, true) || + this.checkSpecialTypeNode(decl, true) + ) { + return true; } - const binaryExpr = pan.parent; - if (binaryExpr.left !== pan) { - return; + if (this.isObjectLiteralExpression(decl)) { + return true; } - if (binaryExpr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { - return; + + if (ts.isFunctionLike(decl)) { + if (decl.type && this.checkIsTypeLiteral(decl.type)) { + return true; + } + const isObjectLiteralExpression = decl.parameters.some((param) => { + return param.type && this.checkIsTypeLiteral(param.type); + }); + if (isObjectLiteralExpression) { + return true; + } + if (TypeScriptLinter.hasObjectLiteralReturn(decl as ts.FunctionLikeDeclaration)) { + return true; + } + } + + return false; + } + + private isMixedEnum(type: ts.Type): boolean { + const symbol = type.getSymbol(); + if (!symbol) { + return false; + } + + const declarations = symbol.getDeclarations(); + if (!declarations) { + return false; } - const rhs = binaryExpr.right; - const lhs = binaryExpr.left as ts.PropertyAccessExpression; + for (const decl of declarations) { + if (ts.isEnumDeclaration(decl)) { + const initializerTypes = new Set(); + + for (const member of decl.members) { + if (member.initializer) { + const memberType = this.tsTypeChecker.getTypeAtLocation(member.initializer); + const baseTypeStr = this.tsTypeChecker.typeToString( + this.tsTypeChecker.getBaseTypeOfLiteralType(memberType) + ); + initializerTypes.add(baseTypeStr); + } + } - const autofix = this.autofixer?.fixInteropTsType(binaryExpr, lhs, rhs); + if (initializerTypes.size > 1) { + return true; + } + } + } - this.incrementCounters(pan, FaultID.InteropDirectAccessToTSTypes, autofix); + return false; } - private checkInteropEqualsBinaryExpression(baseType: ts.Type, binaryExpr: ts.BinaryExpression): void { - if (this.tsUtils.isArray(baseType)) { - return; + private isStdUtilityTools(node: ts.Node): boolean { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + const decl = TsUtils.getDeclaration(symbol); + if (!decl) { + return false; } - if (this.tsUtils.isStringType(baseType)) { - return; + let isStdUtilityType = false; + const utils = this.tsUtils; + function traverse(node: ts.Node): void { + if (isStdUtilityType) { + return; + } + if (ts.isTypeReferenceNode(node) || ts.isExpressionWithTypeArguments(node)) { + let typeName = ''; + if (ts.isTypeReferenceNode(node)) { + typeName = utils.entityNameToString(node.typeName); + } else { + typeName = node.expression.getText(); + } + isStdUtilityType = !!( + LIMITED_STANDARD_UTILITY_TYPES2.includes(typeName) && + node.typeArguments && + node.typeArguments.length > 0 + ); + } + node.forEachChild(traverse); } - if (this.tsUtils.isStdNumberType(baseType)) { - return; + traverse(decl); + return isStdUtilityType; + } + + private checkIsTypeLiteral(node: ts.Node): boolean { + if (ts.isUnionTypeNode(node) || ts.isIntersectionTypeNode(node)) { + return node.types.some((typeNode) => { + return this.checkIsTypeLiteralWithTypeNodes(typeNode); + }); } - if (this.tsUtils.isStdBooleanType(baseType)) { - return; + + return this.checkIsTypeLiteralWithTypeNodes(node); + } + + private checkIsTypeLiteralWithTypeNodes(node: ts.Node): boolean { + if (ts.isTypeLiteralNode(node) && node.members.length > 0) { + return true; + } + + if (ts.isTypeReferenceNode(node) && node.typeName) { + const typeDecl = this.tsUtils.getDeclarationNode(node.typeName); + return ( + typeDecl !== undefined && ts.isTypeAliasDeclaration(typeDecl) && this.checkSpecialTypeNode(typeDecl.type, false) + ); } - this.incrementCounters(binaryExpr, FaultID.InteropDirectAccessToTSTypes); + return false; + } + + private checkSpecialTypeNode(typeNode: ts.Node, isNeedCheckIsTypeLiteral: boolean): boolean { + let specialType = + ts.isIndexedAccessTypeNode(typeNode) || + ts.isConditionalTypeNode(typeNode) || + ts.isFunctionTypeNode(typeNode) || + ts.isMappedTypeNode(typeNode) || + ts.isTemplateLiteralTypeNode(typeNode); + if (isNeedCheckIsTypeLiteral) { + specialType ||= this.checkIsTypeLiteral(typeNode); + } + return specialType; + } + + private isObjectLiteralExpression(decl: ts.Node): boolean { + const isVariableWithInitializer = + ts.isVariableDeclaration(decl) && decl.initializer && ts.isObjectLiteralExpression(decl.initializer); + + const isVariableWithTypeLiteral = ts.isVariableDeclaration(decl) && decl.type && this.checkIsTypeLiteral(decl.type); + const isObjectLiteralExpression = + ts.isObjectLiteralExpression(decl) || + this.checkIsTypeLiteral(decl) || + isVariableWithInitializer || + isVariableWithTypeLiteral; + return !!isObjectLiteralExpression; + } + + private static hasObjectLiteralReturn(funcNode: ts.FunctionLikeDeclaration): boolean { + let found = false; + function visit(node: ts.Node): void { + if (found) { + return; + } + + if (ts.isReturnStatement(node) && node.expression && ts.isObjectLiteralExpression(node.expression)) { + found = true; + return; + } + + ts.forEachChild(node, visit); + } + visit(funcNode); + return found; + } + + private static extractKeyofFromString(typeString: string): boolean { + return (/\bkeyof\b/).test(typeString); } checkUnionTypes(propertyAccessNode: ts.PropertyAccessExpression): void { if (!this.options.arkts2) { return; } + + // Safeguard: only process the outermost property access, not nested chains + if (ts.isPropertyAccessExpression(propertyAccessNode.parent)) { + return; + } + const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (!baseExprType.isUnion()) { + const baseExprSym = baseExprType.aliasSymbol || baseExprType.getSymbol(); + const symbolName = baseExprSym ? baseExprSym.name : this.tsTypeChecker.typeToString(baseExprType); + + if (!baseExprType.isUnion() || COMMON_UNION_MEMBER_ACCESS_WHITELIST.has(symbolName)) { return; } - const allType = baseExprType.types; - const commonPropertyType = allType.filter((type) => { - return this.tsUtils.findProperty(type, propertyAccessNode.name.getText()) !== undefined; + + const allTypes = baseExprType.types; + const propName = propertyAccessNode.name.getText(); + + // Only keep union members that have the property + const typesWithProp = allTypes.filter((type) => { + return this.tsUtils.findProperty(type, propName) !== 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); + + if (typesWithProp.length !== allTypes.length) { + // Not all members have this property, nothing to check + return; + } + + // Extract the type of the property for each member + const propTypes: string[] = []; + for (const t of typesWithProp) { + const propSym = this.tsUtils.findProperty(t, propName); + if (propSym) { + const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(propSym, propertyAccessNode); + propTypes.push(this.tsTypeChecker.typeToString(propType)); } } + + // If there's more than one distinct property type signature, flag it + const distinctPropTypes = new Set(propTypes); + if (distinctPropTypes.size > 1) { + this.incrementCounters(propertyAccessNode, FaultID.AvoidUnionTypes); + } } private handleLiteralAsPropertyName(node: ts.PropertyDeclaration | ts.PropertySignature): void { @@ -1533,7 +1895,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ); const classDecorators = ts.getDecorators(node.parent); const propType = node.type?.getText(); - if (this.options.arkts2 && propType === 'void' && node.type) { + if (this.options.arkts2 && node.type && TsUtils.typeContainsVoid(node.type)) { this.incrementCounters(node.type, FaultID.LimitedVoidType); } this.filterOutDecoratorsDiagnostics( @@ -1545,16 +1907,90 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ); 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.handleSdkGlobalApi(node); + this.handleObjectLiteralAssignmentToClass(node); + this.checkPropertyDeclarationReadonlyUsage(node); + } + + private checkPropertyDeclarationReadonlyUsage(propDecl: ts.PropertyDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const { parent, name } = propDecl; + + if (!ts.isClassDeclaration(parent)) { + return; + } + + if (!parent.heritageClauses) { + return; + } + + const extendedIdent = parent.heritageClauses.at(0); + + if (!TsUtils.hasModifier(propDecl.modifiers, ts.SyntaxKind.ReadonlyKeyword)) { + return; + } + + const extendedProp = this.getExtendedProperty(name, extendedIdent); + if (!extendedProp) { + return; + } + + if (TsUtils.hasModifier(extendedProp.modifiers, ts.SyntaxKind.ReadonlyKeyword)) { + return; + } + + this.incrementCounters(propDecl, FaultID.NoClassSuperPropReadonly); + } + + private getExtendedProperty( + propertyName: ts.PropertyName, + extended: ts.HeritageClause | undefined + ): ts.PropertySignature | undefined { + if (!extended) { + return undefined; + } + + const extendedType = extended.types.at(0); + if (!extendedType) { + return undefined; + } + + const extendedIdent = extendedType.expression; + if (!ts.isIdentifier(extendedIdent)) { + return undefined; + } + + const extendedDeclaration = this.tsUtils.getDeclarationNode(extendedIdent); + if (!extendedDeclaration) { + return undefined; + } + + if (!ts.isInterfaceDeclaration(extendedDeclaration)) { + return undefined; + } + + for (const member of extendedDeclaration.members) { + if (!ts.isPropertySignature(member)) { + continue; + } + if (member.name.getText() !== propertyName.getText()) { + continue; + } + + return member; + } + + return undefined; } private handleSendableClassProperty(node: ts.PropertyDeclaration): void { @@ -1578,10 +2014,19 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handlePropertyAssignment(node: ts.PropertyAssignment): void { this.handleDollarBind(node); + this.handlePropertyAssignmentForProp(node); this.handleQuotedHyphenPropsDeprecated(node); + this.handleNoDeprecatedApi(node); + + if (!this.options.arkts2) { + this.handleLiteralAsPropertyNameForPropertyAssignment(node); + } + } + + private handleLiteralAsPropertyNameForPropertyAssignment(node: ts.PropertyAssignment): void { const propName = node.name; - if (!propName || !(ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { + if (!propName || !(ts.isNumericLiteral(propName) || ts.isStringLiteral(propName))) { return; } @@ -1594,12 +2039,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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); } isDynamic = isLibraryType || this.tsUtils.isDynamicLiteralInitializer(node.parent); + if (!isRecordObjectInitializer && !isDynamic) { const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyAssignment(node); this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); @@ -1807,6 +2254,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (hasUnfixableReturnType) { this.incrementCounters(funcExpr, FaultID.LimitedReturnTypeInference); } + this.handleLimitedVoidFunction(funcExpr); } private handleArrowFunction(node: ts.Node): void { @@ -1820,14 +2268,21 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleMissingReturnType(arrowFunc); } } + if (!ts.isBlock(arrowFunc.body)) { + const contextRetType = this.tsTypeChecker.getContextualType(arrowFunc.body); + if (contextRetType) { + this.checkAssignmentMatching(arrowFunc.body, contextRetType, arrowFunc.body, true); + } + } this.checkDefaultParamBeforeRequired(arrowFunc); + this.handleLimitedVoidFunction(arrowFunc); } private handleFunctionDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.options.cancellationToken?.throwIfCancellationRequested(); - const tsFunctionDeclaration = node as ts.FunctionDeclaration; + if (!tsFunctionDeclaration.type) { this.handleMissingReturnType(tsFunctionDeclaration); } @@ -1837,6 +2292,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (tsFunctionDeclaration.body) { this.reportThisKeywordsInScope(tsFunctionDeclaration.body); } + if (this.options.arkts2) { + this.handleParamType(tsFunctionDeclaration); + } const funcDeclParent = tsFunctionDeclaration.parent; if (!ts.isSourceFile(funcDeclParent) && !ts.isModuleBlock(funcDeclParent)) { const autofix = this.autofixer?.fixNestedFunction(tsFunctionDeclaration); @@ -1846,26 +2304,39 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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.processSendableDecoratorFunctionOverload(tsFunctionDeclaration); } this.handleTSOverload(tsFunctionDeclaration); - this.checkAssignmentNumericSemanticsFuntion(tsFunctionDeclaration); this.handleInvalidIdentifier(tsFunctionDeclaration); this.checkDefaultParamBeforeRequired(tsFunctionDeclaration); + this.handleLimitedVoidFunction(tsFunctionDeclaration); + } + + private processSendableDecoratorFunctionOverload(tsFunctionDeclaration: ts.FunctionDeclaration): void { + 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 + ); + } + + private handleParamType(decl: ts.FunctionLikeDeclaration): void { + for (const param of decl.parameters) { + if (param.type) { + continue; + } + this.incrementCounters(param, FaultID.ParameterType); + } } private handleMissingReturnType( @@ -1981,7 +2452,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const propertyAccess = ts.isParenthesizedExpression(expr) ? expr.expression : expr; if (ts.isPropertyAccessExpression(propertyAccess)) { - const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccess); + const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccess.expression); const declaration = exprSym?.declarations?.[0]; this.checkAndProcessDeclaration(declaration, tsUnaryArithm); } @@ -2023,6 +2494,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (this.useStatic && this.options.arkts2) { const tsUnaryArithm = node as ts.PrefixUnaryExpression; this.handleInteropOperand(tsUnaryArithm); + this.handleInfinityIdentifier(tsUnaryArithm); } const tsUnaryOp = tsUnaryArithm.operator; const tsUnaryOperand = tsUnaryArithm.operand; @@ -2047,6 +2519,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private handleInfinityIdentifier(node: ts.PrefixUnaryExpression): void { + const identifier = node.operand; + if (identifier.getText() === STRINGLITERAL_INFINITY && node.operator === ts.SyntaxKind.TildeToken) { + this.incrementCounters(node, FaultID.PrefixUnaryInfinity); + } + } + private handleBinaryExpression(node: ts.Node): void { const tsBinaryExpr = node as ts.BinaryExpression; const tsLhsExpr = tsBinaryExpr.left; @@ -2064,19 +2543,18 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { case ts.SyntaxKind.InstanceOfKeyword: this.processBinaryInstanceOf(node, tsLhsExpr, leftOperandType); this.handleInstanceOfExpression(tsBinaryExpr); + this.handleInstanceOfFunction(tsBinaryExpr); break; case ts.SyntaxKind.InKeyword: this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); break; case ts.SyntaxKind.EqualsToken: this.handleTsInterop(tsLhsExpr, () => { - this.checkInteropEqualsBinaryExpression(leftOperandType, tsBinaryExpr); + this.checkUsageOfTsTypes(leftOperandType, tsBinaryExpr); }); this.checkAssignmentMatching(tsBinaryExpr, leftOperandType, tsRhsExpr); - this.checkFunctionTypeCompatible(typeNode, tsRhsExpr); this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); - this.handleSdkDuplicateDeclName(tsBinaryExpr); - this.checkArrayTypeImmutable(tsBinaryExpr); + this.handleSdkGlobalApi(tsBinaryExpr); break; case ts.SyntaxKind.AmpersandAmpersandEqualsToken: case ts.SyntaxKind.QuestionQuestionEqualsToken: @@ -2086,10 +2564,15 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } break; default: + this.handleUnsignedShiftOnNegative(tsBinaryExpr); } this.checkInterOpImportJsDataCompare(tsBinaryExpr); this.checkInteropEqualityJudgment(tsBinaryExpr); this.handleNumericBigintCompare(tsBinaryExpr); + this.handleArkTSPropertyAccess(tsBinaryExpr); + this.handleObjectLiteralAssignmentToClass(tsBinaryExpr); + this.handleAssignmentNotsLikeSmartType(tsBinaryExpr); + this.checkNumericSemanticsForBinaryExpression(tsBinaryExpr); } private checkInterOpImportJsDataCompare(expr: ts.BinaryExpression): void { @@ -2097,35 +2580,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - const isJsFileSymbol = (symbol: ts.Symbol | undefined): boolean => { - if (!symbol) { - return false; - } - - const declaration = symbol.declarations?.[0]; - if (!declaration || !ts.isVariableDeclaration(declaration)) { - return false; - } - - const initializer = declaration.initializer; - if (!initializer) { - return false; - } - return isJsFileExpression(initializer); - }; - - const 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; - }; - - const processExpression = (expr: ts.Expression): void => { - const symbol = this.tsUtils.trueSymbolAtLocation(expr); - if (isJsFileSymbol(symbol) || isJsFileExpression(expr)) { - this.incrementCounters(expr, FaultID.InterOpImportJsDataCompare); + const processExpression = (expr: ts.Expression): void => { + const symbol = this.tsUtils.trueSymbolAtLocation(expr); + if (this.isJsFileSymbol(symbol) || this.isJsFileExpression(expr)) { + const autofix = this.autofixer?.fixInteropOperators(expr); + this.incrementCounters(expr, FaultID.InterOpImportJsDataCompare, autofix); } }; @@ -2142,6 +2601,28 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ].includes(kind); } + private isJsFileSymbol(symbol: ts.Symbol | undefined): boolean { + if (!symbol) { + return false; + } + + 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) { @@ -2233,163 +2714,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - 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; @@ -2401,6 +2725,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ) { return true; } + if ( + ts.isBinaryExpression(node) && + TypeScriptLinter.isNumericInitializer(node.left) && + TypeScriptLinter.isNumericInitializer(node.right) + ) { + return true; + } return false; } @@ -2488,6 +2819,28 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private isObjectLiteralKeyTypeValid(objectLiteral: ts.ObjectLiteralExpression, contextualType: ts.Type): void { + const decl = contextualType.symbol?.declarations?.[0]; + if ( + !this.tsUtils.isStdRecordType(contextualType) && + !(decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) + ) { + return; + } + objectLiteral.properties.forEach((prop: ts.ObjectLiteralElementLike): void => { + if (ts.isPropertyAssignment(prop)) { + const propName = prop.name; + const isValid = this.tsUtils.isStdRecordType(contextualType) ? + this.tsUtils.isValidRecordObjectLiteralKey(propName) : + ts.isIdentifier(propName); + + if (!isValid) { + this.incrementCounters(propName, FaultID.ObjectLiteralKeyType); + } + } + }); + } + private handleVariableDeclaration(node: ts.Node): void { const tsVarDecl = node as ts.VariableDeclaration; this.handleVariableDeclarationForProp(tsVarDecl); @@ -2507,267 +2860,162 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type), tsVarDecl.initializer ); - this.checkFunctionTypeCompatible(tsVarDecl.type, tsVarDecl.initializer); } - this.handleEsObjectDelaration(tsVarDecl); + 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); + this.handleSdkGlobalApi(tsVarDecl); + this.handleNoDeprecatedApi(tsVarDecl); + this.checkNumericSemanticsForVariable(tsVarDecl); } - private checkArrayTypeImmutable(node: ts.VariableDeclaration | ts.BinaryExpression): void { + private checkNumericSemanticsForBinaryExpression(node: 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); - } - } + const isInArrayContext = this.isInArrayAssignmentContext(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); - } - } - } - } + const isDivision = node.operatorToken.kind === ts.SyntaxKind.SlashToken; + const isNullishCoalescing = node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken; - private checkTypeFromSdk(type: ts.TypeNode | undefined): void { - if (!this.options.arkts2 || !type) { + if (!isDivision && !isNullishCoalescing) { return; } - const fullTypeName = type.getText(); - const nameArr = fullTypeName.split('.'); - const sdkInfos = this.interfaceMap.get(nameArr[0]); - if (!sdkInfos || sdkInfos.size === 0) { + if (this.tsUtils.isPossiblyImportedFromJS(node.left) || this.tsUtils.isPossiblyImportedFromJS(node.right)) { return; } - for (const sdkInfo of sdkInfos) { - if (sdkInfo.api_name && nameArr.includes(sdkInfo.api_name)) { - this.incrementCounters(type, FaultID.LimitedVoidTypeFromSdk); - return; - } + if (isDivision && isInArrayContext) { + this.checkNumericSemanticsForDivisionOperation(node); + } else { + this.checkNumericSemanticsForNullishCoalescing(node); } } - private static extractUsedObjectType(tsVarDecl: ts.VariableDeclaration): InterfaceSymbolTypePropertyNames | null { - const result = { - propertyNames: [] as string[], - typeNames: [] as string[] - }; + private isInArrayAssignmentContext(node: ts.BinaryExpression): boolean { + if (ts.isArrayLiteralExpression(node.parent)) { + return true; + } - if (!this.isObjectLiteralWithProperties(tsVarDecl)) { - return null; + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isElementAccessExpression(node.parent.left) + ) { + return true; } - this.processObjectLiteralProperties(tsVarDecl.initializer as ts.ObjectLiteralExpression, result); - return result.propertyNames.length > 0 ? result : null; - } + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + this.tsUtils.isNumberArrayType(this.tsTypeChecker.getTypeAtLocation(node.parent.left)) + ) { + return true; + } - private static isObjectLiteralWithProperties(tsVarDecl: ts.VariableDeclaration): boolean { - return ( - tsVarDecl.initializer !== undefined && - ts.isObjectLiteralExpression(tsVarDecl.initializer) && - tsVarDecl.initializer.properties.length > 0 - ); + return false; } - private static processObjectLiteralProperties( - objectLiteral: ts.ObjectLiteralExpression, - result: { propertyNames: string[]; typeNames: string[] } - ): void { - objectLiteral.properties.forEach((property) => { - if (!ts.isPropertyAssignment(property)) { - return; + private checkNumericSemanticsForDivisionOperation(node: ts.BinaryExpression): void { + const left = node.left; + const right = node.right; + if (ts.isNumericLiteral(left)) { + const leftText = left.getText(); + if (!leftText.includes('.')) { + const autofix = this.autofixer?.fixNumericLiteralToFloat(left); + this.incrementCounters(left, FaultID.NumericSemantics, autofix); } + } - const propertyName = property.name.getText(); - result.propertyNames.push(propertyName); - - if (ts.isNewExpression(property.initializer)) { - const typeName = property.initializer.expression.getText(); - result.typeNames.push(typeName); + if (ts.isNumericLiteral(right)) { + const rightText = right.getText(); + if (!rightText.includes('.')) { + const autofix = this.autofixer?.fixNumericLiteralToFloat(right); + this.incrementCounters(right, FaultID.NumericSemantics, autofix); } - }); - } - - private interfaceSymbolType(tsVarDecl: ts.VariableDeclaration): InterfaceSymbolTypeResult | null { - if (!tsVarDecl.type) { - return null; } + } - const typeSymbol = this.getTypeSymbol(tsVarDecl); - if (!typeSymbol) { - return null; + private checkNumericSemanticsForNullishCoalescing(node: ts.BinaryExpression): void { + if (!ts.isArrayLiteralExpression(node.right)) { + return; } - const interfaceType = this.getInterfaceType(tsVarDecl); - if (!interfaceType) { - return null; + const leftType = this.tsTypeChecker.getTypeAtLocation(node.left); + if (!this.tsUtils.isNumberArrayType(leftType)) { + return; } - - 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; + this.checkNumericSemanticsForArrayLiteral(node.right); } - 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 checkNumericSemanticsForArrayLiteral(node: ts.ArrayLiteralExpression): void { + const arrayType = this.tsTypeChecker.getTypeAtLocation(node); + if (!this.tsUtils.isNumberArrayType(arrayType)) { + return; } - } - 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); + for (const element of node.elements) { + if (ts.isNumericLiteral(element) && !element.text.includes('.')) { + const autofix = this.autofixer?.fixNumericLiteralToFloat(element); + this.incrementCounters(element, FaultID.NumericSemantics, autofix); + } else if (ts.isBinaryExpression(element) && element.operatorToken.kind === ts.SyntaxKind.SlashToken) { + this.checkNumericSemanticsForDivisionOperation(element); + } } } - handleNoStructuralTyping(tsVarDecl: ts.VariableDeclaration): void { - const { interfaceInfo, actualUsage } = this.getTypeComparisonData(tsVarDecl); - if (!interfaceInfo || !actualUsage) { + private checkNumericSemanticsForVariable(node: ts.VariableDeclaration): void { + if (!this.options.arkts2 || !node.initializer) { return; } - if (!this.options.arkts2) { + + const type = this.tsTypeChecker.getTypeAtLocation(node.name); + if (!this.tsUtils.isNumberArrayType(type)) { return; } - const actualMap = TypeScriptLinter.createActualTypeMap(actualUsage); - const hasMismatch = TypeScriptLinter.checkTypeMismatches(interfaceInfo, actualMap); - if (hasMismatch) { - this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); + if (ts.isBinaryExpression(node.initializer) && node.initializer.operatorToken.kind === ts.SyntaxKind.BarBarToken) { + this.checkNumericSemanticsForNullishCoalescing(node.initializer); + } else if (ts.isConditionalExpression(node.initializer)) { + this.checkNumericSemanticsForTernaryOperator(node.initializer); } } - 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 checkNumericSemanticsForTernaryOperator(node: ts.ConditionalExpression): void { + if (!ts.isArrayLiteralExpression(node.whenFalse)) { + return; + } + const arrayLiteral = node.whenFalse; - 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; + this.checkNumericSemanticsForArrayLiteral(arrayLiteral); } - private static checkTypeMismatches( - interfaceInfo: { allProps: Map }, - actualMap: Map - ): boolean { - let hasMismatch = false; + private checkTypeFromSdk(type: ts.TypeNode | undefined): void { + if (!this.options.arkts2 || !type) { + return; + } - interfaceInfo.allProps.forEach((expectedType, prop) => { - if (!actualMap.has(prop)) { - return; - } + const fullTypeName = type.getText(); + const nameArr = fullTypeName.split('.'); + const sdkInfos = this.interfaceMap.get(nameArr[0]); + if (!sdkInfos || sdkInfos.size === 0) { + return; + } - const actualType = actualMap.get(prop)!; - if (expectedType !== actualType) { - hasMismatch = true; + for (const sdkInfo of sdkInfos) { + if (sdkInfo.api_name && nameArr.includes(sdkInfo.api_name)) { + this.incrementCounters(type, FaultID.LimitedVoidTypeFromSdk); + return; } - }); - - return hasMismatch; + } } private handleDeclarationDestructuring(decl: ts.VariableDeclaration | ts.ParameterDeclaration): void { @@ -2815,13 +3063,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private handleEsObjectDelaration(node: ts.VariableDeclaration): void { - const isDeclaredESObject = !!node.type && TsUtils.isEsObjectType(node.type); + private handleEsValueDeclaration(node: ts.VariableDeclaration): void { + const isDeclaredESValue = !!node.type && TsUtils.isEsValueType(node.type); const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); - const isInitializedWithESObject = !!initalizerTypeNode && TsUtils.isEsObjectType(initalizerTypeNode); + const isInitializedWithESValue = !!initalizerTypeNode && TsUtils.isEsValueType(initalizerTypeNode); const isLocal = TsUtils.isInsideBlock(node); - if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + if ((isDeclaredESValue || isInitializedWithESValue) && !isLocal) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; this.incrementCounters(node, faultId); return; } @@ -2833,17 +3081,17 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node): void { const isTypeAnnotated = !!nodeDeclType; - const isDeclaredESObject = isTypeAnnotated && TsUtils.isEsObjectType(nodeDeclType); + const isDeclaredESValue = isTypeAnnotated && TsUtils.isEsValueType(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; + 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 (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + if (isDeclaredESValue && !this.tsUtils.isValueAssignableToESValue(initializer)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; this.incrementCounters(node, faultId); } } @@ -2862,31 +3110,330 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.incrementCounters(node, FaultID.CatchWithUnsupportedType, autofix); } - if ( - this.options.arkts2 && - tsCatch.variableDeclaration && - TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(tsCatch.variableDeclaration)) - ) { - this.incrementCounters(node, FaultID.TsLikeCatchType); + if (this.options.arkts2 && tsCatch.variableDeclaration?.name) { + const varDeclName = tsCatch.variableDeclaration?.name.getText(); + tsCatch.block.statements.forEach((statement) => { + this.checkTsLikeCatchType(statement, varDeclName, undefined); + }); } } - private handleClassExtends(tsClassDecl: ts.ClassDeclaration): void { - if (!this.options.arkts2) { + private checkTsLikeCatchType( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { + if (!node) { 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) { + const hasChecked = this.hasCheckedTsLikeCatchTypeInIfStatement(node, variableDeclarationName, typeNode); + if (hasChecked) { return; } - tsClassDecl.heritageClauses.forEach((clause) => { - clause.types.forEach((type) => { + const hasCheckedInConditionalExpr = this.hasCheckedTsLikeCatchTypeInConditionalExpression( + node, + variableDeclarationName, + typeNode + ); + if (hasCheckedInConditionalExpr) { + return; + } + this.checkTsLikeCatchTypeForAsExpr(node, variableDeclarationName); + + for (const child of node.getChildren()) { + if (ts.isPropertyAccessExpression(child)) { + this.checkTsLikeCatchTypeForPropAccessExpr(child, variableDeclarationName, typeNode); + + if ( + ts.isParenthesizedExpression(child.expression) && + ts.isAsExpression(child.expression.expression) && + child.expression.expression.expression.getText() === variableDeclarationName + ) { + this.checkTsLikeCatchTypePropForAsExpression(child, child.expression.expression); + } + } + this.checkTsLikeCatchType(child, variableDeclarationName, typeNode); + } + } + + private hasCheckedTsLikeCatchTypeInIfStatement( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + const checkSubStatement = (node: ts.IfStatement, declaration: ts.ClassDeclaration): void => { + if (!this.isErrorOrInheritError(declaration)) { + this.incrementCounters(node.expression, FaultID.TsLikeCatchType); + } else { + this.checkTsLikeCatchType(node.thenStatement, variableDeclarationName, declaration); + } + const elseStatement = node.elseStatement; + if (elseStatement) { + this.checkTsLikeCatchType(elseStatement, variableDeclarationName, typeNode); + } + }; + + if ( + ts.isIfStatement(node) && + ts.isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && + node.expression.left.getText() === variableDeclarationName + ) { + const rightSym = this.tsTypeChecker.getSymbolAtLocation(node.expression.right); + const decl = rightSym?.declarations?.[0]; + if (decl && ts.isClassDeclaration(decl)) { + checkSubStatement(node, decl); + return true; + } + if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration)) { + checkSubStatement(node, declaration); + return true; + } + } + } + return false; + } + + private hasCheckedTsLikeCatchTypeInConditionalExpression( + node: ts.Node, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + if ( + ts.isConditionalExpression(node) && + ts.isBinaryExpression(node.condition) && + node.condition.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && + node.condition.left.getText() === variableDeclarationName + ) { + const rightSym = this.tsTypeChecker.getSymbolAtLocation(node.condition.right); + const decl = rightSym?.declarations?.[0]; + if (decl && ts.isClassDeclaration(decl)) { + this.checkTsLikeCatchTypeInConditionalExprSubStatement(node, decl, variableDeclarationName, typeNode); + return true; + } else if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration)) { + this.checkTsLikeCatchTypeInConditionalExprSubStatement(node, declaration, variableDeclarationName, typeNode); + return true; + } + } + } + return false; + } + + private checkTsLikeCatchTypeInConditionalExprSubStatement( + node: ts.ConditionalExpression, + declarationType: ts.ClassDeclaration, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { + const checkWhenFalseExpr = ( + whenFalse: ts.Node, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void => { + if (ts.isPropertyAccessExpression(whenFalse) && whenFalse.expression.getText() === variableDeclarationName) { + if (!typeNode) { + if (!ERROR_PROP_LIST.has(whenFalse.name.getText())) { + this.incrementCounters(whenFalse, FaultID.TsLikeCatchType); + } + } else { + const isValidErrorPropAccess = this.isValidErrorPropAccess(whenFalse, typeNode); + if (!isValidErrorPropAccess) { + this.incrementCounters(whenFalse, FaultID.TsLikeCatchType); + } + } + } else { + this.checkTsLikeCatchType(whenFalse, variableDeclarationName, typeNode); + } + }; + + if (!this.isErrorOrInheritError(declarationType)) { + this.incrementCounters(node.condition, FaultID.TsLikeCatchType); + checkWhenFalseExpr(node.whenFalse, typeNode); + } else { + if ( + ts.isPropertyAccessExpression(node.whenTrue) && + node.whenTrue.expression.getText() === variableDeclarationName + ) { + const whenTrue: ts.PropertyAccessExpression = node.whenTrue; + const isValidErrorPropAccess = this.isValidErrorPropAccess(whenTrue, declarationType); + if (!isValidErrorPropAccess) { + this.incrementCounters(whenTrue, FaultID.TsLikeCatchType); + } + } else { + this.checkTsLikeCatchType(node.whenTrue, variableDeclarationName, declarationType); + } + checkWhenFalseExpr(node.whenFalse, typeNode); + } + } + + private checkTsLikeCatchTypeForAsExpr(node: ts.Node, variableDeclarationName: string): void { + if (!ts.isAsExpression(node) || node.expression.getText() !== variableDeclarationName) { + return; + } + const asExprTypeNode = node.type; + if (!asExprTypeNode || !ts.isTypeReferenceNode(asExprTypeNode)) { + return; + } + const checkReport = (node: ts.AsExpression, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): void => { + if (!this.isErrorOrInheritError(declaration)) { + this.incrementCounters(node, FaultID.TsLikeCatchType); + } + }; + + const checkImportSpecifier = (decl: ts.ImportSpecifier): void => { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) { + checkReport(node, declaration); + } + }; + const typeName = asExprTypeNode.typeName; + const sym = this.tsTypeChecker.getSymbolAtLocation(typeName); + const decl = sym?.declarations?.[0]; + if (decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) { + checkReport(node, decl); + } else if (decl && ts.isImportSpecifier(decl)) { + checkImportSpecifier(decl); + } + } + + private checkTsLikeCatchTypeHasPropInType( + propAccessExpr: ts.PropertyAccessExpression, + decl: ts.ClassDeclaration | ts.InterfaceDeclaration + ): void { + if (!decl) { + return; + } + if (this.isErrorOrInheritError(decl)) { + const isValidErrorPropAccess = this.isValidErrorPropAccess(propAccessExpr, decl); + if (!isValidErrorPropAccess) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } + } + + private checkTsLikeCatchTypeForPropAccessExpr( + propAccessExpr: ts.PropertyAccessExpression, + variableDeclarationName: string, + typeNode: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): void { + const checkProp = (): void => { + if (!typeNode) { + if (!ERROR_PROP_LIST.has(propAccessExpr.name.getText())) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } else { + const isValidErrorPropAccess = this.isValidErrorPropAccess(propAccessExpr, typeNode); + if (!isValidErrorPropAccess) { + this.incrementCounters(propAccessExpr, FaultID.TsLikeCatchType); + } + } + }; + + if (propAccessExpr.expression.getText() === variableDeclarationName) { + checkProp(); + return; + } + + const sym = this.tsTypeChecker.getSymbolAtLocation(propAccessExpr.expression); + const decl = sym?.declarations?.[0]; + if (decl && ts.isVariableDeclaration(decl) && decl.initializer) { + if (decl.initializer.getText() === variableDeclarationName) { + checkProp(); + return; + } + if (ts.isAsExpression(decl.initializer) && decl.initializer.expression.getText() === variableDeclarationName) { + this.checkTsLikeCatchTypePropForAsExpression(propAccessExpr, decl.initializer); + } + } + } + + private checkTsLikeCatchTypePropForAsExpression( + propAccessExpr: ts.PropertyAccessExpression, + asExpr: ts.AsExpression + ): void { + const asExprTypeNode = asExpr.type; + if (asExprTypeNode && ts.isTypeReferenceNode(asExprTypeNode)) { + const typeName = asExprTypeNode.typeName; + const sym = this.tsTypeChecker.getSymbolAtLocation(typeName); + const decl = sym?.declarations?.[0]; + if (decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) { + this.checkTsLikeCatchTypeHasPropInType(propAccessExpr, decl); + } else if (decl && ts.isImportSpecifier(decl)) { + const symbol = this.getSymbolByImportSpecifier(decl); + const declaration = symbol?.declarations?.[0]; + if (declaration && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) { + this.checkTsLikeCatchTypeHasPropInType(propAccessExpr, declaration); + } + } + } + } + + private isErrorOrInheritError(declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(declaration); + return this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdErrorType); + } + + private isValidErrorPropAccess( + propertyAccessExpr: ts.PropertyAccessExpression, + decl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): boolean { + void this; + let containsMember = false; + decl?.members.forEach((member) => { + if (member.name?.getText() === propertyAccessExpr.name.getText()) { + containsMember = true; + } + }); + return containsMember || ERROR_PROP_LIST.has(propertyAccessExpr.name.getText()); + } + + private getSymbolByImportSpecifier(declaration: ts.ImportSpecifier): ts.Symbol | undefined { + if (!declaration?.parent?.parent) { + return undefined; + } + if (!ts.isImportClause(declaration.parent.parent)) { + return undefined; + } + const importClause = declaration.parent.parent; + const namedBindings = importClause.namedBindings; + let symbol: ts.Symbol | undefined; + if (namedBindings) { + if (ts.isNamedImports(namedBindings) && namedBindings.elements?.length > 0) { + for (let i = 0; i < namedBindings.elements.length; i++) { + if (namedBindings.elements[i].name.getText() === declaration.name.getText()) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.elements[i].name); + break; + } + } + } else if (ts.isNamespaceImport(namedBindings)) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.name); + } + } + return symbol; + } + + 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)) { @@ -2954,6 +3501,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleInvalidIdentifier(tsClassDecl); this.handleSdkMethod(tsClassDecl); this.handleNotsLikeSmartType(tsClassDecl); + this.handleLocalDeclarationOfClassAndIface(tsClassDecl); + this.checkObjectPublicApiMethods(tsClassDecl); } private static findFinalExpression(typeNode: ts.TypeNode): ts.Node { @@ -2980,6 +3529,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { methodName?: string ): boolean { return heritageClause.types.some((type) => { + const parentName = ts.isPropertyAccessExpression(type.expression) ? + type.expression.name.text : + type.expression.getText(); const fullTypeName = TypeScriptLinter.findFinalExpression(type).getText(); const sdkInfos = this.interfaceMap.get(fullTypeName); if (!sdkInfos || sdkInfos.size === 0) { @@ -2991,8 +3543,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } - if (!methodName) { - this.processSdkInfoWithMembers(sdkInfo, tsClassDecl.members,tsClassDecl); + if (!methodName && sdkInfo.parent_api[0].api_name === parentName) { + this.processSdkInfoWithMembers(sdkInfo, tsClassDecl.members, tsClassDecl); return false; } @@ -3021,7 +3573,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private processSdkInfoWithMembers(sdkInfo: ApiInfo, members: ts.NodeArray,tsClassDecl:ts.ClassDeclaration): void { + private processSdkInfoWithMembers( + sdkInfo: ApiInfo, + members: ts.NodeArray, + tsClassDecl: ts.ClassDeclaration + ): void { for (const member of members) { if (!ts.isMethodDeclaration(member)) { continue; @@ -3029,8 +3585,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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)) { + if ( + !TypeScriptLinter.areParametersEqual(sdkInfo.api_func_args ?? [], member.parameters) && + !TypeScriptLinter.areGenericsParametersEqual(sdkInfo.api_func_args ?? [], tsClassDecl) + ) { return; } this.incrementCounters( @@ -3047,12 +3605,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ): boolean { const apiParamCout = sdkFuncArgs.length; const memberParamCout = memberParams.length; - if (apiParamCout > memberParamCout && sdkFuncArgs[memberParamCout + 1]) { + if (apiParamCout > memberParamCout && sdkFuncArgs[memberParamCout]) { return false; } for (let i = 0; i < apiParamCout; i++) { - const typeName = memberParams[i].type?.getText(); + const typeName = memberParams[i]?.type?.getText(); if (!typeName?.match(sdkFuncArgs[i].type)) { return false; } @@ -3113,6 +3671,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } } + private static areGenericsParametersEqual( sdkFuncArgs: { name: string; type: string }[], node: ts.ClassDeclaration @@ -3125,7 +3684,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!typeParameters) { return false; } - typeParameters.forEach(typeParam => { + typeParameters.forEach((typeParam) => { if (!typeParam.constraint) { return false; } @@ -3353,11 +3912,20 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private handleTemplateType(node: ts.TemplateLiteralTypeNode): void { + if (!this.options.arkts2) { + return; + } + this.incrementCounters(node, FaultID.TemplateStringType); + } + private handleTupleType(node: ts.TupleTypeNode): void { if (!this.options.arkts2) { return; } + this.checkOptionalTupleType(node); + node.elements.forEach((elementType) => { if (elementType.kind === ts.SyntaxKind.VoidKeyword) { this.incrementCounters(elementType, FaultID.LimitedVoidType); @@ -3365,6 +3933,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); } + private checkOptionalTupleType(node: ts.TupleTypeNode): void { + node.elements.forEach((elementType) => { + if (elementType.kind === ts.SyntaxKind.OptionalType) { + this.incrementCounters(elementType, FaultID.OptionalTupleType); + } + }); + } + private handleImportClause(node: ts.Node): void { const tsImportClause = node as ts.ImportClause; if (this.options.arkts2 && tsImportClause.isLazy) { @@ -3410,6 +3986,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } } + if (this.options.arkts2) { + this.handleParamType(tsMethodDecl); + } if (tsMethodDecl.body && isStatic) { this.reportThisKeywordsInScope(tsMethodDecl.body); } @@ -3434,6 +4013,50 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.checkDefaultParamBeforeRequired(tsMethodDecl); this.handleMethodInherit(tsMethodDecl); + this.handleSdkGlobalApi(tsMethodDecl); + this.handleLimitedVoidFunction(tsMethodDecl); + this.checkVoidLifecycleReturn(tsMethodDecl); + this.handleNoDeprecatedApi(tsMethodDecl); + this.checkAbstractOverrideReturnType(tsMethodDecl); + } + + private checkObjectPublicApiMethods(node: ts.ClassDeclaration | ts.InterfaceDeclaration): void { + if (!this.options.arkts2) { + return; + } + for (const member of node.members) { + if (!((ts.isMethodDeclaration(member) || ts.isMethodSignature(member)) && ts.isIdentifier(member.name))) { + continue; + } + const methodName = member.name.text; + const expectedSignature = OBJECT_PUBLIC_API_METHOD_SIGNATURES.get(methodName); + if (!expectedSignature) { + continue; + } + const methodType = this.tsTypeChecker.getTypeAtLocation(member); + const signature = TsUtils.getFunctionalTypeSignature(methodType); + if (!signature) { + continue; + } + const actualSignature = this.tsTypeChecker.signatureToString(signature); + if (actualSignature !== expectedSignature) { + this.incrementCounters(member, FaultID.NoSignatureDistinctWithObjectPublicApi); + } + } + } + + private handleLimitedVoidFunction(node: ts.FunctionLikeDeclaration): void { + const typeNode = node.type; + if (!typeNode || !ts.isUnionTypeNode(typeNode)) { + return; + } + const containsVoid = typeNode.types.some((t) => { + return t.kind === ts.SyntaxKind.VoidKeyword; + }); + if (this.options.arkts2 && containsVoid) { + const autofix = this.autofixer?.fixLimitedVoidTypeFunction(node); + this.incrementCounters(typeNode, FaultID.LimitedVoidType, autofix); + } } private checkDefaultParamBeforeRequired(node: ts.FunctionLikeDeclarationBase): void { @@ -3467,116 +4090,587 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const classDecl = node.parent; if (!ts.isClassDeclaration(classDecl)) { + this.handleMethodInheritForCommonApi(node); return; } + const isStatic = + node.modifiers?.some((mod) => { + return mod.kind === ts.SyntaxKind.StaticKeyword; + }) || false; + const classType: ts.Type | undefined = this.getClassType(classDecl, isStatic); + const allBaseTypes = classType && this.getAllBaseTypes(classType, classDecl, isStatic); - const classType = this.tsTypeChecker.getTypeAtLocation(classDecl); - const baseTypes = classType.getBaseTypes(); - if (!baseTypes || baseTypes.length === 0) { + if (!allBaseTypes || allBaseTypes.length === 0) { return; } - const methodName = node.name.text; + if (allBaseTypes && allBaseTypes.length > 0) { + this.checkMethodType(allBaseTypes, methodName, node, isStatic); + } + this.checkIncompatibleFunctionTypes(node); + } + + private handleMethodInheritForCommonApi(node: ts.MethodDeclaration): void { + const commonApiInfos = getCommonApiInfoMap(); + commonApiInfos?.forEach((apiNode) => { + if (node.name.getText() === apiNode.name.getText()) { + this.checkMethodParameters(node, apiNode); + this.checkMethodReturnType(node, apiNode); + } + }); + } - for (const baseType of baseTypes) { - const baseMethod = baseType.getProperty(methodName); + private checkMethodType( + allBaseTypes: ts.Type[], + methodName: string, + node: ts.MethodDeclaration, + isStatic: boolean = false + ): void { + for (const baseType of allBaseTypes) { + let baseMethod: ts.Symbol | undefined; + const symbol = baseType.getSymbol(); + if (isStatic && symbol) { + const constructorType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, node); + baseMethod = + constructorType.getProperty(methodName) || symbol.members?.get(ts.escapeLeadingUnderscores(methodName)); + } else { + baseMethod = baseType.getProperty(methodName); + } if (!baseMethod) { continue; } + const baseMethodDecl = baseMethod.declarations?.find((d) => { + return ( + (ts.isMethodDeclaration(d) || ts.isMethodSignature(d)) && + this.isSameDeclarationType(d.parent, baseType, isStatic) + ); + }) as ts.MethodDeclaration | ts.MethodSignature; - 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); - } + private isSameDeclarationType(decl: ts.Node, type: ts.Type, isStatic: boolean): boolean { + if (isStatic && ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl)) { + const staticType = this.tsTypeChecker.getTypeAtLocation(decl); + return this.isSameType(staticType, type); } + return this.tsTypeChecker.getTypeAtLocation(decl) === type; } - /** - * 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) { + private checkIncompatibleFunctionTypes(method: ts.MethodDeclaration): void { + const declaredReturnType = this.getActualReturnType(method); + if (!declaredReturnType) { 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); + const returnStatements = this.collectReturnStatements(method); + const declaredReturnTypeStr = this.tsTypeChecker.typeToString(declaredReturnType); + for (const returnStmt of returnStatements) { + if (!returnStmt.expression) { + continue; + } + const actualReturnType = this.tsTypeChecker.getTypeAtLocation(returnStmt.expression); + const actualReturnTypeStr = this.tsTypeChecker.typeToString(actualReturnType); + if (declaredReturnTypeStr === actualReturnTypeStr) { + return; + } + if (this.tsUtils.skipCheckForArrayBufferLike(declaredReturnTypeStr, actualReturnTypeStr)) { + return; + } + if (actualReturnType.flags & ts.TypeFlags.Any || declaredReturnType.flags & ts.TypeFlags.Any) { + return; + } + if (this.isSubtypeByBaseTypesList(actualReturnType, declaredReturnType)) { + this.incrementCounters(returnStmt.expression, FaultID.IncompationbleFunctionType); + return; + } } } - /** - * 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)); + private collectReturnStatements(node: ts.Node): ts.ReturnStatement[] { + const result: ts.ReturnStatement[] = []; - // Check if every type in baseType is also present in derivedType - for (const typeStr of baseTypeSet) { - if (!derivedTypeSet.has(typeStr)) { - return false; + ts.forEachChild(node, (child) => { + if (ts.isReturnStatement(child)) { + result.push(child); + } else { + result.push(...this.collectReturnStatements(child)); } - } + }); - return true; + return result; } - // 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)); + private getClassType(classDecl: ts.ClassDeclaration, isStatic?: boolean): ts.Type | undefined { + let classType: ts.Type; - // All types in `fromTypes` should exist in `toTypes` for assignability. - return fromTypes.every((typeStr) => { - return toTypes.has(typeStr); - }); + if (isStatic) { + const classConstructorSymbol = classDecl.symbol; + if (!classConstructorSymbol) { + return undefined; + } + classType = this.tsTypeChecker.getTypeOfSymbolAtLocation(classConstructorSymbol, classDecl); + } else { + classType = this.tsTypeChecker.getTypeAtLocation(classDecl); + } + return classType; } - // 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); - }); + private isDeclarationInType(decl: ts.Declaration, type: ts.Type, isStatic: boolean = false): boolean { + const declParent = decl.parent; + if (!declParent) { + return false; } - return [this.tsTypeChecker.typeToString(type)]; - } - private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { - for (const member of classDecl.members) { + let declParentType: ts.Type; + if (isStatic && ts.isClassDeclaration(declParent)) { + if (!declParent.symbol) { + return false; + } + declParentType = this.tsTypeChecker.getTypeOfSymbolAtLocation(declParent.symbol, declParent); + } else { + declParentType = this.tsTypeChecker.getTypeAtLocation(declParent); + } + + return this.isSameType(declParentType, type); + } + + private isSameType(type1: ts.Type, type2: ts.Type): boolean { + if (type1.flags & ts.TypeFlags.Any || type2.flags & ts.TypeFlags.Any) { + return true; + } + + if (type1.flags & ts.TypeFlags.TypeParameter && type2.flags & ts.TypeFlags.TypeParameter) { + const constraint1 = (type1 as ts.TypeParameter).getConstraint(); + const constraint2 = (type2 as ts.TypeParameter).getConstraint(); + if (constraint1 && constraint2) { + return this.isSameType(constraint1, constraint2); + } + } + + if (!type1.symbol || type1.symbol !== type2.symbol) { + return false; + } + const type1Args = (type1 as ts.TypeReference).typeArguments; + const type2Args = (type2 as ts.TypeReference).typeArguments; + + if (type1Args && type2Args && type1Args.length === type2Args.length) { + for (let i = 0; i < type1Args.length; i++) { + if (!this.isTypeAssignable(type2Args[i], type1Args[i])) { + return false; + } + } + return true; + } + + return this.tsTypeChecker.typeToString(type1) === this.tsTypeChecker.typeToString(type2); + } + + private getAllBaseTypes(type: ts.Type, classDecl: ts.ClassDeclaration, isStatic?: boolean): ts.Type[] | undefined { + if (isStatic) { + return this.getStaticAllBaseTypes(classDecl); + } + + const baseClasses = type.getBaseTypes() || []; + const resolvedBaseClasses = baseClasses.flatMap((baseType) => { + const symbol = baseType.getSymbol(); + return symbol ? [this.tsTypeChecker.getDeclaredTypeOfSymbol(symbol)] : [baseType]; + }); + + if (!classDecl.heritageClauses) { + return resolvedBaseClasses; + } + + const interfaces: ts.Type[] = []; + for (const clause of classDecl.heritageClauses) { + if (clause.token !== ts.SyntaxKind.ImplementsKeyword) { + continue; + } + for (const typeNode of clause.types) { + const interfaceType = this.tsTypeChecker.getTypeAtLocation(typeNode); + interfaces.push(interfaceType); + + const baseInterfaces = interfaceType.getBaseTypes() || []; + baseInterfaces.forEach((baseInterface) => { + const symbol = baseInterface.getSymbol(); + if (symbol) { + interfaces.push(this.tsTypeChecker.getDeclaredTypeOfSymbol(symbol)); + } + }); + } + } + return [...resolvedBaseClasses, ...interfaces]; + } + + private getStaticAllBaseTypes(classDecl: ts.ClassDeclaration): ts.Type[] | undefined { + const baseTypes: ts.Type[] = []; + if (!classDecl.heritageClauses) { + return baseTypes; + } + + for (const clause of classDecl.heritageClauses) { + if (clause.token !== ts.SyntaxKind.ExtendsKeyword) { + continue; + } + + for (const typeNode of clause.types) { + const baseType = this.tsTypeChecker.getTypeAtLocation(typeNode); + baseTypes.push(baseType); + + const baseDecl = baseType.getSymbol()?.declarations?.[0]; + if (baseDecl && ts.isClassDeclaration(baseDecl)) { + const staticBaseType = this.tsTypeChecker.getTypeAtLocation(baseDecl); + const staticBaseTypes = this.getAllBaseTypes(staticBaseType, baseDecl, true) || []; + baseTypes.push(...staticBaseTypes); + } + } + } + return baseTypes; + } + + /** + * Checks method parameter compatibility + * Derived parameter types must be same or wider than base (contravariance principle) + */ + + private checkMethodParameters( + derivedMethod: ts.MethodDeclaration, + baseMethod: ts.MethodDeclaration | ts.MethodSignature + ): void { + const derivedParams = derivedMethod.parameters; + const baseParams = baseMethod.parameters; + + if (derivedParams.length !== baseParams.length) { + this.incrementCounters(derivedMethod.name, FaultID.MethodInheritRule); + return; + } + + 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 (baseParamType.flags & ts.TypeFlags.TypeParameter) { + if (!(derivedParamType.flags & ts.TypeFlags.TypeParameter)) { + continue; + } + } + + if (!this.isTypeSameOrWider(baseParamType, derivedParamType)) { + this.incrementCounters(derivedParams[i], FaultID.MethodInheritRule); + } + } + } + + /** + * Checks return type compatibility + * Derived return type must be same or narrower than base (covariance principle) + */ + private checkMethodReturnType( + derivedMethod: ts.MethodDeclaration, + baseMethod: ts.MethodDeclaration | ts.MethodSignature + ): void { + if (this.shouldSkipTypeParameterCheck(derivedMethod, baseMethod)) { + return; + } + const baseMethodType = this.getActualReturnType(baseMethod); + const derivedMethodType = this.getActualReturnType(derivedMethod); + const baseMethodTypeIsVoid = TypeScriptLinter.checkMethodTypeIsVoidOrAny(baseMethodType, true); + const baseMethodTypeisAny = TypeScriptLinter.checkMethodTypeIsVoidOrAny(baseMethodType, false); + const derivedMethodTypeIsVoid = TypeScriptLinter.checkMethodTypeIsVoidOrAny(derivedMethodType, true, true); + const baseMethodTypeisAnyWithVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + derivedMethodTypeIsVoid + ); + const baseMethodTypeisAnyWithPromiseVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + this.hasPromiseVoidReturn(derivedMethod) + ); + const baseMethodTypeIsVoidWithoutVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoid, + !derivedMethodTypeIsVoid + ); + const baseMethodTypeisAnyWithoutVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + !derivedMethodTypeIsVoid + ); + const baseMethodTypeIsVoidWithVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoid, + derivedMethodTypeIsVoid + ); + if (baseMethodTypeisAnyWithVoid || baseMethodTypeIsVoidWithoutVoid || baseMethodTypeisAnyWithPromiseVoid) { + this.incrementCounters(derivedMethod.type ? derivedMethod.type : derivedMethod.name, FaultID.MethodInheritRule); + return; + } + const isNoNeedCheck = + !baseMethodType || !derivedMethodType || baseMethodTypeisAnyWithoutVoid || baseMethodTypeIsVoidWithVoid; + if (isNoNeedCheck) { + return; + } + if (this.isDerivedTypeAssignable(derivedMethodType, baseMethodType)) { + return; + } + if (!this.isTypeAssignable(derivedMethodType, baseMethodType)) { + this.incrementCounters(derivedMethod.type ? derivedMethod.type : derivedMethod.name, FaultID.MethodInheritRule); + } + } + + private shouldSkipTypeParameterCheck( + derivedMethod: ts.MethodDeclaration, + baseMethod: ts.MethodDeclaration | ts.MethodSignature + ): boolean { + const baseMethodType = this.getActualReturnType(baseMethod); + const derivedMethodType = this.getActualReturnType(derivedMethod); + + if (baseMethodType && baseMethodType.flags & ts.TypeFlags.TypeParameter) { + if (derivedMethodType && !(derivedMethodType.flags & ts.TypeFlags.TypeParameter)) { + return true; + } + } + return false; + } + + private static checkMethodTypeIsVoidOrAny( + methodType: ts.Type | undefined, + isVoidOrAny: boolean, + isDerived?: boolean + ): boolean | ts.TypeNode | undefined { + if (isDerived && isVoidOrAny) { + return methodType && TsUtils.isVoidType(methodType); + } else if (isVoidOrAny) { + return methodType && TsUtils.isVoidType(methodType); + } + return methodType && TsUtils.isAnyType(methodType); + } + + private static getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoidOrAny: boolean | ts.TypeNode | undefined, + derivedMethodCheckFlag: boolean | ts.TypeNode | undefined + ): boolean | ts.TypeNode | undefined { + return baseMethodTypeIsVoidOrAny && derivedMethodCheckFlag; + } + + private getActualReturnType(method: ts.MethodDeclaration | ts.MethodSignature): ts.Type | undefined { + let type: ts.Type | undefined; + if (method.type) { + type = this.tsTypeChecker.getTypeAtLocation(method.type); + } else { + const signature = this.tsTypeChecker.getSignatureFromDeclaration(method); + if (signature) { + type = this.tsTypeChecker.getReturnTypeOfSignature(signature); + } + } + return type; + } + + private isTypeSameOrWider(baseType: ts.Type, derivedType: ts.Type): boolean { + if (this.tsTypeChecker.typeToString(baseType) === this.tsTypeChecker.typeToString(derivedType)) { + return true; + } + + if (derivedType.flags & ts.TypeFlags.Any || baseType.flags & ts.TypeFlags.Never) { + return true; + } + + if (baseType.symbol === derivedType.symbol && baseType.symbol) { + const baseArgs = (baseType as ts.TypeReference).typeArguments; + const derivedArgs = (derivedType as ts.TypeReference).typeArguments; + + if (!baseArgs || !derivedArgs || baseArgs.length !== derivedArgs.length) { + return false; + } + for (let i = 0; i < baseArgs.length; i++) { + if (!this.isTypeAssignable(baseArgs[i], derivedArgs[i])) { + return false; + } + } + return true; + } + + if (this.checkTypeInheritance(derivedType, baseType, false)) { + return true; + } + + const baseTypeSet = new Set(this.flattenUnionTypes(baseType)); + const derivedTypeSet = new Set(this.flattenUnionTypes(derivedType)); + + for (const typeStr of baseTypeSet) { + if (!derivedTypeSet.has(typeStr)) { + if (TypeScriptLinter.areWrapperAndPrimitiveTypesEqual(typeStr, derivedTypeSet)) { + continue; + } + return false; + } + } + return true; + } + + private isTypeAssignable(fromType: ts.Type, toType: ts.Type): boolean { + if (fromType.flags & ts.TypeFlags.Any) { + return true; + } + + if (fromType.symbol === toType.symbol && fromType.symbol) { + const fromArgs = (fromType as ts.TypeReference).typeArguments; + const toArgs = (toType as ts.TypeReference).typeArguments; + + if (fromArgs && toArgs && fromArgs.length === toArgs.length) { + for (let i = 0; i < fromArgs.length; i++) { + if (!this.isTypeAssignable(fromArgs[i], toArgs[i])) { + return false; + } + } + return true; + } + } + + if (this.checkTypeInheritance(fromType, toType)) { + return true; + } + + const fromTypes = this.flattenUnionTypes(fromType); + const toTypes = new Set(this.flattenUnionTypes(toType)); + + return fromTypes.every((typeStr) => { + if (toTypes.has(typeStr)) { + return true; + } + return TypeScriptLinter.areWrapperAndPrimitiveTypesEqual(typeStr, toTypes); + }); + } + + private checkTypeInheritance(sourceType: ts.Type, targetType: ts.Type, isSouceTotaqrget: boolean = true): boolean { + // Early return if either type lacks symbol information + if (!sourceType.symbol || !targetType.symbol) { + return false; + } + + // Determine which type's inheritance chain to examine based on check direction + const typeToGetChain = isSouceTotaqrget ? sourceType : targetType; + const typeToCheck = isSouceTotaqrget ? targetType : sourceType; + + // Get inheritance chain and check for relationship + const inheritanceChain = this.getTypeInheritanceChain(typeToGetChain); + return inheritanceChain.some((t) => { + return t.symbol === typeToCheck.symbol; + }); + } + + private getTypeInheritanceChain(type: ts.Type): ts.Type[] { + const chain: ts.Type[] = [type]; + const declarations = type.symbol?.getDeclarations() || []; + + for (const declaration of declarations) { + if ( + !ts.isClassDeclaration(declaration) && !ts.isInterfaceDeclaration(declaration) || + !declaration.heritageClauses + ) { + continue; + } + + const heritageClauses = declaration.heritageClauses.filter((clause) => { + return clause.token === ts.SyntaxKind.ExtendsKeyword || clause.token === ts.SyntaxKind.ImplementsKeyword; + }); + + for (const clause of heritageClauses) { + for (const typeExpr of clause.types) { + const baseType = this.tsTypeChecker.getTypeAtLocation(typeExpr.expression); + chain.push(baseType, ...this.getTypeInheritanceChain(baseType)); + } + } + } + + return chain; + } + + // Check if a type string has an equivalent primitive/wrapper type in a set + private static areWrapperAndPrimitiveTypesEqual(typeStr: string, typeSet: Set): boolean { + const typePairs = [ + ['String', 'string'], + ['Number', 'number'], + ['Boolean', 'boolean'] + ]; + + for (const [wrapper, primitive] of typePairs) { + if (typeStr === wrapper && typeSet.has(primitive) || typeStr === primitive && typeSet.has(wrapper)) { + return true; + } + } + return false; + } + + private isDerivedTypeAssignable(derivedType: ts.Type, baseType: ts.Type): boolean { + const baseSymbol = baseType.getSymbol(); + const derivedSymbol = derivedType.getSymbol(); + + if (!baseSymbol || !derivedSymbol) { + return false; + } + const baseDeclarations = baseSymbol.getDeclarations(); + const derivedDeclarations = derivedSymbol.getDeclarations(); + + if (!baseDeclarations || !derivedDeclarations) { + return false; + } + const baseTypeNode = baseDeclarations[0]; + const derivedTypeNode = derivedDeclarations[0]; + + if ( + baseTypeNode && + derivedTypeNode && + ts.isClassDeclaration(baseTypeNode) && + ts.isClassDeclaration(derivedTypeNode) + ) { + const baseTypes = this.tsTypeChecker.getTypeAtLocation(derivedTypeNode).getBaseTypes(); + const baseTypesExtends = baseTypes?.some((t) => { + return t === baseType; + }); + if (baseTypesExtends) { + return true; + } + } + + return false; + } + + // 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 TypeScriptLinter.normalizeTypeString(this.tsTypeChecker.typeToString(t)); + }); + } + return [TypeScriptLinter.normalizeTypeString(this.tsTypeChecker.typeToString(type))]; + } + + // Normalize type string to handle primitive wrapper types consistently + private static normalizeTypeString(typeStr: string): string { + // Handle all primitive wrapper types + const wrapperToPrimitive: Record = { + String: 'string', + Number: 'number', + Boolean: 'boolean' + }; + + // Replace wrapper types with their primitive counterparts + let normalized = typeStr; + for (const [wrapper, primitive] of Object.entries(wrapperToPrimitive)) { + normalized = normalized.replace(new RegExp(wrapper, 'g'), primitive); + } + return normalized; + } + + private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { + for (const member of classDecl.members) { if (member.name?.getText() === methodName) { if (ts.isPropertyDeclaration(member)) { this.incrementCounters(member, FaultID.MethodOverridingField); @@ -3667,38 +4761,48 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!ts.isIdentifier(node)) { return; } + this.checkCollectionsSymbol(node); this.handleInterfaceImport(node); + this.checkAsonSymbol(node); const tsIdentifier = node; + this.handleTsInterop(tsIdentifier, () => { + const parent = tsIdentifier.parent; + if (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'; + const isNewArkTS = this.options.arkts2; + if (isNewArkTS) { + this.checkWorkerSymbol(tsIdentSym, node); + this.checkConcurrencySymbol(tsIdentSym, node); + } + const isGlobalThis = tsIdentifier.text === 'globalThis'; if ( isGlobalThis && (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 ) { - this.handleGlobalThisCase(tsIdentifier, isArkTs2); + this.handleGlobalThisCase(tsIdentifier, isNewArkTS); } else { - if (isArkTs2) { + if (isNewArkTS) { this.checkLimitedStdlibApi(tsIdentifier, tsIdentSym); } this.handleRestrictedValues(tsIdentifier, tsIdentSym); } - if (isArkTs2 && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { + if (isNewArkTS && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { this.incrementCounters(node, FaultID.ArgumentsObject); } - - if (isArkTs2) { - this.checkWorkerSymbol(tsIdentSym, node); - this.checkCollectionsSymbol(tsIdentSym, node); - this.checkAsonSymbol(tsIdentSym, node); - } + this.checkInvalidNamespaceUsage(node); } private handlePropertyDescriptorInScenarios(node: ts.Node): void { @@ -3773,33 +4877,54 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - 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); + private checkInvalidNamespaceUsage(node: ts.Identifier): void { + if (!this.options.arkts2) { return; } - faultId = FaultID.GlobalThisError; - - if (ts.isPropertyAccessExpression(node.parent)) { - const parentExpression = node.parent.parent; - if ( + if (ts.isNamespaceImport(node.parent)) { + return; + } + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + if (!symbol) { + return; + } + const isNamespace = symbol.declarations?.some((decl) => { + return ts.isNamespaceImport(decl); + }); + if (!isNamespace) { + return; + } + const parent = node.parent; + const isValidUsage = ts.isPropertyAccessExpression(parent) && parent.expression === node; + if (!isValidUsage) { + this.incrementCounters(node, FaultID.NoImportNamespaceStarAsVar); + } + } + + private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { + let faultId = FaultID.GlobalThis; + 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); + this.incrementCounters(targetNode, faultId); } // hard-coded alternative to TypeScriptLinter.advancedClassChecks @@ -3891,13 +5016,40 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + this.handleIllegalSymbolUsage(tsIdentifier, tsIdentSym); + } + + private handleIllegalSymbolUsage(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol): void { 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); + return; + } + + const typeName = tsIdentifier.getText(); + const isWrapperObject = typeName === 'Number' || typeName === 'String' || typeName === 'Boolean'; + if (isWrapperObject) { + return; } + + // Special-case element-access cast for autofix: (X as object)["prop"] + const asExpr = tsIdentifier.parent; + let elemAccess: ts.ElementAccessExpression | undefined; + + if ( + ts.isAsExpression(asExpr) && + ts.isParenthesizedExpression(asExpr.parent) && + ts.isElementAccessExpression(asExpr.parent.parent) && + ts.isStringLiteral(asExpr.parent.parent.argumentExpression) + ) { + // only care if it’s literally “as object” && static-class casts + if (asExpr.type.getText() === 'object' && tsIdentSym.flags & ts.SymbolFlags.Class) { + elemAccess = asExpr.parent.parent; + } + } + + const autofix = elemAccess ? this.autofixer?.fixPropertyAccessByIndex(elemAccess) : undefined; + const faultId = this.options.arkts2 ? FaultID.ClassAsObjectError : FaultID.ClassAsObject; + this.incrementCounters(tsIdentifier, faultId, autofix); } private isElementAcessAllowed(type: ts.Type, argType: ts.Type): boolean { @@ -3927,18 +5079,118 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { (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) + 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); + if (this.options.arkts2 && this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, TsUtils.isTuple)) { + this.handleTupleIndex(tsElementAccessExpr); + } + + 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.checkPropertyAccessByIndex(tsElementAccessExpr, tsElemAccessBaseExprType, tsElemAccessArgType); + this.checkArrayUsageWithoutBound(tsElementAccessExpr); + this.checkArrayIndexType(tsElemAccessBaseExprType, tsElemAccessArgType, tsElementAccessExpr); + this.fixJsImportElementAccessExpression(tsElementAccessExpr); + this.checkInterOpImportJsIndex(tsElementAccessExpr); + this.checkEnumGetMemberValue(tsElementAccessExpr); + this.handleNoDeprecatedApi(tsElementAccessExpr); + } + + private handleTupleIndex(expr: ts.ElementAccessExpression): void { + const value = expr.argumentExpression; + + if (this.isArgumentConstDotZero(value)) { + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + return; + } + + if (ts.isNumericLiteral(value)) { + const indexText = value.getText(); + const indexValue = Number(indexText); + const isValid = Number.isInteger(indexValue) && indexValue >= 0; + + if (!isValid) { + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + } + return; + } + + if (ts.isPrefixUnaryExpression(value)) { + const { operator, operand } = value; + const resolved = this.evaluateValueFromDeclaration(operand); + + if (typeof resolved === 'number') { + const final = operator === ts.SyntaxKind.MinusToken ? -resolved : resolved; + const isValid = Number.isInteger(final) && final >= 0; + if (!isValid) { + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + } + return; + } + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + return; + } + + const resolved = this.evaluateValueFromDeclaration(value); + if (typeof resolved === 'number') { + const isValid = Number.isInteger(resolved) && resolved >= 0; + if (!isValid) { + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + } + return; + } + + this.incrementCounters(expr as ts.Node, FaultID.TupleIndex); + } + + private isArgumentConstDotZero(expr: ts.Expression): boolean { + if (ts.isNumericLiteral(expr)) { + return expr.getText().endsWith('.0'); + } + + if (ts.isPrefixUnaryExpression(expr) && ts.isNumericLiteral(expr.operand)) { + return expr.operand.getText().endsWith('.0'); + } + + if (ts.isIdentifier(expr)) { + const declaration = this.tsUtils.getDeclarationNode(expr); + if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) { + const init = declaration.initializer; + + if (ts.isNumericLiteral(init)) { + return init.getText().endsWith('.0'); + } + + if (ts.isPrefixUnaryExpression(init) && ts.isNumericLiteral(init.operand)) { + return init.operand.getText().endsWith('.0'); + } + } + } + + return false; + } + + private checkPropertyAccessByIndex( + tsElementAccessExpr: ts.ElementAccessExpression, + tsElemAccessBaseExprType: ts.Type, + tsElemAccessArgType: ts.Type + ): void { + const tsElementAccessExprSymbol = this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression); + const isSet = TsUtils.isSetExpression(tsElementAccessExpr); const isSetIndexable = isSet && @@ -3953,28 +5205,37 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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) + 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); + return; } - if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + if (this.isStaticClassAccess(tsElementAccessExpr)) { + return; } - if (this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isIndexableArray)) { - this.handleIndexNegative(node); + + const autofix = this.autofixer?.fixPropertyAccessByIndex(tsElementAccessExpr); + this.incrementCounters(tsElementAccessExpr, FaultID.PropertyAccessByIndex, autofix); + } + + /** + * Returns true if this element-access is a static-class cast (e.g., (A as object)["foo"]). + */ + private isStaticClassAccess(expr: ts.ElementAccessExpression): boolean { + const inner = expr.expression; + if ( + ts.isParenthesizedExpression(inner) && + ts.isAsExpression(inner.expression) && + ts.isIdentifier(inner.expression.expression) + ) { + const sym = this.tsTypeChecker.getSymbolAtLocation(inner.expression.expression); + return !!(sym && sym.flags & ts.SymbolFlags.Class); } - this.checkArrayUsageWithoutBound(tsElementAccessExpr); - this.checkArrayIndexType(tsElemAccessBaseExprType, tsElemAccessArgType, tsElementAccessExpr); - this.fixJsImportElementAccessExpression(tsElementAccessExpr); - this.checkInterOpImportJsIndex(tsElementAccessExpr); - this.checkEnumGetMemberValue(tsElementAccessExpr); + return false; } private checkInterOpImportJsIndex(expr: ts.ElementAccessExpression): void { @@ -4021,7 +5282,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - const argExpr = TypeScriptLinter.getUnwrappedArgumentExpression(expr.argumentExpression); const validStringLiteralTypes = [ STRINGLITERAL_INT, STRINGLITERAL_BYTE, @@ -4032,19 +5292,14 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const argTypeString = this.tsTypeChecker.typeToString(argType); if (this.tsUtils.isNumberLikeType(argType)) { - this.handleNumericArgument(argExpr, expr.argumentExpression, argType); + this.handleNumericArgument(expr.argumentExpression, argType); } else if (!validStringLiteralTypes.includes(argTypeString)) { - this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + this.incrementCounters(expr.argumentExpression, 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 { + private handleNumericArgument(argExpr: 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); @@ -4053,7 +5308,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const containsDot = argText.includes('.'); if (!isInteger || containsDot) { - const autofix = this.autofixer?.fixArrayIndexExprType(isAsExpression ? asExpr : argExpr); + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); } } else if (this.tsTypeChecker.typeToString(argType) === 'number') { @@ -4089,18 +5344,15 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const isNumericInitializer = initializer && ts.isNumericLiteral(initializer); const initializerNumber = isNumericInitializer ? Number(initializerText) : NaN; const isUnsafeNumber = isNumericInitializer && !Number.isInteger(initializerNumber); + const containsDot = initializerText.includes('.'); - if (isUnsafeNumber) { + if (containsDot || isUnsafeNumber || initializerText === 'undefined') { 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 { + private evaluateValueFromDeclaration(argExpr: ts.Expression): number | null | 'skip' { const declaration = this.tsUtils.getDeclarationNode(argExpr); if (!declaration) { return null; @@ -4110,18 +5362,25 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return null; } - const initializer = declaration.initializer; - if (!initializer) { - return null; + if (declaration.type !== undefined && declaration.type.getText() !== NUMBER_LITERAL) { + return 'skip'; } - if (!ts.isNumericLiteral(initializer)) { + const initializer = declaration.initializer; + if (!initializer) { return null; } - - const numericValue = Number(initializer.text); - if (!Number.isInteger(numericValue)) { - return null; + let numericValue: number | null = null; + if (ts.isNumericLiteral(initializer)) { + numericValue = Number(initializer.text); + } else if (ts.isPrefixUnaryExpression(initializer) && ts.isNumericLiteral(initializer.operand)) { + const rawValue = Number(initializer.operand.text); + numericValue = + initializer.operator === ts.SyntaxKind.MinusToken ? + -rawValue : + initializer.operator === ts.SyntaxKind.PlusToken ? + rawValue : + null; } return numericValue; @@ -4136,9 +5395,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (ts.isBinaryExpression(argExpr)) { evaluatedValue = this.evaluateNumericValueFromBinaryExpression(argExpr); } else { - evaluatedValue = this.evaluateValueFromDeclaration(argExpr); + const evalResult = this.evaluateValueFromDeclaration(argExpr); + if (evalResult === 'skip') { + return false; + } + evaluatedValue = evalResult; } - const valueString = String(evaluatedValue); if (evaluatedValue === null) { return false; @@ -4147,21 +5409,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!Number.isInteger(evaluatedValue)) { return false; } - // floating points that can be converted to int should be fine, so as long as no floating point is here, we should be fine. + + const valueString = String(evaluatedValue); if (valueString.includes('.') && !valueString.endsWith('.0')) { return false; } - return evaluatedValue >= 0 && !valueString.includes('.'); - } - - 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); - } + return evaluatedValue >= 0; } private handleEnumMember(node: ts.Node): void { @@ -4228,6 +5482,15 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!initializer) { return; } + if (ts.isAsExpression(initializer) || ts.isTypeAssertionExpression(initializer)) { + const typeNode = ts.isAsExpression(initializer) ? initializer.type : initializer.type; + + if (typeNode.kind === ts.SyntaxKind.NumberKeyword) { + this.incrementCounters(enumMember, FaultID.EnumMemberNonConstInit); + return; + } + } + let value; if (ts.isNumericLiteral(initializer)) { value = parseFloat(initializer.text); @@ -4264,11 +5527,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { this.handleStdlibAPICall(tsCallExpr, calleeSym, name, parName); this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); - } else { - this.handleBuiltinThisArgs(tsCallExpr, calleeSym, name, parName); + } else if (parName) { + this.handleSdkApiThisArgs(tsCallExpr, calleeSym, name, parName); + this.handleSdkApiThisArgs(tsCallExpr, calleeSym, name, parName, true); } if (TsUtils.symbolHasEsObjectType(calleeSym)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + 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 @@ -4323,6 +5587,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } + if (ts.isCallExpression(tsCallExpr) && tsCallExpr.expression.kind === ts.SyntaxKind.SuperKeyword) { + return; + } const node = ts.isCallExpression(tsCallExpr) ? tsCallExpr.expression : tsCallExpr.typeName; const constructorType = this.tsTypeChecker.getTypeAtLocation(node); const callSignatures = constructorType.getCallSignatures(); @@ -4354,191 +5621,237 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private handleCallExpression(node: ts.Node): void { - const tsCallExpr = node as ts.CallExpression; - this.handleStateStyles(tsCallExpr); - this.handleBuiltinCtorCallSignature(tsCallExpr); - this.handleInteropAwaitImport(tsCallExpr); - - if (this.options.arkts2 && tsCallExpr.typeArguments !== undefined) { - this.handleSdkPropertyAccessByIndex(tsCallExpr); + private handleCallExpression(callExpr: ts.CallExpression): void { + this.checkSdkAbilityLifecycleMonitor(callExpr); + this.handleCallExpressionForUI(callExpr); + this.handleBuiltinCtorCallSignature(callExpr); + this.handleSdkConstructorIfaceForCallExpression(callExpr); + if (this.options.arkts2 && callExpr.typeArguments !== undefined) { + this.handleSdkPropertyAccessByIndex(callExpr); } - const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); - this.handleImportCall(tsCallExpr); - this.handleRequireCall(tsCallExpr); + const calleeSym = this.tsUtils.trueSymbolAtLocation(callExpr.expression); + const callSignature = this.tsTypeChecker.getResolvedSignature(callExpr); + this.handleImportCall(callExpr); + this.handleRequireCall(callExpr); if (calleeSym !== undefined) { - this.processCalleeSym(calleeSym, tsCallExpr); + this.processCalleeSym(calleeSym, callExpr); } if (callSignature !== undefined) { if (!this.tsUtils.isLibrarySymbol(calleeSym)) { - this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); - this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + this.handleStructIdentAndUndefinedInArgs(callExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(callExpr, callSignature); } else if (this.options.arkts2) { - this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(callExpr, callSignature); } + this.handleNotsLikeSmartTypeOnCallExpression(callExpr, callSignature); } - this.handleInteropForCallExpression(tsCallExpr); - this.handleLibraryTypeCall(tsCallExpr); + this.handleInteropForCallExpression(callExpr); + this.handleLibraryTypeCall(callExpr); if ( - ts.isPropertyAccessExpression(tsCallExpr.expression) && - this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression) + ts.isPropertyAccessExpression(callExpr.expression) && + this.tsUtils.hasEsObjectType(callExpr.expression.expression) ) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(callExpr, 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.handleLimitedVoidWithCall(callExpr); + this.fixJsImportCallExpression(callExpr); + this.handleInteropForCallJSExpression(callExpr, calleeSym, callSignature); + this.handleNoTsLikeFunctionCall(callExpr); + this.handleObjectLiteralInFunctionArgs(callExpr); + this.handleSdkGlobalApi(callExpr); + this.handleObjectLiteralAssignmentToClass(callExpr); + this.checkRestrictedAPICall(callExpr); + this.handleNoDeprecatedApi(callExpr); + this.handleFunctionReturnThisCall(callExpr); + this.handlePromiseTupleGeneric(callExpr); + this.isSelectOfArkUI(callExpr, callSignature); + this.handleTupleGeneric(callExpr); + } + + private isSelectOfArkUI(callExpr: ts.CallExpression, signature: ts.Signature | undefined): void { + if (!this.options.arkts2) { + return; } - this.handleAppStorageCallExpression(tsCallExpr); - this.fixJsImportCallExpression(tsCallExpr); - this.handleInteropForCallJSExpression(tsCallExpr, calleeSym, callSignature); - this.handleNoTsLikeFunctionCall(tsCallExpr); - this.handleObjectLiteralInFunctionArgs(tsCallExpr); - this.handleTaskPoolDeprecatedUsages(tsCallExpr); - this.handleSdkDuplicateDeclName(tsCallExpr); - } + if (callExpr.expression.getText() !== SELECT_IDENTIFIER) { + return; + } - handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { - if (!this.options.arkts2) { + /* + * for some reason UI component methods signatures cannot be accessed through here, + * there should be no signature declaration of this callExpression, + * if there is signature declaration we will assume this is not an ArkUI component + */ + if (signature?.getDeclaration()) { 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); + const insideArkUi = this.isInComponentBlock(callExpr.getSourceFile()); + if (!insideArkUi) { + return; } - } - private handleAppStorageCallExpression(tsCallExpr: ts.CallExpression): void { - if (!this.options.arkts2 || !tsCallExpr) { + const args = callExpr.arguments; + if (args.length !== 1) { return; } - if (!TsUtils.isAppStorageAccess(tsCallExpr)) { + const arg = args[0]; + const argumentType = this.tsTypeChecker.getTypeAtLocation(arg); + const argumentTypeString = this.tsTypeChecker.typeToString(argumentType); + + if (SELECT_OPTIONS.includes(argumentTypeString)) { return; } - let varDecl: ts.VariableDeclaration | undefined; - let parent = tsCallExpr.parent; + this.incrementCounters(arg, FaultID.StructuralIdentity); + } - while (parent) { - if (ts.isVariableDeclaration(parent)) { - varDecl = parent; + private isInComponentBlock(sourceFile: ts.SourceFile): boolean { + void this; + let isInside = false; + for (const statement of sourceFile.statements) { + statement.forEachChild((node) => { + if (node.getText() === COMPONENT_DECORATOR) { + isInside = true; + } + }); + if (isInside) { break; } - parent = parent.parent; } - if (!varDecl || varDecl.type) { + return isInside; + } + + private handleTupleGeneric(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + if (!ts.isPropertyAccessExpression(callExpr.expression)) { + return; + } + const accessedProperty = callExpr.expression; + + if (!ts.isIdentifier(accessedProperty.expression)) { 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 (accessedProperty.expression.text !== TASKPOOL) { + return; + } - if (isNumberGeneric && !isNumberReturnType) { - const autofix = this.autofixer?.fixAppStorageCallExpression(tsCallExpr); - this.incrementCounters(tsCallExpr, FaultID.NumericSemantics, autofix); + if (!callExpr.typeArguments) { + return; + } + + if (callExpr.parent) { + callExpr.typeArguments.forEach((node) => { + if (ts.isTupleTypeNode(node)) { + this.incrementCounters(node, FaultID.NotSupportTupleGenericValidation); + } + }); } } - handleInteropForCallJSExpression( - tsCallExpr: ts.CallExpression, - sym: ts.Symbol | undefined, - callSignature: ts.Signature | undefined - ): void { - if (!callSignature) { + private handleCallExpressionForUI(node: ts.CallExpression): void { + this.handleStateStyles(node); + this.handleCallExpressionForRepeat(node); + this.handleNodeForWrappedBuilder(node); + this.handleCallExpressionForSerialization(node); + } + + handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { return; } - if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature) && this.options.arkts2) { - if (sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - this.incrementCounters( - tsCallExpr, - ts.isPropertyAccessExpression(tsCallExpr.expression) ? - FaultID.InteropCallObjectMethods : - FaultID.CallJSFunction - ); + + const expression = callExpr.expression; + const type = this.tsTypeChecker.getTypeAtLocation(expression); + const typeText = this.tsTypeChecker.typeToString(type); + + if (LIKE_FUNCTION !== typeText) { + return; + } + if (ts.isNewExpression(expression) || ts.isCallExpression(expression)) { + const exprIndentifier = expression.expression; + const typeExprIndent = this.tsTypeChecker.getTypeAtLocation(exprIndentifier); + const typeTextExprIndent = this.tsTypeChecker.typeToString(typeExprIndent); + if (typeTextExprIndent === LIKE_FUNCTION_CONSTRUCTOR) { + this.incrementCounters(expression, FaultID.ExplicitFunctionType); } + } else { + const autofix = this.autofixer?.fixNoTsLikeFunctionCall(callExpr); + this.incrementCounters(expression, FaultID.ExplicitFunctionType, autofix); } } - private handleInteropForCallExpression(tsCallExpr: ts.CallExpression): void { + handleInteropForCallJSExpression( + tsCallExpr: ts.CallExpression, + sym: ts.Symbol | undefined, + callSignature: ts.Signature | undefined + ): void { if (!this.options.arkts2 || !this.useStatic) { return; } + if (ts.isAwaitExpression(tsCallExpr.parent) || ts.isTypeOfExpression(tsCallExpr.parent)) { + return; + } - const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); - if (!callSignature) { + if (!callSignature || this.isDeclaredInArkTs2(callSignature)) { return; } - if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + if (!sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { return; } - this.checkInteropFunctionParameters(callSignature, tsCallExpr); - this.checkForReflectAPIUse(callSignature, tsCallExpr); + const autofix = this.autofixer?.fixInteropInvokeExpression(tsCallExpr); + + this.incrementCounters( + tsCallExpr, + ts.isPropertyAccessExpression(tsCallExpr.expression) ? FaultID.InteropCallObjectMethods : FaultID.CallJSFunction, + autofix + ); } - private isExportedEntityDeclaredInJs(exportDecl: ts.ExportDeclaration): boolean { + private handleInteropForCallExpression(tsCallExpr: ts.CallExpression): void { if (!this.options.arkts2 || !this.useStatic) { - return false; + return; } - if (!exportDecl.exportClause || !ts.isNamedExports(exportDecl.exportClause)) { - return false; + const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); + if (!callSignature) { + return; } - for (const exportSpecifier of exportDecl.exportClause.elements) { - const identifier = exportSpecifier.name; - if (this.tsUtils.isImportedFromJS(identifier)) { - return true; - } + if (!this.isDeclaredInArkTs2(callSignature)) { + return; } - return false; + this.checkForForbiddenAPIs(callSignature, tsCallExpr); } - private isExportedEntityDeclaredInArkTs1(exportDecl: ts.ExportDeclaration): boolean | undefined { + private isExportedEntityDeclaredInJs(exportDecl: ts.ExportDeclaration): boolean { if (!this.options.arkts2 || !this.useStatic) { return false; } - if (!exportDecl.exportClause || !ts.isNamedExports(exportDecl.exportClause)) { - 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 (const exportSpecifier of exportDecl.exportClause.elements) { - const identifier = exportSpecifier.name; - - if (this.tsUtils.isExportImportedFromArkTs1(identifier, exportDecl)) { + // 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; } } @@ -4546,7 +5859,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } - private static isDeclaredInArkTs2(callSignature: ts.Signature): boolean | undefined { + private isDeclaredInArkTs2(callSignature: ts.Signature): boolean | undefined { const declarationSourceFile = callSignature?.declaration?.getSourceFile(); if (!declarationSourceFile) { return undefined; @@ -4554,49 +5867,80 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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) { + + if (this.tsUtils.isArkts12File(declarationSourceFile)) { return true; } 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)) { - return; + private checkRestrictedAPICall(node: ts.CallExpression): void { + if (TypeScriptLinter.isReflectAPICall(node)) { + this.incrementCounters(node.parent, FaultID.InteropCallReflect); + } + } + + static isReflectAPICall(callExpr: ts.CallExpression): boolean { + if (ts.isPropertyAccessExpression(callExpr.expression)) { + const expr = callExpr.expression.expression; + if (ts.isIdentifier(expr) && expr.text === REFLECT_LITERAL) { + return true; } + } - const argument = tsCallExpr.arguments[index]; - if (!argument) { - return; + if (ts.isElementAccessExpression(callExpr.expression)) { + const expr = callExpr.expression.expression; + if (ts.isIdentifier(expr) && expr.text === REFLECT_LITERAL) { + return true; } + } + return false; + } - if (this.tsTypeChecker.getTypeAtLocation(argument).isClass()) { - this.incrementCounters(tsCallExpr, FaultID.InteropCallObjectParam); - return; + private shouldCheckForForbiddenAPI(declaration: ts.SignatureDeclaration | ts.JSDocSignature): boolean { + for (const parameter of declaration.parameters) { + if (ts.isJSDocParameterTag(parameter)) { + continue; + } + const parameterType = this.tsTypeChecker.getTypeAtLocation(parameter); + const parameterTypeString = this.tsTypeChecker.typeToString(parameterType); + + if (parameterTypeString === OBJECT_LITERAL) { + return true; } } + + return false; } - private checkForReflectAPIUse(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): void { + private checkForForbiddenAPIs(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): void { if (!callSignature.declaration) { return; } + if (!this.shouldCheckForForbiddenAPI(callSignature.declaration)) { + return; + } + const functionSymbol = this.getFunctionSymbol(callSignature.declaration); const functionDeclaration = functionSymbol?.valueDeclaration; if (!functionDeclaration) { return; } - if ( - TypeScriptLinter.isFunctionLike(functionDeclaration) && - TypeScriptLinter.containsReflectAPI(functionDeclaration) - ) { - this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallReflect); + 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; } } @@ -4644,8 +5988,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private handleGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, + callSignature?: ts.Signature ): void { /* @@ -4659,20 +6003,20 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); return; } - this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); - this.checkTypeArgumentsForGenericCallWithNoTypeArgsNumber(callLikeExpr, callSignature); + if (callSignature) { + this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); + } } - private static isInvalidBuiltinGenericConstructorCall(newExpression: ts.CallExpression | ts.NewExpression): boolean { - if (!ts.isNewExpression(newExpression)) { - return false; - } + private static isInvalidBuiltinGenericConstructorCall( + newExpression: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments + ): boolean { const isBuiltin = BUILTIN_GENERIC_CONSTRUCTORS.has(newExpression.expression.getText().replace(/Constructor$/, '')); return isBuiltin && (!newExpression.typeArguments || newExpression.typeArguments.length === 0); } private checkTypeArgumentsForGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, callSignature: ts.Signature ): void { if (ts.isNewExpression(callLikeExpr) && this.isNonGenericClass(callLikeExpr)) { @@ -4692,81 +6036,167 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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 providedTypeArgs = callLikeExpr.typeArguments; + const startTypeArg = providedTypeArgs?.length ?? 0; + let shouldReportError = startTypeArg !== resolvedTypeArgs.length; + const shouldCheck = this.shouldCheckGenericCallExpression(callLikeExpr as ts.CallExpression); + if ( + this.options.arkts2 && + (ts.isNewExpression(callLikeExpr) || ts.isCallExpression(callLikeExpr) && shouldCheck) + ) { + shouldReportError = this.shouldReportGenericTypeArgsError( + callLikeExpr, + resolvedTypeArgs, + providedTypeArgs, + startTypeArg, + shouldReportError + ); + if (shouldReportError) { 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; - } - } + this.checkForUnknownTypeInNonArkTS2(callLikeExpr, resolvedTypeArgs, startTypeArg); } } - private isNonGenericClass(expression: ts.NewExpression): boolean { - const declaration = this.tsUtils.getDeclarationNode(expression.expression); - return !!declaration && ts.isClassDeclaration(declaration) && !declaration.typeParameters; + private shouldCheckGenericCallExpression(callExpr: ts.CallExpression): boolean { + const signature = this.tsTypeChecker.getResolvedSignature(callExpr); + if (!signature?.declaration) { + return false; + } + const typeParamsSafeToInfer = this.areTypeParametersReturnTypeOnly(signature.declaration); + if (!typeParamsSafeToInfer) { + return false; + } + return TypeScriptLinter.isInStrictTypeContext(callExpr); } - checkTypeArgumentsForGenericCallWithNoTypeArgsNumber( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature - ): void { - if (TypeScriptLinter.isArrayFromCall(callLikeExpr)) { - return; + private areTypeParametersReturnTypeOnly(decl: ts.SignatureDeclaration | ts.JSDocSignature): boolean { + if (!decl.typeParameters?.length) { + return false; } - 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 + const typeParamNames = new Set( + decl.typeParameters.map((tp) => { + return tp.name.getText(); + }) ); - if (!signDecl?.typeArguments) { - return; + let affectsParams = false; + + decl.parameters.forEach((param) => { + if (param.type && this.containsTypeParameters(param.type, typeParamNames)) { + affectsParams = true; + } + }); + + return !affectsParams; + } + + private containsTypeParameters(node: ts.Node, typeParamNames: Set): boolean { + let found = false; + ts.forEachChild(node, (child) => { + if (ts.isIdentifier(child) && typeParamNames.has(child.text)) { + found = true; + } + if (!found) { + found = this.containsTypeParameters(child, typeParamNames); + } + }); + return found; + } + + private static isInStrictTypeContext(callExpr: ts.CallExpression): boolean { + const parent = callExpr.parent; + + if ((ts.isVariableDeclaration(parent) || ts.isPropertyDeclaration(parent)) && parent.type) { + return true; } - let hasNumberType = false; - const resolvedTypeArgs = signDecl.typeArguments; - const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; + + if (ts.isAsExpression(parent) || ts.isTypeAssertionExpression(parent)) { + return true; + } + + if (ts.isCallExpression(parent.parent) && parent.parent.typeArguments) { + return true; + } + return false; + } + + private checkForUnknownTypeInNonArkTS2( + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, + resolvedTypeArgs: ts.NodeArray, + startTypeArg: number + ): void { 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; + + /* + * 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) { + const autofix = ts.isCallExpression(callLikeExpr) ? + this.autofixer?.fixGenericCallNoTypeArgsForUnknown(callLikeExpr) : + undefined; + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); break; } } - 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 shouldReportGenericTypeArgsError( + callLikeExpr: ts.CallExpression | ts.NewExpression, + resolvedTypeArgs: ts.NodeArray, + providedTypeArgs: ts.NodeArray | undefined, + startTypeArg: number, + initialErrorState: boolean + ): boolean { + const typeParameters = this.getOriginalTypeParameters(callLikeExpr); + if (!typeParameters || typeParameters.length === 0) { + return initialErrorState; + } + const optionalParamsCount = typeParameters.filter((param, index) => { + return param.default && (!providedTypeArgs || index >= providedTypeArgs.length); + }).length; + if (optionalParamsCount === 0) { + return initialErrorState; + } + return startTypeArg + optionalParamsCount !== resolvedTypeArgs.length; + } + + private getOriginalTypeParameters( + callLikeExpr: ts.CallExpression | ts.NewExpression + ): ts.TypeParameterDeclaration[] | undefined { + const typeChecker = this.tsTypeChecker; + const expressionType = typeChecker.getTypeAtLocation(callLikeExpr.expression); + const declarations = expressionType.symbol?.declarations; + if (!declarations || declarations.length === 0) { + return undefined; + } + for (const decl of declarations) { + if (ts.isFunctionDeclaration(decl) && decl.typeParameters) { + return [...decl.typeParameters]; + } + if (ts.isMethodDeclaration(decl) && decl.typeParameters) { + return [...decl.typeParameters]; + } + if (ts.isClassDeclaration(decl) && decl.typeParameters) { + return [...decl.typeParameters]; + } + if (ts.isInterfaceDeclaration(decl) && decl.typeParameters) { + return [...decl.typeParameters]; + } } + return undefined; + } + + 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 { @@ -4799,6 +6229,77 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private handleFunctionReturnThisCall(node: ts.CallExpression | ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + const args = node.arguments; + const isUnsafeCallee = this.checkUnsafeFunctionCalleeName(node.expression); + if (!isUnsafeCallee) { + return; + } + if (!args) { + return; + } + if (args.length === 0) { + return; + } + const isForbidden = this.isForbiddenBodyArgument(args[0]); + if (isForbidden) { + this.incrementCounters(node, FaultID.NoFunctionReturnThis); + } + } + + private isForbiddenBodyArgument(arg: ts.Expression): boolean { + if ((ts.isStringLiteral(arg) || ts.isNoSubstitutionTemplateLiteral(arg)) && arg.text === FORBIDDEN_FUNCTION_BODY) { + return true; + } + + if (ts.isIdentifier(arg)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(arg); + const decl = symbol?.valueDeclaration; + + if ( + decl && + ts.isVariableDeclaration(decl) && + decl.initializer && + ts.isStringLiteral(decl.initializer) && + decl.initializer.text === FORBIDDEN_FUNCTION_BODY + ) { + return true; + } + } + + return false; + } + + private checkUnsafeFunctionCalleeName(expr: ts.Expression): boolean { + if (ts.isIdentifier(expr) && expr.text === LIKE_FUNCTION) { + return true; + } + + if (ts.isParenthesizedExpression(expr)) { + return this.checkUnsafeFunctionCalleeName(expr.expression); + } + + if (ts.isPropertyAccessExpression(expr)) { + if (expr.name.text === LIKE_FUNCTION) { + return true; + } + return this.checkUnsafeFunctionCalleeName(expr.expression); + } + + if (ts.isCallExpression(expr)) { + return this.checkUnsafeFunctionCalleeName(expr.expression); + } + + if (ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.CommaToken) { + return this.checkUnsafeFunctionCalleeName(expr.right); + } + + return false; + } + private handleStructIdentAndUndefinedInArgs( tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, callSignature: ts.Signature @@ -4829,6 +6330,72 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkAssignmentMatching(tsArg, tsParamType, tsArg); } } + this.checkOnClickCallback(tsCallOrNewExpr); + } + + private checkOnClickCallback(tsCallOrNewExpr: ts.CallExpression | ts.NewExpression): void { + if (!tsCallOrNewExpr.arguments || tsCallOrNewExpr.arguments.length === 0 && this.options.arkts2) { + return; + } + + const isOnClick = + ts.isPropertyAccessExpression(tsCallOrNewExpr.expression) && tsCallOrNewExpr.expression.name.text === 'onClick'; + if (!isOnClick) { + return; + } + + const objType = this.tsTypeChecker.getTypeAtLocation(tsCallOrNewExpr.expression.expression); + const declNode = TsUtils.getDeclaration(objType.getSymbol()); + if (declNode) { + const fileName = declNode.getSourceFile().fileName; + if (!fileName.includes('@ohos/')) { + return; + } + } + + const callback = tsCallOrNewExpr.arguments[0]; + if (!ts.isArrowFunction(callback)) { + return; + } + + this.checkAsyncOrPromiseFunction(callback); + } + + private checkAsyncOrPromiseFunction(callback: ts.ArrowFunction): void { + const returnsPromise = this.checkReturnsPromise(callback); + const isAsync = callback.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.AsyncKeyword; + }); + + if (isAsync || returnsPromise) { + const startPos = callback.modifiers?.[0]?.getStart() ?? callback.getStart(); + const endPos = callback.body.getEnd(); + + const errorNode = { + getStart: () => { + return startPos; + }, + getEnd: () => { + return endPos; + }, + getSourceFile: () => { + return callback.getSourceFile(); + } + } as ts.Node; + + this.incrementCounters(errorNode, FaultID.IncompationbleFunctionType); + } + } + + private checkReturnsPromise(callback: ts.ArrowFunction): boolean { + const callbackType = this.tsTypeChecker.getTypeAtLocation(callback); + const signatures = this.tsTypeChecker.getSignaturesOfType(callbackType, ts.SignatureKind.Call); + if (signatures.length === 0) { + return false; + } + + const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signatures[0]); + return !!returnType.getProperty('then'); } private static readonly LimitedApis = new Map | null; fault: FaultID }>([ @@ -4868,27 +6435,22 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private handleBuiltinThisArgs( + private handleSdkApiThisArgs( callExpr: ts.CallExpression, calleeSym: ts.Symbol, name: string, - parName: string | undefined + parName: string | undefined, + isSdkCommon?: boolean ): void { - if (parName === undefined) { - return; - } - - const builtinThisArgsInfos = TypeScriptLinter.funcMap.get(name); + const builtinThisArgsInfos = isSdkCommon ? + TypeScriptLinter.sdkCommonFuncMap.get(name + '_' + parName) : + TypeScriptLinter.funcMap.get(name); if (!builtinThisArgsInfos) { return; } const sourceFile = calleeSym?.declarations?.[0]?.getSourceFile(); - if (!sourceFile) { - return; - } - - const fileName = path.basename(sourceFile.fileName); + const fileName = path.basename(sourceFile?.fileName + ''); const builtinInfos = builtinThisArgsInfos.get(fileName); if (!(builtinInfos && builtinInfos.size > 0)) { return; @@ -4966,17 +6528,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ); } - private checkConstrutorAccess(newExpr: ts.NewExpression): void { + private checkConstrutorAccess(propertyAccessExpr: ts.PropertyAccessExpression): 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); + if (propertyAccessExpr.name.text === 'constructor') { + this.incrementCounters(propertyAccessExpr, FaultID.NoConstructorOnClass); } } @@ -4984,30 +6542,43 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { 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.ConstructorIface); + const typeDeclaration = TsUtils.getDeclaration(type.symbol); + if (typeDeclaration && ts.isInterfaceDeclaration(typeDeclaration) && type.symbol) { + const filePath = typeDeclaration.getSourceFile().fileName; + this.checkIsConstructorIface(calleeExpr, type.symbol.name, path.basename(filePath)); } } + private checkIsConstructorIface(node: ts.Node, symbol: string, filePath: string): void { + const constructorIfaceSetInfos = Array.from(TypeScriptLinter.ConstructorIfaceSet); + constructorIfaceSetInfos.some((constructorFuncsInfo) => { + const api_name = constructorFuncsInfo.api_info.parent_api[0].api_name; + if ( + symbol === api_name && + (constructorFuncsInfo.file_path.includes(filePath) || constructorFuncsInfo.import_path.includes(filePath)) + ) { + this.incrementCounters(node, FaultID.ConstructorIfaceFromSdk); + return true; + } + return false; + }); + } + private handleNewExpression(node: ts.Node): void { const tsNewExpr = node as ts.NewExpression; - + this.handleNodeForWrappedBuilder(tsNewExpr); this.checkForInterfaceInitialization(tsNewExpr); this.handleSharedArrayBuffer(tsNewExpr); - this.handleSdkDuplicateDeclName(tsNewExpr); - this.checkConstrutorAccess(tsNewExpr); + this.handleSdkGlobalApi(tsNewExpr); this.checkCreatingPrimitiveTypes(tsNewExpr); + this.handleNoDeprecatedApi(tsNewExpr); + this.handleNodeForBuilderNode(tsNewExpr); if (this.options.advancedClassChecks || this.options.arkts2) { const calleeExpr = tsNewExpr.expression; @@ -5035,6 +6606,53 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.handleSendableGenericTypes(tsNewExpr); this.handleInstantiatedJsObject(tsNewExpr, sym); + this.handlePromiseNeedVoidResolve(tsNewExpr); + this.handleFunctionReturnThisCall(tsNewExpr); + this.checkArrayInitialization(tsNewExpr); + } + + handlePromiseNeedVoidResolve(newExpr: ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + + if (!ts.isIdentifier(newExpr.expression) || newExpr.expression.text !== 'Promise') { + return; + } + + const typeArg = newExpr.typeArguments?.[0]; + if (!typeArg) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(typeArg); + if (!(type.getFlags() & ts.TypeFlags.Void)) { + return; + } + + const executor = newExpr.arguments?.[0]; + if (!executor || !ts.isFunctionLike(executor)) { + return; + } + + const resolveParam = executor.parameters[0]; + if (resolveParam?.type) { + if (ts.isFunctionTypeNode(resolveParam.type) && resolveParam.type.parameters.length === 0) { + this.incrementCounters(resolveParam.type, FaultID.PromiseVoidNeedResolveArg); + } + } + if (executor.body) { + ts.forEachChild(executor.body, (node) => { + if ( + ts.isCallExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.text === 'resolve' && + node.arguments.length === 0 + ) { + this.incrementCounters(node, FaultID.PromiseVoidNeedResolveArg); + } + }); + } } private checkCreatingPrimitiveTypes(tsNewExpr: ts.NewExpression): void { @@ -5101,41 +6719,117 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (this.tsUtils.isWrongSendableFunctionAssignment(targetType, exprType)) { this.incrementCounters(tsAsExpr, FaultID.SendableFunctionAsExpr); } + this.handleAsExprStructuralTyping(tsAsExpr, targetType, exprType); + this.handleAsExpressionImport(tsAsExpr); + this.handleNoTuplesArrays(node, targetType, exprType); + this.handleObjectLiteralAssignmentToClass(tsAsExpr); + this.handleArrayTypeImmutable(tsAsExpr, exprType, targetType); + this.handleNotsLikeSmartTypeOnAsExpression(tsAsExpr); + this.handleLimitedVoidTypeOnAsExpression(tsAsExpr); + } + + private handleAsExprStructuralTyping(asExpr: ts.AsExpression, targetType: ts.Type, exprType: ts.Type): void { if ( this.options.arkts2 && - this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, tsAsExpr.expression, true) + this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, asExpr.expression, true) && + this.tsUtils.needToDeduceStructuralIdentity(exprType, targetType, asExpr.expression, true) ) { + if (this.isExemptedAsExpression(asExpr)) { + return; + } if (!this.tsUtils.isObject(exprType)) { - this.incrementCounters(node, FaultID.StructuralIdentity); + this.incrementCounters(asExpr, FaultID.StructuralIdentity); } } - this.handleAsExpressionImport(tsAsExpr); - this.handleNoTuplesArrays(node, targetType, exprType); + } + + private isExemptedAsExpression(node: ts.AsExpression): boolean { + if (!ts.isElementAccessExpression(node.expression)) { + return false; + } + + const sourceType = this.tsTypeChecker.getTypeAtLocation(node.expression); + const targetType = this.tsTypeChecker.getTypeAtLocation(node.type); + const isRecordIndexAccess = (): boolean => { + const exprType = this.tsTypeChecker.getTypeAtLocation(node.expression); + const hasNumberIndex = !!exprType.getNumberIndexType(); + const hasStringIndex = !!exprType.getStringIndexType(); + const hasBooleanIndex = !!exprType.getProperty('true') || !!exprType.getProperty('false'); + + return hasNumberIndex || hasStringIndex || hasBooleanIndex; + }; + + if (isRecordIndexAccess()) { + const targetSymbol = targetType.getSymbol(); + if (targetSymbol && targetSymbol.getName() === 'Array') { + return true; + } + } + const primitiveFlags = ts.TypeFlags.Number | ts.TypeFlags.String | ts.TypeFlags.Boolean; + const objectFlag = ts.TypeFlags.Object; + return ( + sourceType.isUnion() && + sourceType.types.some((t) => { + return t.flags & primitiveFlags; + }) && + sourceType.types.some((t) => { + return t.flags & objectFlag; + }) + ); } private handleAsExpressionImport(tsAsExpr: ts.AsExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + const type = tsAsExpr.type; - const restrictedTypes = [ + const expression = tsAsExpr.expression; + const restrictedPrimitiveTypes = [ ts.SyntaxKind.NumberKeyword, ts.SyntaxKind.BooleanKeyword, ts.SyntaxKind.StringKeyword, - ts.SyntaxKind.BigIntKeyword + ts.SyntaxKind.BigIntKeyword, + ts.SyntaxKind.UndefinedKeyword ]; - if (this.useStatic && this.options.arkts2 && restrictedTypes.includes(type.kind)) { - const expr = ts.isPropertyAccessExpression(tsAsExpr.expression) ? - tsAsExpr.expression.expression : - tsAsExpr.expression; + 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 (ts.isIdentifier(expr)) { - const sym = this.tsUtils.trueSymbolAtLocation(expr); - const decl = TsUtils.getDeclaration(sym); - if (decl?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { - this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); - } + 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; @@ -5159,7 +6853,55 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private handleSharedArrayBuffer(node: ts.TypeReferenceNode | ts.NewExpression): void { + private handleSdkConstructorIfaceForCallExpression(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + let type: ts.Type | undefined; + if (!callExpr.arguments || callExpr.arguments.length === 0) { + if (ts.isPropertyAccessExpression(callExpr.expression)) { + type = this.tsTypeChecker.getTypeAtLocation(callExpr.expression.expression); + } + } + callExpr.arguments.some((args) => { + if (ts.isIdentifier(args)) { + type = this.tsTypeChecker.getTypeAtLocation(args); + } + }); + if (!type) { + return; + } + const decl = TsUtils.getDeclaration(type?.symbol); + if (!decl) { + return; + } + const filePath = TypeScriptLinter.getFileName(decl); + this.checkIsConstructorIface(callExpr, type.symbol.name, filePath); + } + + private static getFileName(decl: ts.Declaration): string { + let filePath = ''; + if ( + ts.isImportSpecifier(decl) && + ts.isImportDeclaration(decl.parent.parent.parent) && + ts.isStringLiteral(decl.parent.parent.parent.moduleSpecifier) + ) { + filePath = decl.parent.parent.parent.moduleSpecifier.text; + } else if ( + ts.isImportClause(decl) && + ts.isImportDeclaration(decl.parent) && + ts.isStringLiteral(decl.parent.moduleSpecifier) + ) { + filePath = decl.parent.moduleSpecifier.text; + } else { + filePath = decl.getSourceFile().fileName; + } + return path.basename(filePath); + } + + private handleSharedArrayBuffer( + node: ts.TypeReferenceNode | ts.NewExpression | ts.ExpressionWithTypeArguments + ): void { if (!this.options.arkts2) { return; } @@ -5168,37 +6910,63 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!ts.isIdentifier(typeNameIdentifier) || typeNameIdentifier.getText() !== ESLIB_SHAREDARRAYBUFFER) { return; } + const symbol = this.tsUtils.trueSymbolAtLocation(typeNameIdentifier); + if (!symbol) { + return; + } + + const isImported = this.sourceFile.statements.some((stmt) => { + if (!ts.isImportDeclaration(stmt)) { + return false; + } + const importClause = stmt.importClause; + if (!importClause?.namedBindings || !ts.isNamedImports(importClause.namedBindings)) { + return false; + } - const decls = this.tsUtils.trueSymbolAtLocation(typeNameIdentifier)?.getDeclarations(); + const elements = importClause.namedBindings.elements.some((element) => { + return element.name.text === ESLIB_SHAREDARRAYBUFFER; + }); + return elements; + }); + if (isImported) { + return; + } + const decls = symbol.getDeclarations(); const isSharedMemoryEsLib = decls?.some((decl) => { const srcFileName = decl.getSourceFile().fileName; return srcFileName.endsWith(ESLIB_SHAREDMEMORY_FILENAME); }); - if (!isSharedMemoryEsLib) { + + 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); - } + + const autofix = this.autofixer?.replaceNode(typeNameIdentifier, 'ArrayBuffer'); + this.incrementCounters(typeNameIdentifier, 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.handleESObjectUsage(typeRef); this.handleBuiltinCtorCallSignature(typeRef); this.handleSharedArrayBuffer(typeRef); - this.handleSdkDuplicateDeclName(typeRef); - + this.handleSdkGlobalApi(typeRef); this.handleSdkConstructorIface(typeRef); - - const isESObject = TsUtils.isEsObjectType(typeRef); - const isPossiblyValidContext = TsUtils.isEsObjectPossiblyAllowed(typeRef); - if (isESObject && !isPossiblyValidContext) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + this.handleNodeForWrappedBuilder(typeRef); + this.handleNoDeprecatedApi(typeRef); + this.handleNodeForBuilderNode(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; } @@ -5221,6 +6989,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.checkNoEnumProp(typeRef); + if (ts.isQualifiedName(typeRef.typeName)) { + this.handleSdkForConstructorFuncs(typeRef.typeName); + } } private checkNoEnumProp(typeRef: ts.TypeReferenceNode): void { @@ -5321,10 +7092,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); if (!!symbol && TsUtils.isEsObjectSymbol(symbol)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; this.incrementCounters(tsTypeExpr, faultId); } - this.handleSdkDuplicateDeclName(tsTypeExpr); + this.handleSdkGlobalApi(tsTypeExpr); } private handleComputedPropertyName(node: ts.Node): void { @@ -5578,6 +7349,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleConstructorDeclaration(node: ts.Node): void { const ctorDecl = node as ts.ConstructorDeclaration; + this.checkDefaultParamBeforeRequired(ctorDecl); this.handleTSOverload(ctorDecl); const paramProperties = ctorDecl.parameters.filter((x) => { return this.tsUtils.hasAccessModifier(x); @@ -5792,16 +7564,13 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleExportDeclaration(node: ts.Node): void { const exportDecl = node as ts.ExportDeclaration; + this.handleInvalidIdentifier(exportDecl); + if (this.isExportedEntityDeclaredInJs(exportDecl)) { this.incrementCounters(node, FaultID.InteropJsObjectExport); return; } - if (this.isExportedEntityDeclaredInArkTs1(exportDecl)) { - this.incrementCounters(node, FaultID.InteropArkTs1ObjectExport); - return; - } - if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(node.parent)) { return; } @@ -5838,33 +7607,139 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } this.checkAssignmentMatching(node, lhsType, expr, true); this.handleObjectLiteralInReturn(returnStat); + this.handleObjectLiteralAssignmentToClass(returnStat); } /** * '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 + * + * Also delegates the object-literal → union rule to `handleObjectLiteralUnionArg`. */ private checkAssignmentMatching( - field: ts.Node, + contextNode: ts.Node, lhsType: ts.Type, rhsExpr: ts.Expression, isNewStructuralCheck: boolean = false ): void { const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); - this.handleNoTuplesArrays(field, lhsType, rhsType); + + // Object-literal to union rule (non-call contexts) + this.handleObjectLiteralUnionArg(lhsType, rhsExpr); + + this.handleNoTuplesArrays(contextNode, lhsType, rhsType); + this.handleArrayTypeImmutable(contextNode, lhsType, rhsType, rhsExpr); // check that 'sendable typeAlias' is assigned correctly if (this.tsUtils.isWrongSendableFunctionAssignment(lhsType, rhsType)) { - this.incrementCounters(field, FaultID.SendableFunctionAssignment); + this.incrementCounters(contextNode, FaultID.SendableFunctionAssignment); } const isStrict = this.tsUtils.needStrictMatchType(lhsType, rhsType); // 'isNewStructuralCheck' means that this assignment scenario was previously omitted, so only strict matches are checked now if (isNewStructuralCheck && !isStrict) { return; } + this.handleStructuralTyping(contextNode, lhsType, rhsType, rhsExpr, isStrict); + this.checkFunctionalTypeCompatibility(lhsType, rhsType, rhsExpr); + } + + /** + * Flags `{ ... }` used where the LHS type is a union with + * more than one non-nullish member and the object literal + * is not already asserted (e.g., `{...} as A`). + * Applies to variable initializers, assignments, call expressions and returns + * that route through `checkAssignmentMatching`. + */ + private handleObjectLiteralUnionArg(lhsType: ts.Type, rhsExpr: ts.Expression): void { + if (!this.options.arkts2) { + return; + } + + if (!ts.isObjectLiteralExpression(rhsExpr) || !lhsType?.isUnion()) { + return; + } + + // Already asserted/cast? Allowed. + const parent = rhsExpr.parent; + if (ts.isAsExpression(parent) || ts.isTypeAssertionExpression(parent)) { + return; + } + + // Allow nullish unions like 'T | null | undefined' + const nonNullishMembers = lhsType.types.filter((t) => { + return !TsUtils.isNullishType(t); + }); + if (nonNullishMembers.length <= 1) { + return; + } + + // Skip any types that are from standard lib + const nonStdlibMembers = nonNullishMembers.filter((t) => { + return !(t.getSymbol() && isStdLibrarySymbol(t.getSymbol())); + }); + + const hasClassOrInterfaceMember = nonStdlibMembers.some((t) => { + const sym = t.aliasSymbol ?? t.getSymbol(); + if (!sym) { + return false; + } + const decls = sym.getDeclarations() ?? []; + + return decls.some((d) => { + return ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d); + }); + }); + if (!hasClassOrInterfaceMember) { + return; + } + + this.incrementCounters(rhsExpr, FaultID.ObjectLiteralUnionNeedsCast); + } + + private handleStructuralTyping( + contextNode: ts.Node, + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression, + isStrict: boolean + ): void { + if (TypeScriptLinter.isValidPromiseReturnedFromAsyncFunction(lhsType, rhsType, rhsExpr)) { + return; + } if (this.tsUtils.needToDeduceStructuralIdentity(lhsType, rhsType, rhsExpr, isStrict)) { - this.incrementCounters(field, FaultID.StructuralIdentity); + this.incrementCounters(contextNode, FaultID.StructuralIdentity); + } + } + + private static isValidPromiseReturnedFromAsyncFunction( + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression + ): boolean { + + /* + * When resolving the contextual type for return expression in async function, the TS compiler + * infers 'PromiseLike' type instead of standard 'Promise' (see following link: + * https://github.com/microsoft/TypeScript/pull/27270). In this special case, we treat + * these two types as equal and only need to validate the type argument. + */ + + if (!ts.isReturnStatement(rhsExpr.parent)) { + return false; } + const enclosingFunction = ts.findAncestor(rhsExpr, ts.isFunctionLike); + if (!TsUtils.hasModifier(enclosingFunction?.modifiers, ts.SyntaxKind.AsyncKeyword)) { + return false; + } + + const lhsPromiseLikeType = lhsType.isUnion() && lhsType.types.find(TsUtils.isStdPromiseLikeType); + if (!lhsPromiseLikeType || !TsUtils.isStdPromiseType(rhsType)) { + return false; + } + + const lhsTypeArg = TsUtils.isTypeReference(lhsPromiseLikeType) && lhsPromiseLikeType.typeArguments?.[0]; + const rhsTypeArg = TsUtils.isTypeReference(rhsType) && rhsType.typeArguments?.[0]; + return lhsTypeArg !== undefined && lhsTypeArg === rhsTypeArg; } private handleDecorator(node: ts.Node): void { @@ -5884,6 +7759,16 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } this.handleNotSupportCustomDecorators(decorator); + switch (decorator.parent.kind) { + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Parameter: + this.handleBuiltinDisableDecorator(decorator); + break; + default: + break; + } } private handleProvideDecorator(node: ts.Node): void { @@ -5966,12 +7851,30 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const typeNode = node.type; - if (typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { + if (typeNode && TsUtils.typeContainsVoid(typeNode)) { this.incrementCounters(typeNode, FaultID.LimitedVoidType); } } + private handleLimitedVoidTypeOnAsExpression(node: ts.AsExpression): void { + if (!this.options.arkts2) { + return; + } + const targetType = this.tsTypeChecker.getTypeAtLocation(node.type); + if (TsUtils.isVoidType(targetType)) { + this.incrementCounters(node.type, FaultID.LimitedVoidType); + } + } + private handleLimitedVoidWithCall(node: ts.CallExpression): void { + if ( + ts.isExpressionStatement(node.parent) || + ts.isVoidExpression(node.parent) || + ts.isArrowFunction(node.parent) || + ts.isConditionalExpression(node.parent) && ts.isExpressionStatement(node.parent.parent) + ) { + return; + } if (!this.options.arkts2) { return; } @@ -5981,12 +7884,44 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const signature = this.tsTypeChecker.getResolvedSignature(node); - if (signature) { - const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signature); - if (this.tsTypeChecker.typeToString(returnType) === 'void') { + if (!signature) { + return; + } + + const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signature); + if (this.tsTypeChecker.typeToString(returnType) !== 'void') { + return; + } + + if (ts.isReturnStatement(node.parent)) { + const functionLike = TypeScriptLinter.findContainingFunction(node); + if (functionLike && TypeScriptLinter.isRecursiveCall(node, functionLike)) { this.incrementCounters(node, FaultID.LimitedVoidType); } + return; + } + + this.incrementCounters(node, FaultID.LimitedVoidType); + } + + private static findContainingFunction(node: ts.Node): ts.FunctionLikeDeclaration | undefined { + while (node) { + if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) { + return node; + } + node = node.parent; } + return undefined; + } + + // Helper function to check if a call is recursive + private static isRecursiveCall(callExpr: ts.CallExpression, fn: ts.FunctionLikeDeclaration): boolean { + return ( + ts.isIdentifier(callExpr.expression) && + ts.isFunctionDeclaration(fn) && + !!fn.name && + fn.name.text === callExpr.expression.text + ); } private handleArrayType(arrayType: ts.Node): void { @@ -6024,8 +7959,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } - const autofix = this.autofixer?.fixDebuggerStatement(node as ts.DebuggerStatement); - this.incrementCounters(node, FaultID.DebuggerStatement, autofix); + + this.incrementCounters(node, FaultID.DebuggerStatement); } private handleTSOverload(decl: ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration): void { @@ -6044,15 +7979,21 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const filterDecl = declarations.filter((name) => { return ts.isFunctionDeclaration(name) || ts.isMethodDeclaration(name); }); - if (filterDecl.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) { + 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 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); } } @@ -6073,37 +8014,45 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private validateSwitchExpression(switchStatement: ts.SwitchStatement): void { - const nodeType = this.tsTypeChecker.getTypeAtLocation(switchStatement.expression); - const typeName = this.tsTypeChecker.typeToString(nodeType); + const expr = switchStatement.expression; + const nodeType = this.tsTypeChecker.getTypeAtLocation(expr); + const { isLiteralInitialized, hasExplicitTypeAnnotation } = this.getDeclarationInfo(expr); + const isUnionType = (nodeType.flags & ts.TypeFlags.Union) !== 0; - const { isLiteralInitialized, isFloatLiteral, hasExplicitTypeAnnotation } = this.getDeclarationInfo( - switchStatement.expression - ); + const isTypeAllowed = (t: ts.Type): boolean => { + const typeText = this.tsTypeChecker.typeToString(t); + return Boolean( + t.flags & ts.TypeFlags.StringLike || + typeText === 'String' || + typeText === 'number' || + t.flags & ts.TypeFlags.NumberLike && (/^\d+$/).test(typeText) || + isLiteralInitialized && !hasExplicitTypeAnnotation || + t.flags & ts.TypeFlags.EnumLike + ); + }; - const isAllowed = - !isUnionType && - (nodeType.flags & ts.TypeFlags.StringLike || - typeName === 'String' || - nodeType.flags & ts.TypeFlags.NumberLike && (/^\d+$/).test(typeName) || - isLiteralInitialized && !hasExplicitTypeAnnotation && !isFloatLiteral || - nodeType.flags & ts.TypeFlags.EnumLike); + let isAllowed = !isUnionType && isTypeAllowed(nodeType); + + if (isUnionType) { + const unionType = nodeType as ts.UnionType; + isAllowed = unionType.types.every(isTypeAllowed); + } if (!isAllowed) { - this.incrementCounters(switchStatement.expression, FaultID.SwitchExpression); + this.incrementCounters(expr, FaultID.SwitchExpression); } } 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 }; + return { isLiteralInitialized: false, hasExplicitTypeAnnotation: false }; } const hasExplicitTypeAnnotation = !!declaration.type; @@ -6111,30 +8060,20 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return { isLiteralInitialized: initializerInfo.isLiteralInitialized, - isFloatLiteral: initializerInfo.isFloatLiteral, hasExplicitTypeAnnotation }; } private static getInitializerInfo(initializer?: ts.Expression): { isLiteralInitialized: boolean; - isFloatLiteral: boolean; } { if (!initializer) { - return { isLiteralInitialized: false, isFloatLiteral: false }; + return { isLiteralInitialized: false }; } 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); - } - } - - return { isLiteralInitialized, isFloatLiteral }; + return { isLiteralInitialized }; } private findDuplicateCases(switchStatement: ts.SwitchStatement): ts.CaseClause[] { @@ -6358,94 +8297,220 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private handleExponentOperation(node: ts.Node): void { + private handleNoTuplesArraysForPropertyAccessExpression(node: ts.PropertyAccessExpression): void { if (!this.options.arkts2) { return; } - const autofix = this.autofixer?.fixExponent(node.parent); - this.incrementCounters(node, FaultID.ExponentOp, autofix); + const lhsType = this.tsTypeChecker.getTypeAtLocation(node.expression); + if (this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple)) { + if (ARRAY_API_LIST.includes(node.name.text)) { + this.incrementCounters(node, FaultID.NoTuplesArrays); + } + } } - private handleNonNullExpression(node: ts.Node): void { - if (!this.options.arkts2) { - return; + isExprReturnedFromAsyncFunction(rhsExpr: ts.Expression | undefined, lhsType: ts.Type): ts.Type | undefined { + void this; + if (!rhsExpr) { + return undefined; } - if ( - !ts.isNonNullExpression(node) || - !ts.isNonNullExpression(node.expression) || - ts.isNonNullExpression(node.parent) || - ts.isNonNullExpression(node.expression.expression) - ) { - return; + const enclosingFunction = ts.findAncestor(rhsExpr, ts.isFunctionLike); + const isReturnExpr = ts.isReturnStatement(rhsExpr.parent) || ts.isArrowFunction(rhsExpr.parent); + if (!enclosingFunction) { + return undefined; } - - 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); + if (!isReturnExpr) { + return undefined; } - } - private isCustomComponent(statement: ts.ExpressionStatement): boolean { - const callExpr = statement.expression; - if (!ts.isCallExpression(callExpr)) { - return false; + if (!TsUtils.hasModifier(enclosingFunction.modifiers, ts.SyntaxKind.AsyncKeyword)) { + return undefined; } - const identifier = callExpr.expression; - if (!ts.isIdentifier(identifier)) { - return false; + const lhsPromiseLikeType = lhsType.isUnion() && lhsType.types.find(TsUtils.isStdPromiseLikeType); + if (!lhsPromiseLikeType) { + return undefined; } - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); - if (symbol) { - const decl = this.tsUtils.getDeclarationNode(identifier); - if (decl?.getSourceFile() === statement.getSourceFile()) { - return true; - } + if (!TsUtils.isTypeReference(lhsPromiseLikeType) || !lhsPromiseLikeType.typeArguments?.length) { + return undefined; } - - return this.interfacesAlreadyImported.has(callExpr.expression.getText()); + return lhsPromiseLikeType.typeArguments[0]; } - private handleDoubleDollar(node: ts.Node): void { + private handleArrayTypeImmutable(node: ts.Node, lhsType: ts.Type, rhsType: ts.Type, rhsExpr?: ts.Expression): void { if (!this.options.arkts2) { return; } - 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 possibleLhsType = this.isExprReturnedFromAsyncFunction(rhsExpr, lhsType); + if (possibleLhsType) { + lhsType = possibleLhsType; } - } - private handleDollarBind(node: ts.Node): void { + const isArray = this.tsUtils.isArray(lhsType) && this.tsUtils.isArray(rhsType); + const isTuple = + this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple) && this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple); + if (!((isArray || isTuple) && lhsType !== rhsType)) { + return; + } + const rhsTypeStr = this.tsTypeChecker.typeToString(rhsType); + let lhsTypeStr = this.tsTypeChecker.typeToString(lhsType); + if (rhsExpr && (this.isNullOrEmptyArray(rhsExpr) || ts.isArrayLiteralExpression(rhsExpr))) { + return; + } + + const possibleLhsTypeStr = this.checkLhsTypeString(node, rhsTypeStr); + if (possibleLhsTypeStr) { + lhsTypeStr = possibleLhsTypeStr; + } + + if (lhsTypeStr !== rhsTypeStr) { + this.incrementCounters(node, FaultID.ArrayTypeImmutable); + } + } + + private checkLhsTypeString(node: ts.Node, rhsTypeStr: string): string | undefined { + void this; + if (!ts.isAsExpression(node) || !ts.isArrayLiteralExpression(node.expression)) { + return undefined; + } + let lhsTypeStr: string | undefined; + node.expression.elements.forEach((elem) => { + if (elem.kind === ts.SyntaxKind.FalseKeyword || elem.kind === ts.SyntaxKind.TrueKeyword) { + lhsTypeStr = rhsTypeStr.replace(elem.getText(), 'boolean'); + } + }); + + return lhsTypeStr; + } + + private isSubtypeByBaseTypesList(baseType: ts.Type, actualType: ts.Type): boolean { + if (this.isTypeAssignable(actualType, baseType)) { + return true; + } + const actualBaseTypes = actualType.getBaseTypes() || []; + return actualBaseTypes.some((base) => { + return this.isSubtypeByBaseTypesList(baseType, base); + }); + } + + private isNullOrEmptyArray(expr: ts.Expression): boolean { + if (ts.isNewExpression(expr)) { + const constructorSym = this.tsTypeChecker.getSymbolAtLocation(expr.expression); + if (constructorSym?.name === 'Array') { + if (!expr.arguments || expr.arguments.length === 0) { + return true; + } + if (expr.arguments.length === 1) { + const argType = this.tsTypeChecker.getTypeAtLocation(expr.arguments[0]); + return !!(argType.flags & ts.TypeFlags.NumberLike); + } + } + } + + return false; + } + + private handleExponentOperation(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + const autofix = this.autofixer?.fixExponent(node.parent); + this.incrementCounters(node, FaultID.ExponentOp, autofix); + } + + private handleNonNullExpression(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + + if ( + !ts.isNonNullExpression(node) || + !ts.isNonNullExpression(node.expression) || + ts.isNonNullExpression(node.parent) || + ts.isPropertyAccessExpression(node.parent) || + ts.isNonNullExpression(node.expression.expression) + ) { + return; + } + + const statement = ts.findAncestor(node, ts.isExpressionStatement); + if (statement && this.isCustomComponent(statement)) { + this.handleCustomBidirectionalBinding(node, node.expression); + } else { + const autofix = this.autofixer?.fixNativeBidirectionalBinding(node, this.interfacesNeedToImport); + this.incrementCounters(node, FaultID.DoubleExclaBindingNotSupported, autofix); + } + } + + private isCustomComponent(statement: ts.ExpressionStatement): boolean { + const callExpr = statement.expression; + if (!ts.isCallExpression(callExpr)) { + return false; + } + + const identifier = callExpr.expression; + if (!ts.isIdentifier(identifier)) { + return false; + } + + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + if (symbol) { + const decl = this.tsUtils.getDeclarationNode(identifier); + if (decl?.getSourceFile() === statement.getSourceFile()) { + return true; + } + } + + return this.interfacesAlreadyImported.has(callExpr.expression.getText()); + } + + private handleCustomBidirectionalBinding(firstExpr: ts.NonNullExpression, secondExpr: ts.NonNullExpression): void { + let currentParam: ts.Identifier | undefined; + if (ts.isPropertyAccessExpression(secondExpr.expression)) { + currentParam = secondExpr.expression.name as ts.Identifier; + } + + let customParam: ts.Identifier | undefined; + if (ts.isPropertyAssignment(firstExpr.parent)) { + customParam = firstExpr.parent.name as ts.Identifier; + } + + if (!currentParam || !customParam) { + return; + } + + const originalExpr = firstExpr.parent.parent; + if (!ts.isObjectLiteralExpression(originalExpr)) { + return; + } + + const decl = this.tsUtils.getDeclarationNode(currentParam); + if (!decl || !ts.isPropertyDeclaration(decl)) { + return; + } + + const autofix = this.autofixer?.fixCustomBidirectionalBinding(originalExpr, decl.type, currentParam, customParam); + this.incrementCounters(firstExpr, FaultID.DoubleExclaBindingNotSupported, autofix); + } + + private handleDoubleDollar(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + + if ( + 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); + } + } + + private handleDollarBind(node: ts.Node): void { if (!this.options.arkts2) { return; } @@ -6473,10 +8538,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { - if (node.expression.expression.text === CustomDecoratorName.Extend) { + if (node.expression.expression.text === CustomInterfaceName.Extend) { const autofix = this.autofixer?.fixExtendDecorator(node, false, this.interfacesNeedToImport); this.incrementCounters(node.parent, FaultID.ExtendDecoratorNotSupported, autofix); - } else if (node.expression.expression.text === CustomDecoratorName.AnimatableExtend) { + } else if (node.expression.expression.text === CustomInterfaceName.AnimatableExtend) { const autofix = this.autofixer?.fixExtendDecorator(node, true, this.interfacesNeedToImport); this.incrementCounters(node.parent, FaultID.AnimatableExtendDecoratorTransform, autofix); } @@ -6546,8 +8611,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const shouldSkipCheck = isOptional || defaultSkipTypeCheck(propDecl.type); if (isStatic && hasNoInitializer && !shouldSkipCheck) { - const autofix = this.autofixer?.fixStaticPropertyInitializer(propDecl); - this.incrementCounters(propDecl, FaultID.ClassstaticInitialization, autofix); + this.incrementCounters(propDecl, FaultID.ClassstaticInitialization); } } @@ -6555,11 +8619,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } + this.handleNoDeprecatedApi(node as ts.TaggedTemplateExpression); 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)) { + private checkFunctionalTypeCompatibility(lhsType: ts.Type, rhsType: ts.Type, rhsExpr: ts.Expression): void { + if (this.options.arkts2 && !this.tsUtils.areCompatibleFunctionalTypes(lhsType, rhsType)) { this.incrementCounters(rhsExpr, FaultID.IncompationbleFunctionType); } } @@ -6581,18 +8646,17 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { | ts.EnumMember | ts.ModuleDeclaration | ts.InterfaceDeclaration + | ts.ExportDeclaration ): void { if (!this.options.arkts2) { return; } - const checkIdentifier = (identifier: ts.Identifier | undefined): void => { const text = identifier && ts.isIdentifier(identifier) ? identifier.text : ''; - if (identifier && text && INVALID_IDENTIFIER_KEYWORDS.includes(text)) { + if (identifier && text && INVALID_IDENTIFIER_KEYWORDS.includes(text) && !this.checkImportSymbol(identifier)) { this.incrementCounters(identifier, FaultID.InvalidIdentifier); } }; - if (ts.isImportDeclaration(decl)) { const importClause = decl.importClause; if (importClause?.namedBindings && ts.isNamedImports(importClause?.namedBindings)) { @@ -6601,6 +8665,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { }); } checkIdentifier(importClause?.name); + } else if (ts.isExportDeclaration(decl)) { + if (decl.exportClause && ts.isNamedExports(decl.exportClause)) { + for (const exportSpecifier of decl.exportClause.elements) { + checkIdentifier(exportSpecifier.name); + } + } } else if (isStructDeclaration(decl)) { checkIdentifier((decl as ts.StructDeclaration).name); } else { @@ -6608,6 +8678,21 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + private checkImportSymbol(identifier: ts.Identifier): boolean { + let symbol = this.tsUtils.trueSymbolAtLocation(identifier); + if (symbol && 'unknown' === symbol.name) { + symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + } + let res = false; + const cb = (): void => { + res = true; + }; + if (symbol) { + this.checkSymbolAndExecute(symbol, [identifier.text], SYSTEM_MODULES, cb); + } + return res; + } + private handleHeritageClause(node: ts.HeritageClause): void { this.checkEWTArgumentsForSdkDuplicateDeclName(node); if (!this.options.arkts2 || !this.useStatic) { @@ -6616,6 +8701,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { node.types.forEach((type) => { const expr = type.expression; + this.handleGenericCallWithNoTypeArgs(type); if (ts.isCallExpression(expr)) { this.incrementCounters(expr, FaultID.ExtendsExpression); return; @@ -6630,150 +8716,548 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.fixJsImportExtendsClass(node.parent, expr); } }); - + this.handleInterfaceFieldImplementation(node); this.handleMissingSuperCallInExtendedClass(node); + this.handleFieldTypesMatchingBetweenDerivedAndBaseClass(node); + this.checkReadonlyOverridesFromBase(node); + this.handleNoDeprecatedApi(node); } } - 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) { + private checkReadonlyOverridesFromBase(node: ts.HeritageClause): void { + if (!this.options.arkts2) { return; } - const decoratorName = TsUtils.getDecoratorName(decorator); - const autofix = this.autofixer?.removeNode(decorator); - if (decoratorName === SENDABLE_DECORATOR) { - this.incrementCounters(decorator, FaultID.LimitedStdLibNoSendableDecorator, autofix); + if (node.token !== ts.SyntaxKind.ExtendsKeyword) { + return; } - - if (decoratorName === CONCURRENT_DECORATOR) { - this.incrementCounters(decorator, FaultID.LimitedStdLibNoDoncurrentDecorator, autofix); + const childClass = node.parent; + const baseTypeNode = node.types[0]; + if (!ts.isClassDeclaration(childClass) || !baseTypeNode) { + return; + } + const baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeNode); + if (!baseType) { + return; } + const baseProps = baseType.getProperties(); + this.validateReadonlyOverrides(childClass, baseProps); } - private checkAsonSymbol(symbol: ts.Symbol, node: ts.Node): void { - const cb = (): void => { - let autofix: Autofix[] | undefined; - const parent = node.parent; - autofix = this.autofixer?.replaceNode(parent ? parent : node, JSON_TEXT); - - if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { - autofix = this.autofixer?.removeImport(node, parent); + private validateReadonlyOverrides(childClass: ts.ClassDeclaration, baseProps: ts.Symbol[]): void { + for (const member of childClass.members) { + if (!ts.isPropertyDeclaration(member) || !member.name) { + continue; } - - this.incrementCounters(node, FaultID.LimitedStdLibNoASON, autofix); - }; - this.checkSymbolAndExecute(symbol, ASON_TEXT, ASON_MODULES, cb); - } - - private checkCollectionsSymbol(symbol: ts.Symbol, node: ts.Node): void { - const cb = (): void => { - const parent = node.parent; - if (!parent) { - return; + const isDerivedReadonly = TsUtils.hasModifier(member.modifiers, ts.SyntaxKind.ReadonlyKeyword); + if (!isDerivedReadonly) { + continue; } - if (ts.isPropertyAccessExpression(parent)) { - const autofix = this.autofixer?.replaceNode(parent, parent.name.text); - this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + const memberName = ts.isIdentifier(member.name) ? member.name.text : undefined; + if (!memberName) { + continue; } - - if (ts.isQualifiedName(parent)) { - const autofix = this.autofixer?.replaceNode(parent, parent.right.text); - this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + const baseProp = baseProps.find((p) => { + return p.name === memberName; + }); + if (!baseProp) { + continue; } - if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { - const autofix = this.autofixer?.removeImport(node, parent); - this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + const baseDecl = baseProp.valueDeclaration; + if (!baseDecl || !ts.isPropertyDeclaration(baseDecl)) { + continue; } - }; - - this.checkSymbolAndExecute(symbol, COLLECTIONS_TEXT, COLLECTIONS_MODULES, cb); + const isBaseReadonly = TsUtils.hasModifier(baseDecl.modifiers, ts.SyntaxKind.ReadonlyKeyword); + if (!isBaseReadonly) { + this.incrementCounters(member, FaultID.NoClassSuperPropReadonly); + } + } } - private checkWorkerSymbol(symbol: ts.Symbol, node: ts.Node): void { - const cb = (): void => { - this.incrementCounters(node, FaultID.NoNeedStdlibWorker); - }; + /** + * Ensures classes explicitly implement all optional properties from their interfaces. + * Required fields are ignored because the it's already enforced on ArkTS1.1. + */ + private handleInterfaceFieldImplementation(clause: ts.HeritageClause): void { + // Only process implements clauses + if (clause.token !== ts.SyntaxKind.ImplementsKeyword) { + return; + } - this.checkSymbolAndExecute(symbol, WORKER_TEXT, WORKER_MODULES, cb); - } + const classDecl = clause.parent as ts.ClassDeclaration; + if (!ts.isClassDeclaration(classDecl) || !classDecl.name) { + return; + } - private checkSymbolAndExecute(symbol: ts.Symbol, symbolName: string, modules: string[], cb: () => void): void { - void this; - if (symbol.name === symbolName) { - const decl = TsUtils.getDeclaration(symbol); + for (const interfaceType of clause.types) { + const expr = interfaceType.expression; + if (!ts.isIdentifier(expr)) { + continue; + } + const sym = this.tsUtils.trueSymbolAtLocation(expr); + const interfaceDecl = sym?.declarations?.find(ts.isInterfaceDeclaration); + if (!interfaceDecl) { + continue; + } - if (!decl) { + // Gather all inherited interfaces + const allInterfaces = this.getAllInheritedInterfaces(interfaceDecl); + + // If the class fails to implement any member, report once and exit + if (!this.classImplementsAllMembers(classDecl, allInterfaces)) { + this.incrementCounters(classDecl.name, FaultID.InterfaceFieldNotImplemented); return; } + } + } - const sourceFile = decl.getSourceFile(); - const fileName = path.basename(sourceFile.fileName); - - if ( - modules.some((moduleName) => { - return fileName.startsWith(moduleName); - }) - ) { - cb(); + /** + * Recursively collects an interface and all its ancestor interfaces. + */ + private getAllInheritedInterfaces(root: ts.InterfaceDeclaration): ts.InterfaceDeclaration[] { + const collected: ts.InterfaceDeclaration[] = []; + const stack: ts.InterfaceDeclaration[] = [root]; + while (stack.length) { + const current = stack.pop()!; + collected.push(current); + if (!current.heritageClauses) { + continue; + } + for (const clause of current.heritageClauses) { + if (clause.token !== ts.SyntaxKind.ExtendsKeyword) { + continue; + } + for (const typeNode of clause.types) { + const expr = typeNode.expression; + if (!ts.isIdentifier(expr)) { + continue; + } + const sym = this.tsUtils.trueSymbolAtLocation(expr); + const decl = sym?.declarations?.find(ts.isInterfaceDeclaration); + if (decl) { + stack.push(decl); + } + } } } + return collected; } - interfacesNeedToAlarm: ts.Identifier[] = []; - interfacesNeedToImport: Set = new Set(); - interfacesAlreadyImported: Set = new Set(); + /** + * Returns true if the class declaration declares every optional property or method + * signature from the provided list of interface declarations. + */ + private classImplementsAllMembers(classDecl: ts.ClassDeclaration, interfaces: ts.InterfaceDeclaration[]): boolean { + void this; - private handleInterfaceImport(identifier: ts.Identifier): void { - if (!this.options.arkts2) { - return; + // Check optional members only + for (const intf of interfaces) { + for (const member of intf.members) { + if ( + (ts.isPropertySignature(member) || ts.isMethodSignature(member)) && + ts.isIdentifier(member.name) && + member.questionToken + ) { + const propName = member.name.text; + + // does derived class have this member? + const hasImpl = classDecl.members.some((m) => { + return ( + (ts.isPropertyDeclaration(m) || ts.isMethodDeclaration(m)) && + ts.isIdentifier(m.name) && + m.name.text === propName + ); + }); + + if (!hasImpl) { + return false; + } + } + } } + return true; + } + + private isVariableReference(identifier: ts.Identifier): boolean { + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + return !!symbol && (symbol.flags & ts.SymbolFlags.Variable) !== 0; + } - if (this.shouldSkipIdentifier(identifier)) { + private checkSendableAndConcurrentDecorator(decorator: ts.Decorator): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - - const name = identifier.getText(); - if (!this.interfacesNeedToImport.has(name)) { - this.interfacesNeedToImport.add(name); + const decoratorName = TsUtils.getDecoratorName(decorator); + const autofix = this.autofixer?.removeNode(decorator); + if (decoratorName === SENDABLE_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoSendableDecorator, autofix); } - this.interfacesNeedToAlarm.push(identifier); - } - - private shouldSkipIdentifier(identifier: ts.Identifier): boolean { - const name = identifier.getText(); - if (!arkuiImportList.has(name)) { - return true; + if (decoratorName === CONCURRENT_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoDoncurrentDecorator, autofix); } + } - if (skipImportDecoratorName.has(name)) { - return true; + private checkAsonSymbol(node: ts.Identifier): void { + if (!this.options.arkts2) { + 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; - } + if (node.text !== ASON_TEXT) { + return; } - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + const parent = node.parent; + switch (parent.kind) { + case ts.SyntaxKind.QualifiedName: + if (!ts.isQualifiedName(parent)) { + return; + } + if (parent.right.text !== node.text) { + return; + } + if (ts.isQualifiedName(parent.parent) && ASON_WHITE_SET.has(parent.parent.right.text)) { + this.checkAsonUsage(parent.left, true); + } else { + this.checkAsonUsage(parent.left, false); + } + break; + case ts.SyntaxKind.PropertyAccessExpression: + if (!ts.isPropertyAccessExpression(parent)) { + return; + } + if (parent.name.text !== node.text) { + return; + } + if (ts.isPropertyAccessExpression(parent.parent) && ASON_WHITE_SET.has(parent.parent.name.text)) { + this.checkAsonUsage(parent.expression, true); + } else { + this.checkAsonUsage(parent.expression, false); + } + break; + default: + } + } + + private checkAsonUsage(nodeToCheck: ts.Node, needAutofix: boolean): void { + if (!ts.isIdentifier(nodeToCheck)) { + return; + } + + const declaration = this.tsUtils.getDeclarationNode(nodeToCheck); + if (!declaration && nodeToCheck.text === ARKTS_UTILS_TEXT) { + const autofix = + needAutofix && this.autofixer ? this.autofixer.replaceNode(nodeToCheck.parent, JSON_TEXT) : undefined; + this.incrementCounters(nodeToCheck, FaultID.LimitedStdLibNoASON, autofix); + return; + } + + if (!declaration) { + return; + } + + const sourceFile = declaration.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + + if ( + ASON_MODULES.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + const autofix = + needAutofix && this.autofixer ? this.autofixer.replaceNode(nodeToCheck.parent, JSON_TEXT) : undefined; + this.incrementCounters(nodeToCheck, FaultID.LimitedStdLibNoASON, autofix); + } + } + + private checkCollectionsForPropAccess(node: ts.Node, ident: ts.Node): void { + if (!ts.isIdentifier(ident)) { + return; + } + if (this.isBitVector(ident)) { + return; + } + const autofix = this.autofixer?.replaceNode(node, ident.getText()); + + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } + + private checkCollectionsSymbol(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + + const cb = (): void => { + const parent = node.parent; + if (!parent) { + return; + } + const shouldSkipFix = TypeScriptLinter.shouldSkipFixForCollectionsArray(node); + if (shouldSkipFix) { + if (ts.isPropertyAccessExpression(parent)) { + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer); + } + if (ts.isQualifiedName(parent)) { + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer); + } + } else { + if (ts.isPropertyAccessExpression(parent)) { + this.checkCollectionsForPropAccess(parent, parent.name); + return; + } + if (ts.isQualifiedName(parent)) { + this.checkCollectionsForPropAccess(parent, parent.right); + return; + } + } + if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { + const bitVectorUsed = this.checkBitVector(node.getSourceFile()); + + if (bitVectorUsed?.used) { + const ns = bitVectorUsed.ns; + if (parent.name.text === ns) { + return; + } + } + + if (parent.propertyName && node.text === parent.propertyName.text) { + return; + } + + const autofix = this.autofixer?.removeImport(node, parent); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } + }; + + this.checkNodeForUsage(node, COLLECTIONS_TEXT, COLLECTIONS_MODULES, cb); + } + + private static shouldSkipFixForCollectionsArray(node: ts.Node): boolean { + const isArrayWithNumericArg = (n: ts.Node | undefined): boolean => { + return !!( + n && + ts.isNewExpression(n) && + ts.isPropertyAccessExpression(n.expression) && + n.expression.name.text === 'Array' && + n.arguments?.some((arg) => { + return ts.isNumericLiteral(arg); + }) + ); + }; + if (isArrayWithNumericArg(node.parent)) { + return true; + } + + let currentNode: ts.Node | undefined = node; + while (currentNode) { + if (ts.isVariableDeclaration(currentNode)) { + if (isArrayWithNumericArg(currentNode.initializer)) { + return true; + } + break; + } + currentNode = currentNode.parent; + } + + return false; + } + + 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 checkConcurrencySymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + const parent = node.parent; + + if (!ts.isPropertyAccessExpression(parent)) { + return; + } + + if (parent.name.text === ARKTSUTILS_LOCKS_MEMBER) { + const autofix = this.autofixer?.fixConcurrencyLock(parent); + this.incrementCounters(node, FaultID.LimitedStdLibNoImportConcurrency, autofix); + } + + if (PROCESS_DEPRECATED_INTERFACES.includes(parent.name.text)) { + this.incrementCounters(node, FaultID.DeprecatedProcessApi); + } + }; + + this.checkSymbolAndExecute(symbol, [ARKTSUTILS_LOCKS_MEMBER, ARKTSUTILS_PROCESS_MEMBER], ARKTSUTILS_MODULES, cb); + } + + private checkSymbolAndExecute(symbol: ts.Symbol, symbolNames: string[], modules: string[], cb: () => void): void { + void this; + + // Only execute if the provided list contains the symbol’s actual name + if (!symbolNames.includes(symbol.name)) { + return; + } + + const decl = TsUtils.getDeclaration(symbol); + if (!decl) { + cb(); + return; + } + + const fileName = TypeScriptLinter.getFileName(decl); + if ( + modules.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + cb(); + } + } + + private checkNodeForUsage(node: ts.Node, symbolName: string, modules: string[], cb: () => void): void { + const symbol = this.tsUtils.trueSymbolAtLocation(node); if (symbol) { - const decl = this.tsUtils.getDeclarationNode(identifier); - if (decl?.getSourceFile() === identifier.getSourceFile()) { + this.checkSymbolAndExecute(symbol, [symbolName], modules, cb); + + return; + } + + if (node.getText() === symbolName) { + cb(); + } + } + + private checkBitVector(node: ts.Node): BitVectorUsage { + if (!ts.isIdentifier(node)) { + let isBitVector: BitVectorUsage; + node.forEachChild((child) => { + const checked = this.checkBitVector(child); + if (checked?.used) { + isBitVector = checked; + } + }); + + return isBitVector; + } + + if (!this.isBitVector(node)) { + return { ns: '', used: false }; + } + + if (!ts.isPropertyAccessExpression(node.parent)) { + return undefined; + } + + return { ns: node.parent.expression.getText(), used: true }; + } + + private isBitVector(ident: ts.Identifier): boolean { + void this; + + return ident.text === BIT_VECTOR; + } + + interfacesNeedToAlarm: ts.Identifier[] = []; + interfacesNeedToImport: Set = new Set(); + interfacesAlreadyImported: Set = new Set(); + + private handleInterfaceImport(identifier: ts.Identifier): void { + if (!this.options.arkts2) { + return; + } + + if (!this.isInterfaceImportNeeded(identifier)) { + return; + } + + const name = identifier.getText(); + if (!this.interfacesNeedToImport.has(name)) { + this.interfacesNeedToImport.add(name); + } + + this.interfacesNeedToAlarm.push(identifier); + } + + private isInterfaceImportNeeded(identifier: ts.Identifier): boolean { + const name = identifier.getText(); + return ( + arkuiImportList.has(name) && + !skipImportDecoratorName.has(name) && + !this.interfacesAlreadyImported.has(name) && + !this.isParentAlreadyImported(identifier.parent) && + !this.isDeclarationInSameFile(identifier) && + !this.isDeprecatedInterface(identifier) && + !TypeScriptLinter.isWrappedByExtendDecorator(identifier) + ); + } + + private isDeprecatedInterface(node: ts.Identifier): boolean { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + const decl = TsUtils.getDeclaration(symbol); + if (!decl) { + return false; + } + + const parName = this.tsUtils.getParentSymbolName(symbol); + const parameters = ts.isFunctionLike(decl) ? decl.parameters : undefined; + const returnType = ts.isFunctionLike(decl) ? decl.type?.getText() : undefined; + const fileName = path.basename(decl.getSourceFile().fileName) + ''; + + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName, + parameters, + returnType, + fileName + ); + return this.getFaultIdWithMatchedDeprecatedApi(node.getText(), deprecatedApiCheckMap).length > 0; + } + + private static isWrappedByExtendDecorator(node: ts.Identifier): boolean { + const wrappedSkipComponents = new Set([CustomInterfaceName.AnimatableExtend, CustomInterfaceName.Extend]); + if (ts.isCallExpression(node.parent)) { + const expr = node.parent.expression; + if (wrappedSkipComponents.has(expr.getText()) && node.getText() !== CustomInterfaceName.AnimatableExtend) { return true; } } + return false; + } + + private isParentAlreadyImported(node: ts.Node): boolean { + let identifier: ts.Identifier | undefined; + + while ( + ts.isPropertyAccessExpression(node) || + ts.isParenthesizedExpression(node) || + ts.isCallExpression(node) || + ts.isQualifiedName(node) + ) { + const nextNode = ts.isQualifiedName(node) ? node.left : node.expression; + if (!nextNode) { + break; + } + + if (ts.isIdentifier(nextNode)) { + identifier = nextNode; + break; + } + + node = nextNode; + } - return this.interfacesAlreadyImported.has(name); + return identifier !== undefined && this.isDeclarationInSameFile(identifier); + } + + private isDeclarationInSameFile(node: ts.Node): boolean { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + const decl = TsUtils.getDeclaration(symbol); + if (decl?.getSourceFile() === node.getSourceFile()) { + return true; + } + + return false; } private processInterfacesToImport(sourceFile: ts.SourceFile): void { @@ -6788,7 +9272,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ); this.interfacesNeedToAlarm.forEach((identifier) => { - this.incrementCounters(identifier, FaultID.UIInterfaceImport, autofix); + const name = identifier.getText(); + const errorMsg = `The ArkUI interface "${name}" should be imported before it is used (arkui-modular-interface)`; + this.incrementCounters(identifier, FaultID.UIInterfaceImport, autofix, errorMsg); }); this.interfacesNeedToAlarm = []; @@ -6831,7 +9317,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomDecoratorName.Styles) { + if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomInterfaceName.Styles) { return; } @@ -6895,7 +9381,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const autofix = this.autofixer?.fixStateStyles(object, startNode, this.interfacesNeedToImport); - this.incrementCounters(object, FaultID.StylesDecoratorNotSupported, autofix); + this.incrementCounters(object, FaultID.StateStylesBlockNeedArrowFunc, autofix); } private static hasAnonBlock(properties: ts.NodeArray): boolean { @@ -6928,7 +9414,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } const text = stringLiteral.text; - const autofix = this.autofixer?.removeNode(stringLiteral); + const autofix = this.autofixer?.removeNode(stringLiteral.parent); if (text === USE_CONCURRENT) { this.incrementCounters(stringLiteral, FaultID.UseConcurrentDeprecated, autofix); @@ -7015,7 +9501,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; }); if (filteredClassDecls.length !== 0) { - this.interfacesNeedToImport.add(CustomDecoratorName.Observed); + this.interfacesNeedToImport.add(CustomInterfaceName.Observed); } const autofix = this.autofixer?.fixDataObservation(filteredClassDecls); this.incrementCounters(node, FaultID.DataObservation, autofix); @@ -7077,7 +9563,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private static hasObservedDecorator(classDecl: ts.ClassDeclaration): boolean { return ( ts.getDecorators(classDecl)?.some((decorator) => { - return decorator.getText() === '@' + CustomDecoratorName.Observed; + return decorator.getText() === '@' + CustomInterfaceName.Observed; }) ?? false ); } @@ -7124,7 +9610,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + if (!this.isDeclaredInArkTs2(callSignature)) { return; } @@ -7140,7 +9626,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if ( TypeScriptLinter.isFunctionLike(functionDeclaration) && - TypeScriptLinter.containsReflectAPI(functionDeclaration) + TypeScriptLinter.containsForbiddenAPI(functionDeclaration) ) { this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallReflect); } @@ -7167,30 +9653,50 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } - private static containsReflectAPI( + private static containsForbiddenAPI( node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression - ): boolean { + ): ForbidenAPICheckResult { if (!node.body) { - return false; + return NONE; } + return TypeScriptLinter.isForbiddenUsed(node.body); + } - 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); - } - } - let found = false; + private static isForbiddenUsed(currentNode: ts.Node): ForbidenAPICheckResult { + if (!ts.isCallExpression(currentNode)) { + let found: ForbidenAPICheckResult = NONE; ts.forEachChild(currentNode, (child) => { - found = found || checkForReflect(child); + if (found === NONE) { + found = TypeScriptLinter.isForbiddenUsed(child); + } }); + return found; - }; + } + + const expr = currentNode.expression; + if (!ts.isPropertyAccessExpression(expr)) { + return NONE; + } + + const obj = expr.expression; + const method = expr.name; + if (!ts.isIdentifier(obj)) { + return NONE; + } + + if (obj.text === REFLECT_LITERAL) { + if (REFLECT_PROPERTIES.includes(method.text)) { + return REFLECT_LITERAL; + } + } - return checkForReflect(node.body); + if (obj.text === OBJECT_LITERAL) { + if (OBJECT_PROPERTIES.includes(method.text)) { + return OBJECT_LITERAL; + } + } + return NONE; } private getFunctionSymbol(declaration: ts.Declaration): ts.Symbol | undefined { @@ -7206,30 +9712,49 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isFunctionExpression(node); } - private handleSdkForConstructorFuncs(node: ts.PropertyAccessExpression): void { - if (!this.options.arkts2 || !node) { - return; + private static isThirdPartyBySymbol(symbol: ts.Symbol | undefined, apiList: ApiListItem): boolean { + if (!symbol) { + return false; } - const sdkInfos = this.interfaceMap.get(node.expression.getText()); - if (!sdkInfos || sdkInfos.size === 0) { - return; + const declaration = symbol.getDeclarations()?.[0]; + if (declaration && ts.isImportClause(declaration)) { + const importDecl = declaration.parent; + const importPath = TsUtils.removeOrReplaceQuotes(importDecl.moduleSpecifier.getText(), false); + const import_path = TypeScriptLinter.getLocalApiListItemByKey(SdkNameInfo.ImportPath, apiList); + if (import_path.includes(importPath)) { + return true; + } } + return false; + } - for (const sdkInfo of sdkInfos) { - const propertyName = node.name.getText(); - if (propertyName === sdkInfo.api_name) { - this.incrementCounters(node.name, FaultID.ConstructorTypesDeprecated); - } + private static getLocalApiListItemByKey(key: string, apiList: ApiListItem): string | string[] { + if (!apiList) { + return ''; } + if (SdkNameInfo.ImportPath === key) { + return apiList.import_path; + } + return ''; } - private handleArkTSPropertyAccess(node: ts.PropertyAccessExpression): void { - if (this.useStatic && this.options.arkts2) { - if (this.isFromJSModule(node.expression)) { - this.incrementCounters(node, FaultID.BinaryOperations); - } + private handleSdkForConstructorFuncs(node: ts.PropertyAccessExpression | ts.QualifiedName): void { + if (!this.options.arkts2) { + return; } - this.handlePropertyDescriptorInScenarios(node); + const rightNode = ts.isPropertyAccessExpression(node) ? node.name : node.right; + const leftNode = ts.isPropertyAccessExpression(node) ? node.expression : node.left; + const constructorFuncsInfos = Array.from(TypeScriptLinter.constructorFuncsSet); + constructorFuncsInfos.some((constructorFuncsInfo) => { + const api_name = constructorFuncsInfo.api_info.api_name; + if (api_name !== rightNode.getText()) { + return; + } + const parentSym = this.tsTypeChecker.getSymbolAtLocation(leftNode); + if (TypeScriptLinter.isThirdPartyBySymbol(parentSym, constructorFuncsInfo)) { + this.incrementCounters(rightNode, FaultID.ConstructorTypesDeprecated); + } + }); } private handleQuotedHyphenPropsDeprecated(node: ts.PropertyAccessExpression | ts.PropertyAssignment): void { @@ -7277,7 +9802,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if (ts.isPropertySignature(node)) { - return this.tsTypeChecker.getTypeAtLocation(node.type!).getSymbol(); + return this.tsTypeChecker.getSymbolAtLocation(node); } const nodesWithResolvableType = [ @@ -7315,38 +9840,27 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!ts.isTypeReferenceNode(typeNode)) { return undefined; } - const symbol = this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); - if (!symbol) { - return this.resolveTypeNoSymbol(typeNode); + return this.resolveTypeNoSymbol(typeNode); + } + + private resolveTypeNoSymbol(typeNode: ts.TypeReferenceNode): ts.Symbol | undefined { + if (!typeNode.typeName) { + return undefined; } - 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; - } - } - return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); - } - 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)) { + + const symbol = this.tsUtils.trueSymbolAtLocation(typeNode.typeName); + if (symbol?.declarations && symbol.declarations.length > 0) { + const globalDeclaration = symbol.declarations[0]; + if (ts.isTypeAliasDeclaration(globalDeclaration)) { return this.resolveTypeNodeSymbol(globalDeclaration.type); + } else if (ts.isInterfaceDeclaration(globalDeclaration)) { + return this.processQuotedHyphenPropsDeprecatedOnInterfaceDeclaration(globalDeclaration); } } - return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); } @@ -7411,6 +9925,32 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return undefined; } + private handleLocalDeclarationOfClassAndIface(node: ts.ClassDeclaration | ts.InterfaceDeclaration): void { + if (!this.options.arkts2) { + return; + } + this.isLocalClass(node); + } + + private isLocalClass(node: ts.Node): void { + if ( + ts.findAncestor(node, (node) => { + return ( + ts.isArrowFunction(node) || + ts.isFunctionDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isConstructorDeclaration(node) || + ts.isGetAccessor(node) || + ts.isSetAccessor(node) || + ts.isBlock(node) + ); + }) + ) { + this.incrementCounters(node, FaultID.NoLocalClass); + } + } + private processPropertyAccessExpression(expression: ts.PropertyAccessExpression): ts.Symbol | undefined { const heritageSymbol = this.tsTypeChecker.getSymbolAtLocation(expression.expression); if (heritageSymbol && expression.name.text === this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName)) { @@ -7431,16 +9971,19 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return undefined; } - private processApiNodeSdkDuplicateDeclName(apiName: string, errorNode: ts.Node): void { - const setApiListItem = TypeScriptLinter.globalApiInfo.get(SdkProblem.DeclWithDuplicateName); + private processApiNodeSdkGlobalApi(apiName: string, errorNode: ts.Node): void { + for (const [key, value] of globalApiAssociatedInfo) { + this.doProcessApiNodeSdkGlobalApi(apiName, errorNode, key, value); + } + } + + private doProcessApiNodeSdkGlobalApi(apiName: string, errorNode: ts.Node, key: string, faultId: number): void { + const setApiListItem = TypeScriptLinter.globalApiInfo.get(key); if (!setApiListItem) { return; } - const apiNamesArr = [...setApiListItem]; - const hasSameApiName = apiNamesArr.some((apilistItem) => { - return apilistItem.api_info.api_name === errorNode.getText(); - }); - if (!hasSameApiName) { + + if (TypeScriptLinter.isInterfaceImplementation(errorNode)) { return; } @@ -7448,18 +9991,87 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { errorNode = errorNode.typeName; } + const symbol = this.tsUtils.trueSymbolAtLocation(errorNode); + const oriDecl = TsUtils.getDeclaration(symbol); + const fileName = path.normalize(oriDecl?.getSourceFile().fileName || ''); + const apiNamesArr = [...setApiListItem]; + const hasSameApiName = apiNamesArr.some((apilistItem) => { + return ( + apilistItem.api_info.api_name === errorNode.getText() && + fileName.endsWith(path.normalize(apilistItem.file_path)) + ); + }); + if (!hasSameApiName) { + return; + } + const matchedApi = apiNamesArr.some((sdkInfo) => { const isSameName = sdkInfo.api_info.api_name === apiName; const isGlobal = sdkInfo.is_global; return isSameName && isGlobal; }); + const checkSymbol = TypeScriptLinter.isIdentifierFromSDK(symbol); + const type = this.tsTypeChecker.getTypeAtLocation(errorNode); + const typeName = this.tsTypeChecker.typeToString(type); - if (matchedApi) { - this.incrementCounters(errorNode, FaultID.DuplicateDeclNameFromSdk); + if (checkSymbol) { + if (arkTsBuiltInTypeName.has(typeName)) { + return; + } + if (matchedApi) { + this.incrementCounters(errorNode, faultId); + } + } + } + + static isInterfaceImplementation(node: ts.Node): boolean { + const classDeclaration = ts.findAncestor(node, ts.isClassDeclaration); + if (!classDeclaration) { + return false; + } + + if (classDeclaration.heritageClauses) { + return classDeclaration.heritageClauses.some((clause) => { + return clause.token === ts.SyntaxKind.ImplementsKeyword; + }); + } + return false; + } + + static isIdentifierFromSDK(symbol: ts.Symbol | undefined): boolean { + if (!symbol) { + return true; + } + + // Check if the symbol is from an SDK import + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return true; + } + + let isLocal = false; + for (const declaration of declarations) { + if ( + ts.isVariableDeclaration(declaration) || + ts.isTypeAliasDeclaration(declaration) || + ts.isClassDeclaration(declaration) || + ts.isInterfaceDeclaration(declaration) || + ts.isFunctionDeclaration(declaration) || + ts.isEnumDeclaration(declaration) + ) { + isLocal = true; + break; + } } + + if (isLocal) { + return false; + } + + return true; } - private handleSdkDuplicateDeclName( + private handleSdkGlobalApi( node: | ts.TypeReferenceNode | ts.NewExpression @@ -7470,75 +10082,87 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { | ts.BinaryExpression | ts.ExpressionWithTypeArguments | ts.Identifier + | ts.MethodDeclaration ): void { if (!this.options.arkts2) { return; } switch (node.kind) { case ts.SyntaxKind.TypeReference: - this.checkTypeReferenceForSdkDuplicateDeclName(node); + this.checkTypeReferenceForSdkGlobalApi(node); break; case ts.SyntaxKind.NewExpression: - this.checkNewExpressionForSdkDuplicateDeclName(node); + this.checkNewExpressionForSdkGlobalApi(node); break; case ts.SyntaxKind.Identifier: - this.checkHeritageClauseForSdkDuplicateDeclName(node); + this.checkHeritageClauseForSdkGlobalApi(node); break; case ts.SyntaxKind.VariableDeclaration: case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.Parameter: - this.checkDeclarationForSdkDuplicateDeclName(node); + this.checkDeclarationForSdkGlobalApi(node); break; case ts.SyntaxKind.CallExpression: - this.checkCallExpressionForSdkDuplicateDeclName(node); + this.checkCallExpressionForSdkGlobalApi(node); break; case ts.SyntaxKind.BinaryExpression: - this.checkBinaryExpressionForSdkDuplicateDeclName(node); + this.checkBinaryExpressionForSdkGlobalApi(node); + break; + case ts.SyntaxKind.MethodDeclaration: + this.checkMethodDeclarationForSdkGlobalApi(node); break; default: } } - private checkTypeReferenceForSdkDuplicateDeclName(node: ts.TypeReferenceNode): void { + private checkTypeReferenceForSdkGlobalApi(node: ts.TypeReferenceNode): void { const typeName = node.typeName; if (ts.isIdentifier(typeName)) { - this.processApiNodeSdkDuplicateDeclName(typeName.text, node); + this.processApiNodeSdkGlobalApi(typeName.text, node); } } - private checkNewExpressionForSdkDuplicateDeclName(node: ts.NewExpression): void { + private checkNewExpressionForSdkGlobalApi(node: ts.NewExpression): void { const expression = node.expression; if (ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkHeritageClauseForSdkDuplicateDeclName(node: ts.Identifier): void { + private checkHeritageClauseForSdkGlobalApi(node: ts.Identifier): void { if (ts.isIdentifier(node)) { - this.processApiNodeSdkDuplicateDeclName(node.text, node); + this.processApiNodeSdkGlobalApi(node.text, node); } } - private checkDeclarationForSdkDuplicateDeclName( + private checkDeclarationForSdkGlobalApi( node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration ): void { const expression = node.initializer; if (expression && ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkCallExpressionForSdkDuplicateDeclName(node: ts.CallExpression): void { + private checkCallExpressionForSdkGlobalApi(node: ts.CallExpression): void { if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { const expression = node.expression.expression; - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + + this.processApiNodeSdkGlobalApi(expression.text, expression); } } - private checkBinaryExpressionForSdkDuplicateDeclName(node: ts.BinaryExpression): void { + private checkBinaryExpressionForSdkGlobalApi(node: ts.BinaryExpression): void { const expression = node.right; if (ts.isIdentifier(expression)) { - this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + this.processApiNodeSdkGlobalApi(expression.text, expression); + } + } + + private checkMethodDeclarationForSdkGlobalApi(node: ts.MethodDeclaration): void { + const expression = node.name; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkGlobalApi(expression.text, expression); } } @@ -7548,9 +10172,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { node.types.forEach((type) => { + this.handleSharedArrayBuffer(type); const expr = type.expression; if (ts.isIdentifier(expr)) { - this.processApiNodeSdkDuplicateDeclName(expr.text, expr); + this.processApiNodeSdkGlobalApi(expr.text, expr); } }); } @@ -7688,6 +10313,152 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + /** + * Returns true if the method’s declared return type or body returns Promise. + */ + private hasPromiseVoidReturn(method: ts.MethodDeclaration): boolean { + return ( + this.hasAnnotatedPromiseVoidReturn(method) || this.isAsyncMethod(method) || this.hasBodyPromiseReturn(method) + ); + } + + /** + * Checks if the method’s declared return type annotation includes Promise. + */ + private hasAnnotatedPromiseVoidReturn(method: ts.MethodDeclaration): boolean { + void this; + if (!method.type) { + return false; + } + const t = method.type; + // Union type check + if (ts.isUnionTypeNode(t)) { + return t.types.some((u) => { + return this.isSinglePromiseVoid(u); + }); + } + // Single Promise check + return this.isSinglePromiseVoid(t); + } + + private isSinglePromiseVoid(n: ts.Node): boolean { + void this; + return ts.isTypeReferenceNode(n) && n.typeName.getText() === PROMISE && n.typeArguments?.[0]?.getText() === VOID; + } + + /** + * Checks if the method is declared async (implying Promise return). + */ + private isAsyncMethod(method: ts.MethodDeclaration): boolean { + void this; + return ( + method.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.AsyncKeyword; + }) ?? false + ); + } + + /** + * Scans the method body iteratively for any Promise-returning statements. + */ + private hasBodyPromiseReturn(method: ts.MethodDeclaration): boolean { + if (!method.body) { + return false; + } + + let found = false; + const visit = (node: ts.Node): void => { + if (ts.isReturnStatement(node) && node.expression) { + const retType = this.tsTypeChecker.getTypeAtLocation(node.expression); + if (retType.symbol?.getName() === PROMISE) { + found = true; + return; + } + } + ts.forEachChild(node, visit); + }; + ts.forEachChild(method.body, visit); + + return found; + } + + /** + * Returns true if this method name is onDestroy/onDisconnect and class extends one of the supported Ability subclasses. + */ + private isLifecycleMethodOnAbilitySubclass(method: ts.MethodDeclaration): boolean { + const name = method.name.getText(); + if (name !== ON_DESTROY && name !== ON_DISCONNECT) { + return false; + } + const cls = method.parent; + if (!ts.isClassDeclaration(cls) || !cls.heritageClauses) { + return false; + } + return cls.heritageClauses.some((h) => { + return ( + h.token === ts.SyntaxKind.ExtendsKeyword && + h.types.some((tn) => { + return this.isSupportedAbilityBase(method.name.getText(), tn.expression); + }) + ); + }); + } + + /** + * Checks that the base class name and its import source or declaration file are supported, + * and matches the lifecycle method (onDestroy vs onDisconnect). + */ + private isSupportedAbilityBase(methodName: string, baseExprNode: ts.Expression): boolean { + const sym = this.tsTypeChecker.getSymbolAtLocation(baseExprNode); + if (!sym) { + return false; + } + + const baseName = sym.getName(); + if (!ASYNC_LIFECYCLE_SDK_LIST.has(baseName)) { + return false; + } + + if (methodName === ON_DISCONNECT && baseName !== SERVICE_EXTENSION_ABILITY) { + return false; + } + if (methodName === ON_DESTROY && baseName === SERVICE_EXTENSION_ABILITY) { + return false; + } + + const decl = sym.getDeclarations()?.[0]; + if (!decl || !ts.isImportSpecifier(decl)) { + return false; + } + + const importDecl = decl.parent.parent.parent; + const moduleName = (importDecl.moduleSpecifier as ts.StringLiteral).text; + const srcFile = decl.getSourceFile().fileName; + + return moduleName === ABILITY_KIT || srcFile.endsWith(`${baseName}.${EXTNAME_D_TS}`); + } + + /** + * Rule sdk-void-lifecycle-return: + * Flags onDestroy/onDisconnect methods in Ability subclasses + * whose return type includes Promise. + */ + private checkVoidLifecycleReturn(method: ts.MethodDeclaration): void { + if (!this.options.arkts2) { + return; + } + + if (!this.isLifecycleMethodOnAbilitySubclass(method)) { + return; + } + + if (!this.hasPromiseVoidReturn(method)) { + return; + } + + this.incrementCounters(method.name, FaultID.SdkAbilityAsynchronousLifecycle); + } + private handleGetOwnPropertyNames(decl: ts.PropertyAccessExpression): void { if (this.checkPropertyAccessExpression(decl, GET_OWN_PROPERTY_NAMES_TEXT, TypeScriptLinter.missingAttributeSet)) { const autofix = this.autofixer?.fixMissingAttribute(decl); @@ -7705,7 +10476,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (set.size === 0 || decl.getText() !== name) { return false; } - const symbol = this.tsUtils.trueSymbolAtLocation(decl); const sourceFile = symbol?.declarations?.[0]?.getSourceFile(); if (!sourceFile) { @@ -7717,7 +10487,12 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private fixJsImportCallExpression(callExpr: ts.CallExpression): void { - if (!this.options.arkts2 || !this.useStatic) { + if ( + !this.options.arkts2 || + !this.useStatic || + ts.isAwaitExpression(callExpr.parent) || + ts.isTypeOfExpression(callExpr.parent) + ) { return; } @@ -7730,16 +10505,27 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - // check if any argument is a `new` expression - const hasNewExpressionArg = callExpr.arguments.some((arg) => { - return ts.isNewExpression(arg); + 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); + } + if (type?.isClassOrInterface()) { + this.incrementCounters(arg, FaultID.InteropJsObjectExpandStaticInstance); + } + } else if (ts.isObjectLiteralExpression(arg) || type?.isClassOrInterface()) { + this.incrementCounters(arg, FaultID.InteropJsObjectExpandStaticInstance); + } }); - - const faultId = hasNewExpressionArg ? - FaultID.InteropJsObjectExpandStaticInstance : - FaultID.InteropJsObjectCallStaticFunc; - - this.incrementCounters(callExpr, faultId); } private fixJsImportExtendsClass( @@ -7772,34 +10558,25 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } // 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 - ); + if (!this.tsUtils.isImportedFromJS(identifier)) { return; } - - // 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); + const autofix = this.autofixer?.createReplacementForJsImportPropertyAccessExpression( + node as ts.PropertyAccessExpression + ); + if (!TsUtils.isInsideIfCondition(node)) { + return; } + this.incrementCounters(node, FaultID.InteropJsObjectConditionJudgment, autofix); } private fixJsImportElementAccessExpression(elementAccessExpr: ts.ElementAccessExpression): void { if (!this.options.arkts2 || !this.useStatic) { return; } - + if (!TypeScriptLinter.isInForLoopBody(elementAccessExpr)) { + return; + } const variableDeclaration = ts.isIdentifier(elementAccessExpr.expression) ? this.tsUtils.findVariableDeclaration(elementAccessExpr.expression) : undefined; @@ -7818,58 +10595,54 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - const autofix = this.autofixer?.createReplacementJsImportElementAccessExpression( - elementAccessExpr, - elementAccessExpr.expression as ts.Identifier - ); + const autofix = this.autofixer?.fixJsImportElementAccessExpression(elementAccessExpr); this.incrementCounters(elementAccessExpr, FaultID.InteropJsObjectTraverseJsInstance, autofix); } - private handleTaskPoolDeprecatedUsages(node: ts.CallExpression): void { - if (!this.options.arkts2 || !this.useStatic) { - return; + private static isInForLoopBody(node: ts.Node): boolean { + let current: ts.Node | undefined = node.parent; + while (current) { + if (ts.isForStatement(current) || ts.isForInStatement(current) || ts.isForOfStatement(current)) { + return true; + } + current = current.parent; } + return false; + } - if (!ts.isPropertyAccessExpression(node.expression)) { + private handleTaskPoolDeprecatedUsages(propertyAccess: ts.PropertyAccessExpression): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - - const propertyAccess = node.expression; - const objectExpr = propertyAccess.expression; - + const objectExpr = ts.isNewExpression(propertyAccess.expression) ? + propertyAccess.expression.expression : + propertyAccess.expression; // Step 1: Must be either setCloneList or setTransferList if (!TypeScriptLinter.isDeprecatedTaskPoolMethodCall(propertyAccess)) { return; } - - if (!ts.isIdentifier(objectExpr)) { - return; - } - - // Step 2: Resolve declaration of task - const variableDecl = this.tsUtils.findVariableDeclaration(objectExpr); - if (!variableDecl?.initializer || !ts.isNewExpression(variableDecl.initializer)) { + const variableDecl = TsUtils.getDeclaration(this.tsUtils.trueSymbolAtLocation(objectExpr)); + const isNoContinue = + !variableDecl || + !ts.isVariableDeclaration(variableDecl) || + !variableDecl?.initializer || + !ts.isNewExpression(variableDecl.initializer); + if (isNoContinue) { return; } - - // Step 3: Check new taskpool.Task() const taskpoolExpr = variableDecl.initializer.expression; - if (!TypeScriptLinter.isTaskPoolTaskCreation(taskpoolExpr)) { + if (!this.isTaskPoolTaskCreation(taskpoolExpr)) { return; } - const faultId = propertyAccess.name.text === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST ? FaultID.SetCloneListDeprecated : FaultID.SetTransferListDeprecated; - this.incrementCounters(node.parent, faultId); + this.incrementCounters(propertyAccess.name, 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 || @@ -7877,882 +10650,4962 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ); } - 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 isTaskPoolTaskCreation(taskpoolExpr: ts.Expression): boolean { + if ( + ts.isIdentifier(taskpoolExpr) || + ts.isPropertyAccessExpression(taskpoolExpr) && taskpoolExpr.name.text === STDLIB_TASK_CLASS_NAME + ) { + const objectExpr = ts.isIdentifier(taskpoolExpr) ? taskpoolExpr : taskpoolExpr.expression; + return this.isTaskPoolReferenceisTaskPoolImportForTaskPoolDeprecatedUsages(objectExpr); + } + return false; } - private checkStdLibConcurrencyImport(importDeclaration: ts.ImportDeclaration): void { + private isTaskPoolReferenceisTaskPoolImportForTaskPoolDeprecatedUsages(expr: ts.Expression): boolean { + if (ts.isIdentifier(expr)) { + const sym = this.tsTypeChecker.getSymbolAtLocation(expr); + const importChild = TsUtils.getDeclaration(sym); + if (!importChild) { + return false; + } + if (ts.isImportSpecifier(importChild)) { + return TypeScriptLinter.isTaskPoolImportForTaskPoolDeprecatedUsages(importChild); + } + if (ts.isImportClause(importChild) && importChild.name?.text === STDLIB_TASKPOOL_OBJECT_NAME) { + return TypeScriptLinter.checkModuleSpecifierForTaskPoolDeprecatedUsages(importChild.parent); + } + } + if (ts.isPropertyAccessExpression(expr)) { + return this.isTaskPoolReferenceOnPropertyAccessExpression(expr); + } + return false; + } + + private static checkModuleSpecifierForTaskPoolDeprecatedUsages(importDecl: ts.ImportDeclaration): boolean { + if (ts.isImportDeclaration(importDecl) && ts.isStringLiteral(importDecl.moduleSpecifier)) { + const moduleSpecifier = importDecl.moduleSpecifier; + return TASKPOOL_MODULES.includes(TsUtils.removeOrReplaceQuotes(moduleSpecifier.getText(), false)); + } + return false; + } + + private isTaskPoolReferenceOnPropertyAccessExpression(expr: ts.PropertyAccessExpression): boolean { + if (expr.name.text !== STDLIB_TASKPOOL_OBJECT_NAME || !ts.isIdentifier(expr.expression)) { + return false; + } + const sym = this.tsTypeChecker.getSymbolAtLocation(expr.expression); + const importChild = TsUtils.getDeclaration(sym); + if (importChild && ts.isNamespaceImport(importChild)) { + return TypeScriptLinter.checkModuleSpecifierForTaskPoolDeprecatedUsages(importChild.parent.parent); + } + return false; + } + + private static isTaskPoolImportForTaskPoolDeprecatedUsages(specifier: ts.ImportSpecifier): boolean { + const specifierName = specifier.propertyName ? specifier.propertyName : specifier.name; + if (STDLIB_TASKPOOL_OBJECT_NAME !== specifierName.text) { + return false; + } + const importDeclaration = specifier.parent.parent.parent; + return TypeScriptLinter.checkModuleSpecifierForTaskPoolDeprecatedUsages(importDeclaration); + } + + private checkSdkAbilityLifecycleMonitor(callExpr: ts.CallExpression): void { if (!this.options.arkts2) { return; } - const importClause = importDeclaration.importClause; - if (!importClause) { + // Guard: must be a property-access .on + if (!this.isOnMethod(callExpr)) { return; } - const moduleName = (importDeclaration.moduleSpecifier as ts.StringLiteral).text; - const expectedImports = MODULE_IMPORTS[moduleName]; - if (!expectedImports) { + // Guard: left side must be applicationContext + if (!this.isApplicationContext(callExpr)) { return; } - const defaultImport = importClause.name; - const namedBindings = importClause.namedBindings; + // Guard: exactly two arguments + const args = callExpr.arguments; + if (args.length !== 2) { + return; + } - 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); - }); + // Guard: first arg must be string literal "abilityLifecycle" + const eventArg = args[0]; + if (!ts.isStringLiteral(eventArg) || eventArg.text !== 'abilityLifecycle') { + return; + } + // Guard: second arg must be a variable declared as AbilityLifecycleCallback + const cbArg = args[1]; + if (!ts.isIdentifier(cbArg)) { + return; + } + const varSym = this.tsUtils.trueSymbolAtLocation(cbArg); + const decl = varSym?.declarations?.find(ts.isVariableDeclaration); if ( - TypeScriptLinter.shouldRemoveWholeImport( - defaultIsForbidden, - forbiddenNamed.length, - namedImports.length, - defaultImport - ) + !decl?.type || + !ts.isTypeReferenceNode(decl.type) || + decl.type.typeName.getText() !== 'AbilityLifecycleCallback' ) { - const autofix = this.autofixer?.removeNode(importDeclaration); - this.incrementCounters(importDeclaration, FaultID.LimitedStdLibNoImportConcurrency, autofix); return; } - if (defaultIsForbidden) { - const autofix = this.autofixer?.removeDefaultImport(importDeclaration, defaultImport); - this.incrementCounters(defaultImport, FaultID.LimitedStdLibNoImportConcurrency, autofix); - } + // Report the legacy callback usage + this.incrementCounters(callExpr, FaultID.SdkAbilityLifecycleMonitor); + } - for (const spec of forbiddenNamed) { - const autofix = this.autofixer?.removeImportSpecifier(spec, importDeclaration); - this.incrementCounters(spec, FaultID.LimitedStdLibNoImportConcurrency, autofix); + private isOnMethod(node: ts.CallExpression): boolean { + void this; + const expr = node.expression; + return ts.isPropertyAccessExpression(expr) && expr.name.text === 'on'; + } + + private isApplicationContext(node: ts.CallExpression): boolean { + const expr = node.expression as ts.PropertyAccessExpression; + if (!ts.isIdentifier(expr.expression)) { + return false; } + const type = this.tsTypeChecker.getTypeAtLocation(expr.expression); + const symbol = type.getSymbol(); + return symbol ? this.checkApplicationContextSymbol(symbol) : false; } - 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 - ); + private checkApplicationContextSymbol(symbol: ts.Symbol): boolean { + void this; + if (symbol.getName() === 'default') { + const declarations = symbol.getDeclarations() || []; + for (const decl of declarations) { + if ( + ts.isClassDeclaration(decl) && + decl.name?.getText() === ABILITY_LIFECYCLE_SDK && + decl.getSourceFile().fileName.endsWith(`${ABILITY_LIFECYCLE_SDK}${EXTNAME_D_TS}`) + ) { + return true; + } + } + return false; + } + const symbolName = symbol.getName(); + const hasValidName = symbolName === ABILITY_LIFECYCLE_SDK; + if (hasValidName) { + const declarations = symbol.getDeclarations() || []; + return declarations.some((decl) => { + return decl.getSourceFile().fileName.endsWith(`${ABILITY_LIFECYCLE_SDK}${EXTNAME_D_TS}`); + }); + } + return false; } - /** - * 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 { + private handleForOfJsArray(node: ts.ForOfStatement): void { if (!this.options.arkts2 || !this.useStatic) { return; } - // We are only interested in 'extends' clauses - if (node.token !== ts.SyntaxKind.ExtendsKeyword) { + const expr = node.expression; + if (!ts.isIdentifier(expr) || !this.tsUtils.isPossiblyImportedFromJS(expr)) { return; } - // Get the parent class declaration (what the child class extends) - const parentClass = this.getParentClassDeclaration(node); - if (!parentClass) { - return; - } + const exprType = this.tsTypeChecker.getTypeAtLocation(expr); - // If parent class has a parameterless constructor (or no constructor at all), child is fine - if (TypeScriptLinter.parentHasParameterlessConstructor(parentClass)) { + if (!this.tsUtils.isArray(exprType)) { return; } - // The child class node (the one extending) - const childClass = node.parent; - if (!ts.isClassDeclaration(childClass)) { + const autofix = this.autofixer?.applyForOfJsArrayFix(node); + this.incrementCounters(node, FaultID.InteropJsObjectTraverseJsInstance, autofix); + } + + private checkStdLibConcurrencyImport(importDeclaration: ts.ImportDeclaration): void { + if (!this.options.arkts2) { return; } - // 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); + const importClause = importDeclaration.importClause; + if (!importClause) { + 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 moduleName = path.basename((importDeclaration.moduleSpecifier as ts.StringLiteral).text); + const expectedImports = MODULE_IMPORTS[moduleName]; + if (!expectedImports) { + return; } - const parentSymbol = this.tsUtils.trueSymbolAtLocation(parentExpr); - return parentSymbol?.declarations?.find(ts.isClassDeclaration); - } - /** - * 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; - }) - ); - } + const defaultImport = importClause.name; + const namedBindings = importClause.namedBindings; - private static childHasSuperCall(constructor: ts.ConstructorDeclaration): boolean { - let superCalled = false; + const namedImports = namedBindings && ts.isNamedImports(namedBindings) ? namedBindings.elements : []; - if (!constructor.body) { - return false; - } + const FORBIDDEN_DEFAULT_IMPORT_MODULES = Object.keys(MODULE_IMPORTS).filter((name) => { + return name !== '@kit.ArkTS'; + }); - ts.forEachChild(constructor.body, (stmt) => { - if ( - ts.isExpressionStatement(stmt) && - ts.isCallExpression(stmt.expression) && - stmt.expression.expression.kind === ts.SyntaxKind.SuperKeyword - ) { - superCalled = true; - } + const defaultIsForbidden = defaultImport && FORBIDDEN_DEFAULT_IMPORT_MODULES.includes(moduleName); + const forbiddenNamed = namedImports.filter((spec) => { + const name = spec.propertyName ? spec.propertyName.getText() : spec.name.getText(); + return expectedImports.includes(name); }); - return superCalled; - } - private handleInterOpImportJs(importDecl: ts.ImportDeclaration): void { - if (!this.options.arkts2 || !importDecl || !this.useStatic) { - return; - } - const importClause = importDecl.importClause; - if (!importClause) { - return; - } - 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); + if (defaultIsForbidden) { + if (defaultImport?.getText() === 'process') { + this.incrementCounters(defaultImport, FaultID.LimitedStdLibNoImportConcurrency); + } else { + const autofix = this.autofixer?.removeDefaultImport(importDeclaration, defaultImport, expectedImports[0]); + this.incrementCounters(defaultImport, FaultID.LimitedStdLibNoImportConcurrency, autofix); } } - const symbolToUse = defaultSymbol || symbol; - if (symbolToUse) { - this.tryAutoFixInterOpImportJs(importDecl, importClause, symbolToUse, defaultSymbol); - } - } - 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); - } - } + this.processImportSpecifier(forbiddenNamed, importDeclaration); } - 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; - } + private processImportSpecifier(forbiddenNamed: ts.ImportSpecifier[], importDeclaration: ts.ImportDeclaration): void { + for (const spec of forbiddenNamed) { + const bitVectorUsed = this.checkBitVector(spec.getSourceFile()); - 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); + if (bitVectorUsed?.used) { + const ns = bitVectorUsed.ns; + if (spec.name.text === ns) { + continue; + } + } + const autofix = this.autofixer?.removeImportSpecifier(spec, importDeclaration); + this.incrementCounters(spec, FaultID.LimitedStdLibNoImportConcurrency, autofix); } - return false; } - private handleInteropAwaitImport(callExpr: ts.CallExpression): void { - if (!this.options.arkts2 || !this.useStatic) { + /** + * Checks that each field in a subclass matches the type of the same-named field + * in its base class or implemented interfaces. + */ + private handleFieldTypesMatchingBetweenDerivedAndBaseClass(node: ts.HeritageClause): void { + if (node.token !== ts.SyntaxKind.ExtendsKeyword && node.token !== ts.SyntaxKind.ImplementsKeyword) { return; } - if (callExpr.expression.kind !== ts.SyntaxKind.ImportKeyword) { + const derivedClass = node.parent; + if (!ts.isClassDeclaration(derivedClass)) { return; } - if (ts.isAwaitExpression(callExpr.parent) || ts.isPropertyAccessExpression(callExpr.parent)) { - this.checkInteropForDynamicImport(callExpr); + for (const member of derivedClass.members) { + if (!ts.isPropertyDeclaration(member) || !ts.isIdentifier(member.name) || !member.type) { + continue; + } + const propName = member.name.text; + + // Delegate heritage comparison logic + if (this.hasFieldTypeMismatchWithBases(node, propName, member)) { + this.incrementCounters(member.name, FaultID.FieldTypeMismatch); + } } } - private checkInteropForDynamicImport(callExpr: ts.CallExpression): void { - const interopType = TsUtils.resolveModuleAndCheckInterop( - this.options.wholeProjectPath ?? path.resolve(TsUtils.getCurrentModule(callExpr.getSourceFile().fileName)), - callExpr - ); + /** + * Checks the given derived property against all base classes/interfaces + * in the heritage clause. Returns true if a mismatch is found. + */ + private hasFieldTypeMismatchWithBases( + node: ts.HeritageClause, + propName: string, + member: ts.PropertyDeclaration + ): boolean { + for (const hType of node.types) { + const baseExpr = hType?.expression; + if (!ts.isIdentifier(baseExpr)) { + continue; + } - if (!interopType) { - return; - } + const baseSym = this.tsUtils.trueSymbolAtLocation(baseExpr); + const baseDecl = baseSym?.declarations?.find(TsUtils.isClassOrInterfaceDeclaration); + if (!baseDecl) { + continue; + } - switch (interopType) { - case InteropType.JS: - this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImportJs); - break; - case InteropType.TS: - this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImportTs); - break; - case InteropType.LEGACY: - this.incrementCounters(callExpr.parent, FaultID.InteropDynamicImport); - break; - default: - break; + const baseProp = this.findPropertyDeclarationInBaseChain(baseDecl, propName); + if (!baseProp?.type) { + continue; + } + + const derivedType = this.tsTypeChecker.getTypeAtLocation(member.type!); + const baseType = this.tsTypeChecker.getTypeAtLocation(baseProp.type); + + if (!this.isFieldTypeMatchingBetweenDerivedAndBase(derivedType, baseType)) { + return true; + } } + return false; } - handleInstanceOfExpression(node: ts.BinaryExpression): void { - if (!this.options.arkts2 || !this.useStatic) { - return; + /** + * Searches the base chain (classes or interfaces) to find the first declaration + * of the given property (with a type annotation). Avoids cycles. + */ + private findPropertyDeclarationInBaseChain( + decl: ts.ClassDeclaration | ts.InterfaceDeclaration, + propName: string, + visited: Set = new Set() + ): ts.PropertyDeclaration | ts.PropertySignature | undefined { + if (visited.has(decl)) { + return undefined; } - 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); + visited.add(decl); + + if (ts.isClassDeclaration(decl)) { + return this.findPropertyInClassChain(decl, propName, visited); } + + // Interface path + return this.findPropertyInInterfaceChain(decl, propName, visited); } - 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); - } - } + /** Look for a property in a class declaration or its base classes */ + private findPropertyInClassChain( + decl: ts.ClassDeclaration, + propName: string, + visited: Set + ): ts.PropertyDeclaration | ts.PropertySignature | undefined { + // Check current class members + const member = decl.members.find((m): m is ts.PropertyDeclaration => { + return ts.isPropertyDeclaration(m) && ts.isIdentifier(m.name) && m.name.text === propName && !!m.type; + }); + if (member) { + return member; } - } - private handleObjectLiteralforUnionTypeInterop(node: ts.VariableDeclaration): void { - if (!this.options.arkts2 || !this.useStatic) { - return; + // Otherwise, follow the extends clause (single inheritance) + const ext = decl.heritageClauses?.find((c) => { + return c.token === ts.SyntaxKind.ExtendsKeyword; + }); + if (!ext || ext.types.length === 0) { + return undefined; } - if (!node.type || !ts.isUnionTypeNode(node.type)) { - return; + const expr = ext.types[0].expression; + if (!ts.isIdentifier(expr)) { + return undefined; } - if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { - return; + const sym = this.tsUtils.trueSymbolAtLocation(expr); + const nextDecl = sym?.declarations?.find(ts.isClassDeclaration); + return nextDecl ? this.findPropertyInClassChain(nextDecl, propName, visited) : undefined; + } + + /** Look for a property in an interface declaration or its extended interfaces */ + private findPropertyInInterfaceChain( + decl: ts.InterfaceDeclaration, + propName: string, + visited: Set + ): ts.PropertySignature | ts.PropertyDeclaration | undefined { + // Check current interface members + const member = decl.members.find((m): m is ts.PropertySignature => { + return ts.isPropertySignature(m) && ts.isIdentifier(m.name) && m.name.text === propName && !!m.type; + }); + if (member) { + return member; } - const typeNodes = node.type.types; + // Otherwise, follow extended interfaces + const ext = decl.heritageClauses?.find((c) => { + return c.token === ts.SyntaxKind.ExtendsKeyword; + }); + if (!ext) { + return undefined; + } - 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 t of ext.types) { + const expr = t.expression; + if (!ts.isIdentifier(expr)) { + continue; } - for (const declaration of symbol.declarations ?? []) { - if (!TsUtils.isArkts12File(declaration.getSourceFile())) { - return true; + const sym = this.tsUtils.trueSymbolAtLocation(expr); + const nextDecl = sym?.declarations?.find(ts.isInterfaceDeclaration); + if (nextDecl) { + const found = this.findPropertyInInterfaceChain(nextDecl, propName, visited); + if (found) { + return found; } } - return false; - }); + } + return undefined; + } - if (isDefected) { - this.incrementCounters(node, FaultID.InteropObjectLiteralAmbiguity); + /** + * Returns true if the union type members of subclass field's type + * exactly match those of the base field's type (order-insensitive). + * So `number|string` ↔ `string|number` passes, but `number` ↔ `number|string` fails. + */ + private isFieldTypeMatchingBetweenDerivedAndBase(derivedType: ts.Type, baseType: ts.Type): boolean { + // Split union type strings into trimmed member names + const derivedNames = this.tsTypeChecker. + typeToString(derivedType). + split('|'). + map((s) => { + return s.trim(); + }); + const baseNames = this.tsTypeChecker. + typeToString(baseType). + split('|'). + map((s) => { + return s.trim(); + }); + + // Only match if both unions contain exactly the same members + if (derivedNames.length !== baseNames.length) { + return false; } + return ( + derivedNames.every((name) => { + return baseNames.includes(name); + }) && + baseNames.every((name) => { + return derivedNames.includes(name); + }) + ); } - private handleObjectLiteralAssignmentToClass(node: ts.VariableDeclaration): void { - if (!this.options.arkts2 || !this.useStatic) { + /** + * If a class method overrides a base-class abstract method that had no explicit return type, + * then any explicit return type other than `void` is an error. + * Also flags async overrides with no explicit annotation. + */ + private checkAbstractOverrideReturnType(method: ts.MethodDeclaration): void { + if (!this.options.arkts2) { return; } - if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + + const baseClass = this.getDirectBaseClassOfGivenMethodDecl(method); + if (!baseClass) { return; } - if (!node.type) { + + // Locate the abstract method in the inheritance chain + const methodName = method.name.getText(); + const baseMethod = this.findAbstractMethodInBaseChain(baseClass, methodName); + if (!baseMethod) { return; } - const type = this.tsTypeChecker.getTypeAtLocation(node.type); - const symbol = type.getSymbol(); - if (!symbol) { + // Only if base had no explicit return type + if (baseMethod.type) { return; } - const declarations = symbol.declarations ?? []; + // If override declares a return type, and it isn't void → error + if (method.type && method.type.kind !== ts.SyntaxKind.VoidKeyword) { + const target = ts.isIdentifier(method.name) ? method.name : method; + this.incrementCounters(target, FaultID.InvalidAbstractOverrideReturnType); - const isClass = declarations.some(ts.isClassDeclaration); - if (!isClass) { - return; + // Also catch async overrides with no explicit annotation (defaulting to Promise) + } else if (TsUtils.hasModifier(method.modifiers, ts.SyntaxKind.AsyncKeyword)) { + const target = ts.isIdentifier(method.name) ? method.name : method; + this.incrementCounters(target, FaultID.InvalidAbstractOverrideReturnType); } + } - const isFromArkTs2 = declarations.some((decl) => { - return TsUtils.isArkts12File(decl.getSourceFile()); - }); - - if (isFromArkTs2) { - return; + /** + * Finds the direct superclass declaration for the given method's containing class. + * Returns undefined if the class has no extends clause or cannot resolve the base class. + */ + private getDirectBaseClassOfGivenMethodDecl(method: ts.MethodDeclaration): ts.ClassDeclaration | undefined { + // Must live in a class with an extends clause + const classDecl = method.parent; + if (!ts.isClassDeclaration(classDecl) || !classDecl.heritageClauses) { + return undefined; } - const hasConstructor = declarations.some((decl) => { - return ts.isClassDeclaration(decl) && decl.members.some(ts.isConstructorDeclaration); - }); + return this.getBaseClassDeclFromHeritageClause(classDecl.heritageClauses); + } - if (hasConstructor) { - this.incrementCounters(node, FaultID.InteropObjectLiteralClass); + /** + * Walks up the inheritance chain starting from `startClass` to find an abstract method + * named `methodName`. Returns the MethodDeclaration if found, otherwise `undefined`. + */ + private findAbstractMethodInBaseChain( + startClass: ts.ClassDeclaration, + methodName: string + ): ts.MethodDeclaration | undefined { + // Prevent infinite loops from circular extends + const visited = new Set(); + let current: ts.ClassDeclaration | undefined = startClass; + while (current && !visited.has(current)) { + visited.add(current); + const found = current.members.find((m) => { + return ( + ts.isMethodDeclaration(m) && + ts.isIdentifier(m.name) && + m.name.text === methodName && + TsUtils.hasModifier(m.modifiers, ts.SyntaxKind.AbstractKeyword) + ); + }) as ts.MethodDeclaration | undefined; + if (found) { + return found; + } + current = this.getBaseClassDeclFromHeritageClause(current.heritageClauses); } + return undefined; } - private isObjectLiteralAssignedToArkts12Type(node: ts.Expression, expectedTypeNode?: ts.TypeNode): boolean { - if (node.kind !== ts.SyntaxKind.ObjectLiteralExpression) { - return false; + getBaseClassDeclFromHeritageClause(clauses?: ts.NodeArray): ts.ClassDeclaration | undefined { + if (!clauses) { + return undefined; } - let type: ts.Type; - if (expectedTypeNode) { - type = this.tsTypeChecker.getTypeAtLocation(expectedTypeNode); - } else { - type = this.tsTypeChecker.getContextualType(node) ?? this.tsTypeChecker.getTypeAtLocation(node); + const ext = clauses.find((h) => { + return h.token === ts.SyntaxKind.ExtendsKeyword; + }); + if (!ext || ext.types.length === 0) { + return undefined; } - if (!type) { - return false; + // Resolve the base-class declaration + const expr = ext.types[0].expression; + if (!ts.isIdentifier(expr)) { + return undefined; } - return TypeScriptLinter.isTypeFromArkts12(type); + const sym = this.tsUtils.trueSymbolAtLocation(expr); + return sym?.declarations?.find(ts.isClassDeclaration); } - private static isTypeFromArkts12(type: ts.Type): boolean { - const symbol = type?.getSymbol(); - if (!symbol) { - return false; + /** + * 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) { + return; } - const isFromArkts12 = (symbol.declarations ?? []).some((decl) => { - return TsUtils.isArkts12File(decl.getSourceFile()); - }); + // We are only interested in 'extends' clauses + if (node.token !== ts.SyntaxKind.ExtendsKeyword) { + return; + } - if (isFromArkts12) { - return true; + if (!ts.isClassDeclaration(node.parent)) { + return; } - return false; - } - private processNestedObjectLiterals(objLiteral: ts.Expression, parentType?: ts.Type): void { - if (!ts.isObjectLiteralExpression(objLiteral)) { + /* + * Get the parent class declaration (what the child class extends) + * This could be a stdlib error type + */ + const identInfo = this.getExtendedIdentifiersInfo(node); + if (identInfo.type === ExtendedIdentifierType.UNKNOWN) { + // if it's unknown return return; } - objLiteral.properties.forEach((prop) => { - if (!ts.isPropertyAssignment(prop) || !ts.isObjectLiteralExpression(prop.initializer)) { + if (identInfo.type === ExtendedIdentifierType.ERROR) { + this.handleErrorClassExtend(node.parent); + // handled error case return + return; + } + + if (identInfo.type === ExtendedIdentifierType.CLASS) { + // If it's class, get the constructor's parameters and match against it. + const extendedClassInfo = this.extractExtendedClassConstructorInfo(identInfo.decl); + if (!extendedClassInfo) { return; } - if (this.isObjectLiteralAssignedToArkts12Type(prop.initializer)) { - this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + // If there are only non parametric constructions, do not check. + const value = extendedClassInfo.values().next().value; + if (extendedClassInfo.size === 1 && value && value.length === 0) { return; } - this.checkPropertyTypeFromParent(prop, parentType); - this.processNestedObjectLiterals(prop.initializer); - }); + this.handleExtendCustomClass(node.parent, extendedClassInfo, identInfo.decl.name?.text + ''); + } } - private checkPropertyTypeFromParent(prop: ts.PropertyAssignment, parentType?: ts.Type): void { - if (!parentType) { + private handleExtendCustomClass( + classDecl: ts.ClassDeclaration, + extendedClassInfo: Set, + extendedClassName: string + ): void { + const superCall = TypeScriptLinter.checkIfSuperCallExists(classDecl); + if (!superCall) { + this.incrementCounters(classDecl, FaultID.MissingSuperCall); return; } - if (!ts.isObjectLiteralExpression(prop.initializer)) { + outer: for (const ctorParams of extendedClassInfo) { + const matches: boolean[] = []; + if (superCall.arguments.length > ctorParams.length) { + continue; + } + + for (const [idx, param] of ctorParams.entries()) { + const argument = superCall.arguments[idx]; + if (!this.checkParameter(param, argument, matches, idx)) { + continue outer; + } + } + + if ( + matches.some((val) => { + return !val; + }) + ) { + continue; + } + this.handleExtendCustomClassForSdkApiDeprecated(extendedClassName, superCall, SDK_COMMON_TYPE); + this.handleExtendCustomClassForSdkApiDeprecated(extendedClassName, superCall, BUILTIN_TYPE); return; } - const propName = prop.name.getText(); - const property = parentType.getProperty(propName); + this.incrementCounters(classDecl, FaultID.MissingSuperCall); + } - if (!property?.valueDeclaration) { - return; + private checkParameter( + param: ConstructorParameter, + argument: ts.Expression | undefined, + matches: boolean[], + idx: number + ): boolean { + if (!param.isOptional && !argument) { + matches[idx] = false; + return false; } - const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(property, property.valueDeclaration); + if (!argument && param.isOptional) { + matches[idx] = true; + return true; + } - if (TypeScriptLinter.isTypeFromArkts12(propType)) { - this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + if (argument !== undefined) { + if (this.isEnumArgument(argument)) { + matches[idx] = true; + return true; + } + matches[idx] = this.checkIfArgumentAndParamMatches(param, argument); + return matches[idx]; } + return true; } - private handleObjectLiteralAssignment(node: ts.VariableDeclaration): void { - if (TsUtils.isArkts12File(node.getSourceFile())) { - return; + private isEnumArgument(argument: ts.Expression): boolean { + if (!ts.isPropertyAccessExpression(argument)) { + return false; } - if (!node.initializer) { - return; + const leftSide = argument.expression; + const symbol = this.tsTypeChecker?.getSymbolAtLocation(leftSide); + + return ( + symbol?.declarations?.some((decl) => { + return ( + ts.isEnumDeclaration(decl) || + ts.isVariableDeclaration(decl) && decl.initializer && ts.isEnumDeclaration(decl.initializer) + ); + }) ?? false + ); + } + + private handleExtendCustomClassForSdkApiDeprecated( + extendedClassName: string, + superCall: ts.CallExpression, + apiType: string + ): void { + const problemStr = TypeScriptLinter.getFaultIdSdkApiInfoWithConstructorDecl(extendedClassName, apiType); + if (problemStr) { + const faultID = sdkCommonAllDeprecatedTypeName.has(extendedClassName) ? + FaultID.SdkCommonApiDeprecated : + TypeScriptLinter.getFinalSdkFaultIdByProblem(problemStr, apiType); + if (!faultID) { + return; + } + this.incrementCounters( + superCall, + faultID, + undefined, + apiType === SDK_COMMON_TYPE ? + TypeScriptLinter.getErrorMsgForSdkCommonApi(extendedClassName, faultID) : + undefined + ); + } + } + + private static getErrorMsgForSdkCommonApi(name: string, faultID: number): string { + let errorMsg = cookBookMsg[faultID]; + if (faultID === FaultID.SdkCommonApiDeprecated || faultID === FaultID.SdkCommonApiWhiteList) { + errorMsg = `The "${name}" in SDK is no longer supported.(sdk-method-not-supported)`; + } else if (faultID === FaultID.SdkCommonApiBehaviorChange) { + errorMsg = `The "${name}" in SDK has been changed.(sdk-method-changed)`; + } else if (faultID === FaultID.NoDeprecatedApi) { + errorMsg = `The ArkUI interface "${name}" is deprecated (arkui-deprecated-interface)`; + } + return errorMsg; + } + + private checkIfArgumentAndParamMatches(param: ConstructorParameter, argument: ts.Expression): boolean { + const typeNode = this.tsTypeChecker.getTypeAtLocation(argument); + const typeString = this.tsTypeChecker.typeToString(typeNode); + + if (param.type.includes(STRINGLITERAL_STRING) && argument.kind === ts.SyntaxKind.StringLiteral) { + return true; + } + if (param.type.includes(NUMBER_LITERAL) && argument.kind === ts.SyntaxKind.NumericLiteral) { + return true; } if ( - ts.isObjectLiteralExpression(node.initializer) && - this.isObjectLiteralAssignedToArkts12Type(node.initializer, node.type) + param.type.includes('boolean') && + (argument.kind === ts.SyntaxKind.FalseKeyword || argument.kind === ts.SyntaxKind.TrueKeyword) ) { - this.incrementCounters(node.initializer, FaultID.InteropStaticObjectLiterals); - return; + return true; } - const parentType = node.type ? - this.tsTypeChecker.getTypeAtLocation(node.type) : - this.tsTypeChecker.getTypeAtLocation(node.initializer); + if (param.type === typeString) { + return true; + } - this.processNestedObjectLiterals(node.initializer, parentType); + return false; } - private handleObjectLiteralInFunctionArgs(node: ts.CallExpression): void { - if (TsUtils.isArkts12File(node.getSourceFile())) { + private handleErrorClassExtend(classDecl: ts.ClassDeclaration): void { + // if it's Error, the super method should be called with no arguments or a single string argument + const superCall = TypeScriptLinter.checkIfSuperCallExists(classDecl); + if (!superCall) { + this.incrementCounters(classDecl, FaultID.MissingSuperCall); return; } - const signature = this.tsTypeChecker.getResolvedSignature(node); - if (!signature) { + + if (superCall.arguments.length > 1) { + + /* + * STD Error Type have two constructors + * either empty constructor which is just "Error" message + * or the message you provide, so if it's more than one argument provided, + * this should be raised as an issue + */ + this.incrementCounters(classDecl, FaultID.MissingSuperCall); return; } - const params = signature.getParameters(); + if (superCall.arguments.length === 1) { + const argument = superCall.arguments[0]; + const typeNode = this.tsTypeChecker.getTypeAtLocation(argument); + const typeString = this.tsTypeChecker.typeToString(typeNode); - node.arguments.forEach((arg, index) => { - if (!ts.isObjectLiteralExpression(arg)) { + if (typeString === 'string' || ts.isStringLiteral(argument) || ts.isNumericLiteral(argument)) { return; } + this.incrementCounters(classDecl, FaultID.MissingSuperCall); + } + } - if (index < params.length) { - const param = params[index]; - if (!param.valueDeclaration) { - return; - } - - const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, param.valueDeclaration); + private static checkIfSuperCallExists(classDecl: ts.ClassDeclaration): ts.CallExpression | undefined { + // check if current class has constructor + const constructor = TypeScriptLinter.getConstructorOfClass(classDecl); + if (!constructor) { + return undefined; + } + const superCallExpr = TypeScriptLinter.getSuperCallExpr(constructor); + if (!superCallExpr) { + return undefined; + } - if (TypeScriptLinter.isTypeFromArkts12(paramType)) { - this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); - } - } else if (this.isObjectLiteralAssignedToArkts12Type(arg)) { - this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); - } - }); + return superCallExpr; } - private handleObjectLiteralInReturn(node: ts.ReturnStatement): void { - if (TsUtils.isArkts12File(node.getSourceFile())) { - return; + /** + * Extracts the type of the Identifier node from an extends heritage clause. + */ + private getExtendedIdentifiersInfo(node: ts.HeritageClause): ExtendedIdentifierInfo { + const extendedIdentifier = node.types[0]?.expression; + if (!extendedIdentifier) { + return { type: ExtendedIdentifierType.UNKNOWN }; } - if (!node.expression || !ts.isObjectLiteralExpression(node.expression)) { - return; + const symbol = this.tsUtils.trueSymbolAtLocation(extendedIdentifier); + if (!symbol) { + return { type: ExtendedIdentifierType.UNKNOWN }; } - let current: ts.Node = node; - let functionNode: ts.FunctionLikeDeclaration | undefined; + if (symbol.getName().includes(STRING_ERROR_LITERAL)) { + const declaration = this.tsUtils.getDeclarationNode(extendedIdentifier); + if (!declaration) { + return { type: ExtendedIdentifierType.ERROR }; + } - while (current && !functionNode) { - current = current.parent; - if ( - current && - (ts.isFunctionDeclaration(current) || - ts.isMethodDeclaration(current) || - ts.isFunctionExpression(current) || - ts.isArrowFunction(current)) - ) { - functionNode = current; + if (declaration.getSourceFile().fileName !== this.sourceFile.fileName) { + return { type: ExtendedIdentifierType.ERROR }; } } - if (functionNode?.type) { - const returnType = this.tsTypeChecker.getTypeAtLocation(functionNode.type); - if (TypeScriptLinter.isTypeFromArkts12(returnType)) { - this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); - } - } else if (this.isObjectLiteralAssignedToArkts12Type(node.expression)) { - this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); + const classDecl = symbol?.declarations?.find(ts.isClassDeclaration); + if (!classDecl) { + return { type: ExtendedIdentifierType.UNKNOWN }; } + + return { type: ExtendedIdentifierType.CLASS, decl: classDecl }; } - private handleLocalBuilderDecorator(node: ts.Node): void { - if (!this.options.arkts2) { - return; - } - if (!ts.isDecorator(node) || !ts.isIdentifier(node.expression)) { - return; + private extractExtendedClassConstructorInfo(extendedClass: ts.ClassDeclaration): BaseClassConstructorInfo { + const constructors = extendedClass.members.filter(ts.isConstructorDeclaration); + if (constructors.length === 0) { + return undefined; } - const decoratorName = node.expression.getText(); - if (decoratorName === CustomDecoratorName.LocalBuilder) { - const autofix = this.autofixer?.fixBuilderDecorators(node); - this.incrementCounters(node, FaultID.LocalBuilderDecoratorNotSupported, autofix); + + const allConstructorInformation: BaseClassConstructorInfo = new Set(); + for (const ctor of constructors) { + const allParams: ConstructorParameter[] = []; + const parameters = ctor.parameters; + for (const param of parameters) { + const ident = param.name; + const name = ident.getText(); + const type = this.tsTypeChecker.getTypeAtLocation(ident); + const typeString = this.tsTypeChecker.typeToString(type); + const isOptional = !!param.questionToken; + const info = { name, type: typeString, isOptional }; + + allParams.push(info); + } + allConstructorInformation.add(allParams); } + + return allConstructorInformation; } - private checkEnumGetMemberValue(node: ts.ElementAccessExpression): void { - if (!this.options.arkts2) { - return; + private static getConstructorOfClass(classDecl: ts.ClassDeclaration): ts.ConstructorDeclaration | undefined { + if (classDecl.members.length === 0) { + return undefined; } - if (!ts.isIdentifier(node.expression) || !ts.isNumericLiteral(node.argumentExpression)) { - return; + for (const member of classDecl.members) { + if (!ts.isConstructorDeclaration(member)) { + continue; + } + return member; } + return undefined; + } - const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); - if (!symbol?.declarations) { - return; + private static getSuperCallExpr(constructor: ts.ConstructorDeclaration): ts.CallExpression | undefined { + if (!constructor.body) { + return undefined; } - for (const decl of symbol.declarations) { - if (ts.isEnumDeclaration(decl)) { - this.incrementCounters(node, FaultID.UnsupportPropNameFromValue); - return; + for (const stmt of constructor.body.statements) { + if (!ts.isExpressionStatement(stmt)) { + continue; + } + const callExpr = stmt.expression; + if (!ts.isCallExpression(callExpr)) { + continue; } + if (callExpr.expression.kind !== ts.SyntaxKind.SuperKeyword) { + continue; + } + + return callExpr; } + return undefined; } - private handleMakeObserved(node: ts.PropertyAccessExpression): void { - if (!this.options.arkts2) { + private handleInterOpImportJs(importDecl: ts.ImportDeclaration): void { + if (!this.options.arkts2 || !importDecl || !this.useStatic) { return; } - - const name = node.name; - if (name.getText() !== MAKE_OBSERVED) { + const importClause = importDecl.importClause; + if (!importClause) { return; } - - const expr = node.expression; - const symbol = this.tsTypeChecker.getSymbolAtLocation(expr); + 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) && namedBindings.elements?.length > 0 && namedBindings.elements[0]?.name) { + 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, symbolToUse); + } + } + + private tryAutoFixInterOpImportJs(importDecl: ts.ImportDeclaration, symbolToUse: ts.Symbol): void { + const declaration = symbolToUse.declarations?.[0]; + if (declaration) { + const sourceFile = declaration.getSourceFile(); + if (sourceFile.fileName.endsWith(EXTNAME_JS)) { + this.incrementCounters(importDecl, FaultID.InterOpImportJs); + } + } + } + + 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; + } + + 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; + } + + handleInstanceOfExpression(node: ts.BinaryExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + 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)) { + return; + } + + const autofix = this.autofixer?.fixInteropJsInstanceOfExpression(node); + this.incrementCounters(node, FaultID.InteropJsInstanceof, autofix); + } + + handleInstanceOfFunction(node: ts.BinaryExpression): void { + const right = node.right; + const symbol = this.tsUtils.trueSymbolAtLocation(right); + if (!symbol) { + return; + } + + const visitedSymbols = new Set(); + if (this.checkSymbolDeclarationsForInstanceOfFunction(symbol, visitedSymbols)) { + this.incrementCounters(right, FaultID.InstanceOfFunction); + } + } + + private checkSymbolDeclarationsForInstanceOfFunction(symbol: ts.Symbol, visited: Set): boolean { + if (visited.has(symbol)) { + return false; + } + visited.add(symbol); + const declarations = symbol.getDeclarations() || []; + for (const decl of declarations) { + const sourceFile = decl.getSourceFile(); + if (!sourceFile?.fileName) { + continue; + } + + if (!sourceFile.fileName.endsWith(ETS)) { + continue; + } + + if (ts.isFunctionDeclaration(decl)) { + return true; + } + + if (ts.isVariableDeclaration(decl) && decl.initializer) { + const initSymbol = this.tsUtils.trueSymbolAtLocation(decl.initializer); + if (!!initSymbol && this.checkSymbolDeclarationsForInstanceOfFunction(initSymbol, visited)) { + return true; + } + continue; + } + } + return false; + } + + private checkAutoIncrementDecrement(unaryExpr: ts.PostfixUnaryExpression | ts.PrefixUnaryExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + + if (!ts.isPropertyAccessExpression(unaryExpr.operand)) { + return; + } + + const propertyAccess = unaryExpr.operand; + if (!this.tsUtils.isJsImport(propertyAccess.expression)) { + return; + } + + const autofix = this.autofixer?.fixUnaryIncrDecr(unaryExpr, propertyAccess); + + this.incrementCounters(unaryExpr, FaultID.InteropIncrementDecrement, autofix); + } + + private handleObjectLiteralforUnionTypeInterop(node: ts.VariableDeclaration): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!node.type || !ts.isUnionTypeNode(node.type)) { + return; + } + + if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return; + } + + 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 (!this.tsUtils.isArkts12File(declaration.getSourceFile()) && !isStdLibrarySymbol(symbol)) { + return true; + } + } + return false; + }); + + if (isDefected) { + this.incrementCounters(node, FaultID.InteropObjectLiteralAmbiguity); + } + } + + 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; + } + + 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 reportIfAssignedToNonArkts2Class(type: ts.Type, expr: ts.ObjectLiteralExpression): void { + const symbol = type.getSymbol(); + if (!symbol) { + return; + } + + const declarations = symbol.declarations ?? []; + const isClass = declarations.some(ts.isClassDeclaration); + if (!isClass) { + return; + } + + const isFromArkTs2 = declarations.some((decl) => { + return this.tsUtils.isArkts12File(decl.getSourceFile()); + }); + + if (isFromArkTs2) { + return; + } + + const hasConstructor = declarations.some((decl) => { + return ts.isClassDeclaration(decl) && decl.members.some(ts.isConstructorDeclaration); + }); + + if (hasConstructor) { + this.incrementCounters(expr, FaultID.InteropObjectLiteralClass); + } + } + + private checkVariableDeclarationForObjectLiteral(node: ts.VariableDeclaration): void { + if (!node.initializer || !node.type) { + return; + } + + 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); + } + } + + 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); + } + } + } + + 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 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 checkPropertyDeclarationForObjectLiteral(node: ts.PropertyDeclaration): void { + if (!node.initializer || !ts.isObjectLiteralExpression(node.initializer) || !node.type) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + this.reportIfAssignedToNonArkts2Class(type, node.initializer); + } + + private checkAsExpressionForObjectLiteral(node: ts.AsExpression): void { + if (!ts.isObjectLiteralExpression(node.expression)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + this.reportIfAssignedToNonArkts2Class(type, node.expression); + } + + private checkBinaryExpressionForObjectLiteral(node: ts.BinaryExpression): void { + if (node.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return; + } + if (!ts.isObjectLiteralExpression(node.right)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(node.left); + this.reportIfAssignedToNonArkts2Class(type, node.right); + } + + private isObjectLiteralAssignedToArkts12Type(node: ts.Expression, expectedTypeNode?: ts.TypeNode): boolean { + if (node.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return false; + } + + let type: ts.Type; + if (expectedTypeNode) { + type = this.tsTypeChecker.getTypeAtLocation(expectedTypeNode); + } else { + type = this.tsTypeChecker.getContextualType(node) ?? this.tsTypeChecker.getTypeAtLocation(node); + } + + if (!type) { + return false; + } + + return this.isTypeFromArkts12(type); + } + + private isTypeFromArkts12(type: ts.Type): boolean { + const symbol = type?.getSymbol(); + if (!symbol) { + return false; + } + + const isFromArkts12 = (symbol.declarations ?? []).some((decl) => { + return this.tsUtils.isArkts12File(decl.getSourceFile()); + }); + + if (isFromArkts12) { + return true; + } + return false; + } + + private processNestedObjectLiterals(objLiteral: ts.Expression, parentType?: ts.Type): void { + if (!ts.isObjectLiteralExpression(objLiteral)) { + return; + } + + objLiteral.properties.forEach((prop) => { + if (!ts.isPropertyAssignment(prop) || !ts.isObjectLiteralExpression(prop.initializer)) { + return; + } + + if (this.isObjectLiteralAssignedToArkts12Type(prop.initializer)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + return; + } + + this.checkPropertyTypeFromParent(prop, parentType); + this.processNestedObjectLiterals(prop.initializer); + }); + } + + private checkPropertyTypeFromParent(prop: ts.PropertyAssignment, parentType?: ts.Type): void { + if (!parentType) { + return; + } + if (!ts.isObjectLiteralExpression(prop.initializer)) { + return; + } + + const propName = prop.name.getText(); + const property = parentType.getProperty(propName); + + if (!property?.valueDeclaration) { + return; + } + + const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(property, property.valueDeclaration); + + if (this.isTypeFromArkts12(propType)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + } + } + + private handleObjectLiteralAssignment(node: ts.VariableDeclaration): void { + if (this.tsUtils.isArkts12File(node.getSourceFile())) { + return; + } + + if (!node.initializer) { + return; + } + + if ( + ts.isObjectLiteralExpression(node.initializer) && + this.isObjectLiteralAssignedToArkts12Type(node.initializer, node.type) + ) { + this.incrementCounters(node.initializer, FaultID.InteropStaticObjectLiterals); + return; + } + + const parentType = node.type ? + this.tsTypeChecker.getTypeAtLocation(node.type) : + this.tsTypeChecker.getTypeAtLocation(node.initializer); + + this.processNestedObjectLiterals(node.initializer, parentType); + } + + private handleObjectLiteralInFunctionArgs(node: ts.CallExpression): void { + if (this.tsUtils.isArkts12File(node.getSourceFile())) { + return; + } + const signature = this.tsTypeChecker.getResolvedSignature(node); + if (!signature) { + return; + } + + 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 (this.isTypeFromArkts12(paramType)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + } else if (this.isObjectLiteralAssignedToArkts12Type(arg)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + }); + } + + private handleObjectLiteralInReturn(node: ts.ReturnStatement): void { + if (this.tsUtils.isArkts12File(node.getSourceFile())) { + return; + } + + if (!node.expression || !ts.isObjectLiteralExpression(node.expression)) { + 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 (this.isTypeFromArkts12(returnType)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); + } + } else if (this.isObjectLiteralAssignedToArkts12Type(node.expression)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); + } + } + + private handleLocalBuilderDecorator(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + if (!ts.isDecorator(node) || !ts.isIdentifier(node.expression)) { + return; + } + const decoratorName = node.expression.getText(); + if (decoratorName === CustomInterfaceName.LocalBuilder) { + const autofix = this.autofixer?.fixBuilderDecorators(node); + this.incrementCounters(node, FaultID.LocalBuilderDecoratorNotSupported, autofix); + } + } + + private checkEnumGetMemberValue(node: ts.ElementAccessExpression): void { + if (!this.options.arkts2) { + return; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); + if (!symbol?.declarations) { + return; + } + + for (const decl of symbol.declarations) { + if (ts.isEnumDeclaration(decl) && this.shouldIncrementCounters(node)) { + this.incrementCounters(node, FaultID.UnsupportPropNameFromValue); + return; + } + } + } + + private shouldIncrementCounters(node: ts.ElementAccessExpression): boolean { + const indexExpr = node.argumentExpression; + if (!indexExpr) { + return false; + } + if (ts.isStringLiteral(indexExpr) || ts.isNumericLiteral(indexExpr)) { + return true; + } + const indexType = this.tsTypeChecker.getTypeAtLocation(indexExpr); + const typeString = this.tsTypeChecker.typeToString(indexType); + if (typeString === 'number' || typeString === 'string') { + return true; + } + const baseExprSym = this.tsUtils.trueSymbolAtLocation(node.expression); + if (indexType.isUnion()) { + return indexType.types.some((t) => { + return this.isInvalidEnumMemberType(t, baseExprSym); + }); + } + return this.isInvalidEnumMemberType(indexType, baseExprSym); + } + + private isInvalidEnumMemberType(indexType: ts.Type, baseExprSym: ts.Symbol | undefined): boolean { + const indexSym = indexType.getSymbol(); + if (!indexSym) { + return false; + } + return !indexSym.declarations?.some((decl) => { + if (decl && ts.isEnumDeclaration(decl.parent) && ts.isEnumMember(decl)) { + const enumDeclSym = this.tsUtils.trueSymbolAtLocation(decl.parent.name); + return enumDeclSym === baseExprSym; + } + return false; + }); + } + + private handleMakeObserved(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + + const name = node.name; + if (name.getText() !== MAKE_OBSERVED) { + return; + } + + const expr = node.expression; + const symbol = this.tsTypeChecker.getSymbolAtLocation(expr); const importSpecifier = TsUtils.getDeclaration(symbol); if (!importSpecifier || !ts.isImportSpecifier(importSpecifier)) { return; } - const importDecl = ts.findAncestor(importSpecifier, ts.isImportDeclaration); - if (!importDecl) { + const importDecl = ts.findAncestor(importSpecifier, ts.isImportDeclaration); + if (!importDecl) { + return; + } + + const moduleSpecifier = importDecl.moduleSpecifier; + if (!ts.isStringLiteral(moduleSpecifier)) { + return; + } + if (moduleSpecifier.text !== ARKUI_MODULE && moduleSpecifier.text !== STATE_MANAGEMENT_MODULE) { + return; + } + + const callExpr = node.parent; + if (!callExpr || !ts.isCallExpression(callExpr)) { + return; + } + + const arg = callExpr.arguments?.[0]; + if (!arg) { + return; + } + + if (!this.isCustomClass(arg)) { + return; + } + + this.incrementCounters(node, FaultID.MakeObservedCannotObserveCustomClass); + } + + private isCustomClass(node: ts.Node): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(node); + const typeSymbol = type.getSymbol(); + if (!typeSymbol) { + return false; + } + + const decl = TsUtils.getDeclaration(typeSymbol); + return decl !== undefined && decl.getSourceFile() === node.getSourceFile() && ts.isClassDeclaration(decl); + } + + private handlePropertyDeclarationForProp(node: ts.PropertyDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const decorator = ts.getDecorators(node)?.[0]; + if (!decorator) { + return; + } + + let identifier: ts.Identifier | undefined; + if (ts.isIdentifier(decorator.expression)) { + identifier = decorator.expression; + } else if (ts.isCallExpression(decorator.expression) && ts.isIdentifier(decorator.expression.expression)) { + identifier = decorator.expression.expression; + } + + if (!identifier) { + return; + } + + const decoratorName = identifier.getText(); + const autofix = this.autofixer?.fixPropDecorator(identifier, decoratorName); + switch (decoratorName) { + case PropDecoratorName.Prop: + this.incrementCounters(node, FaultID.PropDecoratorNotSupported, autofix); + break; + case PropDecoratorName.StorageProp: + this.incrementCounters(node, FaultID.StoragePropDecoratorNotSupported, autofix); + break; + case PropDecoratorName.LocalStorageProp: + this.incrementCounters(node, FaultID.LocalStoragePropDecoratorNotSupported, autofix); + break; + default: + } + } + + private handleVariableDeclarationForProp(node: ts.VariableDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const callExpr = node.initializer; + if (!callExpr || !ts.isCallExpression(callExpr)) { + return; + } + + const propertyAccessExpr = callExpr.expression; + if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { + return; + } + + const storage = propertyAccessExpr.expression; + if ( + !ts.isIdentifier(storage) || + !this.isTargetStorageType(storage, [StorageTypeName.LocalStorage, StorageTypeName.AppStorage]) + ) { + return; + } + + 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 isTargetStorageType(storage: ts.Identifier, targetTypes: string[]): boolean { + const decl = this.tsUtils.getDeclarationNode(storage); + if (!decl || decl.getSourceFile() !== storage.getSourceFile()) { + return targetTypes.includes(storage.getText()); + } + + if (!ts.isVariableDeclaration(decl)) { + return false; + } + + 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; + } + } + + if (!storageType || !ts.isIdentifier(storageType)) { + return false; + } + + return targetTypes.includes(storageType.getText()); + } + + private handlePropertyAssignmentForProp(node: ts.PropertyAssignment): void { + if (!this.options.arkts2) { + return; + } + + const callExpr = node.parent.parent; + if (!ts.isCallExpression(callExpr)) { + return; + } + + const structDecl = TsUtils.getDeclaration(this.tsTypeChecker.getSymbolAtLocation(callExpr.expression)); + if (!structDecl || !ts.isStructDeclaration(structDecl) || !structDecl.name) { + return; + } + + const variable = node.name; + if (!ts.isIdentifier(variable)) { + return; + } + + const targetNode = TypeScriptLinter.findVariableChangeNodeInStruct(variable, structDecl); + if (!targetNode) { + return; + } + + const targetDecl = TsUtils.getDeclaration(this.tsTypeChecker.getSymbolAtLocation(targetNode)); + if (!targetDecl || !ts.isPropertyDeclaration(targetDecl)) { + return; + } + + const decorators = ts.getDecorators(targetDecl); + if (!decorators || decorators.length === 0) { + return; + } + + const decorator = decorators[0]; + const decoratorName = TsUtils.getDecoratorName(decorator); + if (decoratorName === PropDecoratorName.Prop) { + this.incrementCounters(node, FaultID.PropNeedCallMethodForDeepCopy); + } + } + + private static findVariableChangeNodeInStruct( + variable: ts.Identifier, + structDecl: ts.StructDeclaration + ): ts.MemberName | undefined { + let changeNode: ts.MemberName | undefined; + + function traverse(node: ts.Node): void { + if (changeNode) { + return; + } + + if (ts.isPropertyAccessExpression(node)) { + if ( + node.expression.kind === ts.SyntaxKind.ThisKeyword && + node.name.getText() === variable.getText() && + (ts.findAncestor(node, ts.isPostfixUnaryExpression) || + ts.findAncestor(node, ts.isPrefixUnaryExpression) || + ts.findAncestor(node, ts.isBinaryExpression)) + ) { + changeNode = node.name; + } + } + + ts.forEachChild(node, traverse); + } + + traverse(structDecl); + return changeNode; + } + + private getIdentifierForAwaitExpr(awaitExpr: ts.AwaitExpression): IdentifierAndArguments { + void this; + + let ident: undefined | ts.Identifier; + let args: ts.NodeArray | undefined; + + const expr = awaitExpr.expression; + if (ts.isCallExpression(expr)) { + if (ts.isIdentifier(expr.expression)) { + ident = expr.expression; + } + + if (ts.isPropertyAccessExpression(expr.expression)) { + if (ts.isIdentifier(expr.expression.name)) { + ident = expr.expression.name; + } + } + args = expr.arguments; + } else if (ts.isIdentifier(expr)) { + ident = expr; + } + + return { ident, args }; + } + + private handleAwaitExpression(awaitExpr: ts.AwaitExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + const { ident, args } = this.getIdentifierForAwaitExpr(awaitExpr); + if (!ident) { + return; + } + + if (!this.tsUtils.isJsImport(ident)) { + return; + } + + const declaration = this.tsUtils.getDeclarationNode(ident); + if (!declaration) { + return; + } + + if ( + ts.isFunctionDeclaration(declaration) && + TsUtils.hasModifier(declaration.modifiers, ts.SyntaxKind.AsyncKeyword) + ) { + const autofix = this.autofixer?.fixAwaitJsCallExpression(ident, args); + this.incrementCounters(awaitExpr, FaultID.NoAwaitJsPromise, autofix); + return; + } + + if (ts.isMethodDeclaration(declaration) && TsUtils.hasModifier(declaration.modifiers, ts.SyntaxKind.AsyncKeyword)) { + const autofix = this.autofixer?.fixAwaitJsMethodCallExpression(ident, args); + this.incrementCounters(awaitExpr, FaultID.NoAwaitJsPromise, autofix); + return; + } + + if (!ts.isVariableDeclaration(declaration)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(declaration); + const typeString = this.tsTypeChecker.typeToString(type); + + if (typeString.split('<')[0] !== 'Promise') { + return; + } + + const autofix = this.autofixer?.fixAwaitJsPromise(ident); + this.incrementCounters(awaitExpr, FaultID.NoAwaitJsPromise, autofix); + } + + private handleNotsLikeSmartTypeOnCallExpression(tsCallExpr: ts.CallExpression, callSignature: ts.Signature): void { + if (!this.options.arkts2) { + return; + } + + if (ts.isIdentifier(tsCallExpr.expression)) { + const funcName = tsCallExpr.expression.text; + if (funcName === 'setTimeout') { + return; + } + } + + const isContinue = + ts.isCallExpression(tsCallExpr) && + ts.isIdentifier(tsCallExpr.expression) && + !ts.isReturnStatement(tsCallExpr.parent); + if (!isContinue || !tsCallExpr.arguments) { + return; + } + const declaration = callSignature.getDeclaration(); + if (!declaration || !ts.isFunctionDeclaration(declaration)) { + return; + } + const parameterTypes = declaration.parameters?.map((param) => { + const paramType = this.tsTypeChecker.getTypeAtLocation(param); + return this.tsTypeChecker.typeToString(paramType); + }); + tsCallExpr.arguments.forEach((arg, index) => { + if (index >= parameterTypes.length) { + return; + } + const expectedType = parameterTypes[index]; + let expectedUnionType: string[] = []; + if (expectedType.includes('|')) { + expectedUnionType = expectedType.split('|').map((item) => { + return item.trim(); + }); + } + this.checkParameterTypeCompatibility(arg, expectedUnionType, expectedType); + }); + } + + private checkParameterTypeCompatibility(arg: ts.Expression, expectedUnionType: string[], expectedType: string): void { + const actualSym = this.tsTypeChecker.getSymbolAtLocation(arg); + const decl = TsUtils.getDeclaration(actualSym); + if (decl && ts.isParameter(decl) && decl.type) { + const actualType = this.tsTypeChecker.getTypeFromTypeNode(decl.type); + const actualTypeName = this.tsTypeChecker.typeToString(actualType); + if (expectedUnionType.length > 0) { + if (!expectedUnionType.includes(actualTypeName)) { + this.incrementCounters(arg, FaultID.NoTsLikeSmartType); + } + return; + } + if (actualTypeName !== expectedType && expectedType !== 'any') { + this.incrementCounters(arg, FaultID.NoTsLikeSmartType); + } + } + } + + private handleNotsLikeSmartTypeOnAsExpression(tsAsExpr: ts.AsExpression): void { + if (!this.options.arkts2) { + return; + } + + if (TypeScriptLinter.isInForLoopBody(tsAsExpr)) { + const identifier = TypeScriptLinter.getIdentifierFromAsExpression(tsAsExpr); + if (identifier && this.isDeclaredOutsideForLoop(identifier)) { + return; + } + } + + const asType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.type); + const originType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression); + const originTypeStr = this.tsTypeChecker.typeToString(originType); + if (originTypeStr === 'never' && this.tsTypeChecker.typeToString(asType) !== originTypeStr) { + this.incrementCounters(tsAsExpr, FaultID.NoTsLikeSmartType); + } + } + + private isDeclaredOutsideForLoop(identifier: ts.Identifier): boolean { + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + if (!symbol) { + return false; + } + + const declarations = symbol.declarations ?? []; + for (const decl of declarations) { + if (ts.findAncestor(decl, ts.isForStatement)) { + return false; + } + } + + return true; + } + + private static getIdentifierFromAsExpression(asExpr: ts.AsExpression): ts.Identifier | undefined { + const expr = asExpr.expression; + if (ts.isIdentifier(expr)) { + // case: data as Type + return expr; + } else if (ts.isElementAccessExpression(expr) && ts.isIdentifier(expr.expression)) { + // case: data[i] as Type + return expr.expression; + } + return undefined; + } + + private handleAssignmentNotsLikeSmartType(tsBinaryExpr: ts.BinaryExpression): void { + if (!this.options.arkts2) { + return; + } + + if (this.isPriorityInThreadInfo(tsBinaryExpr)) { + this.incrementCounters(tsBinaryExpr, FaultID.NoTsLikeSmartType); + } + } + + private isPriorityInThreadInfo(node: ts.BinaryExpression): boolean { + if (!ts.isBinaryExpression(node)) { + return false; + } + + // Handle both regular assignment and 'as' type assertion + const right: ts.Expression = ts.isAsExpression(node.right) ? node.right.expression : node.right; + if (!ts.isPropertyAccessExpression(right)) { + return false; + } + + const propertyName = right.name; + if (!ts.isIdentifier(propertyName)) { + return false; + } + + const object = right.expression; + if (!ts.isIdentifier(object)) { + return false; + } + + const symbol = this.tsTypeChecker.getSymbolAtLocation(object); + if (!symbol) { + return false; + } + + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, object); + const typeString = this.tsTypeChecker.typeToString(type); + + for (const [typeName, properties] of Object.entries(ERROR_TASKPOOL_PROP_LIST)) { + if (typeString === typeName && properties.has(propertyName.text)) { + return true; + } + } + + return false; + } + + private handleUnsafeOptionalCallComparison(expr: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + const symbol = this.tsTypeChecker.getSymbolAtLocation(expr.expression); + if (!symbol) { + return; + } + const declaredType = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, expr.expression); + const usageType = this.tsTypeChecker.getTypeAtLocation(expr.expression); + + const declaration = this.tsUtils.getDeclarationNode(expr.expression); + if (!declaration) { + return; + } + + if ( + (ts.isParameter(declaration) || ts.isPropertyDeclaration(declaration) || ts.isVariableDeclaration(declaration)) && + TsUtils.isNullableUnionType(declaredType) && + TsUtils.isNullableUnionType(usageType) && + !ts.isPropertyAccessChain(expr) && + !this.isWriteAccess(expr.expression) + ) { + this.incrementCounters(expr, FaultID.NoTsLikeSmartType); + } + } + + private isWriteAccess(node: ts.Node): boolean { + const parent = node.parent; + if (!parent) { + return false; + } + + if (ts.isBinaryExpression(parent) && parent.left === node) { + return isAssignmentOperator(parent.operatorToken); + } + + if (ts.isVariableDeclaration(parent) && parent.name === node) { + return true; + } + + if (ts.isPropertyAccessExpression(parent) && parent.name === node) { + return this.isWriteAccess(parent); + } + + if (ts.isBindingElement(parent) && parent.name === node) { + return true; + } + + if (ts.isParameter(parent) && parent.name === node) { + return true; + } + + return false; + } + + private handleNotsLikeSmartType(classDecl: ts.ClassDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const className = classDecl.name?.getText(); + const { staticProps, instanceProps } = this.collectClassProperties(classDecl); + + classDecl.members.forEach((member) => { + if (!ts.isMethodDeclaration(member) || !member.body) { + return; + } + + const methodReturnType = this.tsTypeChecker.getTypeAtLocation(member); + this.checkMethodAndReturnStatements(member.body, className, methodReturnType, staticProps, instanceProps); + }); + } + + private checkMethodAndReturnStatements( + body: ts.Block, + className: string | undefined, + methodReturnType: ts.Type, + staticProps: Map, + instanceProps: Map + ): void { + const stopCondition = (node: ts.Node): boolean => { + return ( + ts.isFunctionDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isMethodDeclaration(node) || + ts.isAccessor(node) || + ts.isArrowFunction(node) + ); + }; + const callback = (node: ts.Node): void => { + if (!ts.isReturnStatement(node) || !node.expression) { + return; + } + const getPropertyAccess = (expr: ts.Expression): ts.PropertyAccessExpression | undefined => { + if (ts.isPropertyAccessExpression(expr)) { + return expr; + } + if (ts.isCallExpression(expr) && ts.isPropertyAccessExpression(expr.expression)) { + return expr.expression; + } + + return undefined; + }; + + const isStaticPropertyAccess = (expr: ts.PropertyAccessExpression, className: string): boolean => { + return ts.isIdentifier(expr.expression) && expr.expression.text === className; + }; + + const isInstancePropertyAccess = (node: ts.Expression): boolean => { + return ts.isPropertyAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword; + }; + + const propExp = getPropertyAccess(node.expression); + if (className && propExp && isStaticPropertyAccess(propExp, className)) { + this.checkPropertyAccess(node, propExp, staticProps, methodReturnType); + } + + if (isInstancePropertyAccess(node.expression)) { + this.checkPropertyAccess(node, node.expression as ts.PropertyAccessExpression, instanceProps, methodReturnType); + } + }; + forEachNodeInSubtree(body, callback, stopCondition); + } + + private checkPropertyAccess( + returnNode: ts.ReturnStatement, + propAccess: ts.PropertyAccessExpression, + propsMap: Map, + methodReturnType: ts.Type + ): void { + const propName = propAccess.name.getText(); + const propType = propsMap.get(propName); + + if (propType && this.isExactlySameType(propType, methodReturnType)) { + return; + } + + this.incrementCounters(returnNode, FaultID.NoTsLikeSmartType); + } + + private collectClassProperties(classDecl: ts.ClassDeclaration): { + staticProps: Map; + instanceProps: Map; + } { + const result = { + staticProps: new Map(), + instanceProps: new Map() + }; + + this.tsUtils.collectPropertiesFromClass(classDecl, result); + return result; + } + + private isExactlySameType(type1: ts.Type, type2: ts.Type): boolean { + if (type2.getCallSignatures().length > 0) { + const returnType = TsUtils.getFunctionReturnType(type2); + return returnType ? this.isExactlySameType(type1, returnType) : false; + } + + const type1String = this.tsTypeChecker.typeToString(type1); + const type2String = this.tsTypeChecker.typeToString(type2); + if (type1String === type2String) { + return true; + } + + if (this.checkBaseTypes(type1, type2) || this.checkBaseTypes(type2, type1)) { + return true; + } + return type1String === type2String; + } + + private checkBaseTypes(type1: ts.Type, type2: ts.Type): boolean { + const isClassType = + (type1.getFlags() & ts.TypeFlags.Object) !== 0 && + ((type1 as ts.ObjectType).objectFlags & ts.ObjectFlags.Class) !== 0; + if (isClassType) { + const baseTypes = (type1 as any).getBaseTypes?.() || []; + for (const baseType of baseTypes) { + if (this.isExactlySameType(baseType, type2)) { + return true; + } + } + } + return false; + } + + 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 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(); + + if ((/^0[box]/i).test(literalText)) { + this.incrementCounters(node, FaultID.NondecimalBigint); + } + } + + private handleStructDeclarationForLayout(node: ts.StructDeclaration): void { + if (!this.options.arkts2) { + return; + } + + if (!node.name) { + return; + } + + let hasTargetFunc = false; + + const members = node.members; + for (const member of members) { + if (!ts.isMethodDeclaration(member)) { + continue; + } + + if (customLayoutFunctionName.has(member.name.getText())) { + hasTargetFunc = true; + break; + } + } + + if (!hasTargetFunc) { + return; + } + + const decorators = ts.getDecorators(node); + if (decorators) { + for (const decorator of decorators) { + const decoratorName = TsUtils.getDecoratorName(decorator); + if (decoratorName && decoratorName === CustomInterfaceName.CustomLayout) { + return; + } + } + } + + const autofix = this.autofixer?.fixCustomLayout(node); + const name = node.name.getText(); + const errorMsg = + `The Custom component "${name}" with custom layout capability needs to add the "@CustomLayout" decorator ` + + '(arkui-custom-layout-need-add-decorator)'; + this.incrementCounters(node.name, FaultID.CustomLayoutNeedAddDecorator, autofix, errorMsg); + } + + private handleArkTSPropertyAccess(expr: ts.BinaryExpression): void { + if (!this.useStatic || !this.options.arkts2 || !TypeScriptLinter.isBinaryOperations(expr.operatorToken.kind)) { + return; + } + + const processExpression = (expr: ts.Expression): void => { + const symbol = this.tsUtils.trueSymbolAtLocation(expr); + if (this.isJsFileSymbol(symbol) || this.isJsFileExpression(expr)) { + const autofix = this.autofixer?.fixInteropOperators(expr); + this.incrementCounters(expr, FaultID.BinaryOperations, autofix); + } + }; + + processExpression(expr.left); + processExpression(expr.right); + } + + 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 handleNumericLiteral(node: ts.Node): void { + if (!this.options.arkts2 || !ts.isNumericLiteral(node)) { + return; + } + this.handleLargeNumericLiteral(node); + } + + private handleLargeNumericLiteral(node: ts.NumericLiteral): void { + const parent = node.parent; + const isPrefix = ts.isPrefixUnaryExpression(parent) && parent.operator === ts.SyntaxKind.MinusToken; + + if (TsUtils.isLargeNumericLiteral(node, isPrefix)) { + this.incrementCounters(node, FaultID.LargeNumericLiteral); + return; + } + + // Check for int overflow (existing logic) + const type = isPrefix ? this.tsTypeChecker.getContextualType(parent) : this.tsTypeChecker.getContextualType(node); + const isLarge = TsUtils.ifLargerThanInt(node, isPrefix); + if (!isLarge) { + return; + } + const isLong = this.tsUtils.isStdLongType(type); + if (isLong) { + return; + } + this.incrementCounters(node, FaultID.LongNumeric); + } + + private checkArrayUsageWithoutBound(accessExpr: ts.ElementAccessExpression): void { + if (this.shouldSkipArrayBoundCheck(accessExpr)) { + return; + } + + this.performArrayBoundValidation(accessExpr); + } + + private shouldSkipArrayBoundCheck(accessExpr: ts.ElementAccessExpression): boolean { + if (!this.options.arkts2 || !this.useStatic) { + return true; + } + if (this.isDirectLengthCheckWithNumber(accessExpr)) { + return true; + } + if ( + this.isInMaxLengthControlledLoop(accessExpr) || + TypeScriptLinter.hasDefaultValueProtection(accessExpr) || + this.isInLengthCheckedBlock(accessExpr) || + this.isInStandardLengthControlledLoop(accessExpr) + ) { + return true; + } + + if (ts.isConditionalExpression(accessExpr.parent)) { + const conditional = accessExpr.parent; + if (this.isLengthCheckCondition(conditional.condition, accessExpr)) { + return true; + } + } + + if (ts.isNumericLiteral(accessExpr.argumentExpression)) { + return false; + } + + if (this.isObjectPropertyAccess(accessExpr)) { + return true; + } + + return this.isInstanceOfCheck(accessExpr.parent, accessExpr); + } + + private performArrayBoundValidation(accessExpr: ts.ElementAccessExpression): void { + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + if (!arrayAccessInfo) { + const accessArgument = accessExpr.argumentExpression; + if (TypeScriptLinter.isFunctionCall(accessArgument)) { + this.incrementCounters(accessExpr, FaultID.RuntimeArrayCheck); + } + return; + } + const { arrayIdent } = arrayAccessInfo; + const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySym) { + return; + } + if (this.isInLoopWithArrayLengthModification(accessExpr, arrayIdent.text)) { + this.incrementCounters(accessExpr, FaultID.RuntimeArrayCheck); + return; + } + const arrayDecl = TypeScriptLinter.findArrayDeclaration(arraySym); + if (arrayDecl && TypeScriptLinter.isArrayCreatedWithOtherArrayLength(arrayDecl)) { + return; + } + const indexExpr = accessExpr.argumentExpression; + const loopVarName = ts.isIdentifier(indexExpr) ? indexExpr.text : undefined; + if (ts.isPrefixUnaryExpression(indexExpr) && indexExpr.operator === ts.SyntaxKind.PlusPlusToken) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + return; + } + const { isInSafeContext, isValidBoundCheck, isVarModifiedBeforeAccess } = this.analyzeSafeContext( + accessExpr, + loopVarName, + arraySym + ); + if (TypeScriptLinter.isIncrementOrDecrement(indexExpr)) { + return; + } + if (isInSafeContext) { + if (!isValidBoundCheck || isVarModifiedBeforeAccess) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + } + return; + } + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + } + + static isIncrementOrDecrement(expr: ts.Expression): boolean { + if (ts.isPostfixUnaryExpression(expr)) { + return expr.operator === ts.SyntaxKind.PlusPlusToken || expr.operator === ts.SyntaxKind.MinusMinusToken; + } + + if (ts.isPrefixUnaryExpression(expr)) { + return expr.operator === ts.SyntaxKind.PlusPlusToken || expr.operator === ts.SyntaxKind.MinusMinusToken; + } + + return false; + } + + private analyzeSafeContext( + accessExpr: ts.ElementAccessExpression, + loopVarName: string | undefined, + arraySym: ts.Symbol + ): { isInSafeContext: boolean; isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + const context = TypeScriptLinter.findSafeContext(accessExpr); + if (!context) { + return { isInSafeContext: false, isValidBoundCheck: false, isVarModifiedBeforeAccess: false }; + } + + return this.analyzeContextSafety(context, accessExpr, loopVarName, arraySym); + } + + static findSafeContext( + accessExpr: ts.ElementAccessExpression + ): { node: ts.ForStatement | ts.WhileStatement | ts.IfStatement } | void { + let currentNode: ts.Node | undefined = accessExpr; + + while (currentNode) { + if (ts.isForStatement(currentNode) || ts.isWhileStatement(currentNode) || ts.isIfStatement(currentNode)) { + return { node: currentNode }; + } + currentNode = currentNode.parent; + } + + return undefined; + } + + private analyzeContextSafety( + context: { node: ts.ForStatement | ts.WhileStatement | ts.IfStatement }, + accessExpr: ts.ElementAccessExpression, + loopVarName: string | undefined, + arraySym: ts.Symbol + ): { isInSafeContext: boolean; isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + const { node } = context; + + if (!loopVarName) { + return { + isInSafeContext: true, + isValidBoundCheck: false, + isVarModifiedBeforeAccess: false + }; + } + + const analysis = this.analyzeStatementType(node, accessExpr, loopVarName, arraySym); + + return { + isInSafeContext: true, + isValidBoundCheck: analysis.isValidBoundCheck, + isVarModifiedBeforeAccess: analysis.isVarModifiedBeforeAccess + }; + } + + private analyzeStatementType( + node: ts.ForStatement | ts.WhileStatement | ts.IfStatement, + accessExpr: ts.ElementAccessExpression, + loopVarName: string, + arraySym: ts.Symbol + ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + switch (node.kind) { + case ts.SyntaxKind.ForStatement: + return this.analyzeForStatement(node, accessExpr, loopVarName, arraySym); + case ts.SyntaxKind.WhileStatement: + return this.analyzeWhileStatement(node, accessExpr, loopVarName, arraySym); + case ts.SyntaxKind.IfStatement: + return this.analyzeIfStatement(node, accessExpr, loopVarName, arraySym); + default: + return { isValidBoundCheck: false, isVarModifiedBeforeAccess: false }; + } + } + + private analyzeForStatement( + forNode: ts.ForStatement, + accessExpr: ts.ElementAccessExpression, + loopVarName: string, + arraySym: ts.Symbol + ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + const isValidBoundCheck = forNode.condition ? + this.checkBoundCondition(forNode.condition, loopVarName, arraySym) : + false; + + const isVarModifiedBeforeAccess = forNode.statement ? + TypeScriptLinter.checkVarModifiedBeforeNode(forNode.statement, accessExpr, loopVarName) : + false; + + return { isValidBoundCheck, isVarModifiedBeforeAccess }; + } + + private analyzeWhileStatement( + whileNode: ts.WhileStatement, + accessExpr: ts.ElementAccessExpression, + loopVarName: string, + arraySym: ts.Symbol + ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + const isValidBoundCheck = whileNode.expression ? + this.checkBoundCondition(whileNode.expression, loopVarName, arraySym) : + false; + + const isVarModifiedBeforeAccess = whileNode.statement ? + TypeScriptLinter.checkVarModifiedBeforeNode(whileNode.statement, accessExpr, loopVarName) : + false; + + return { isValidBoundCheck, isVarModifiedBeforeAccess }; + } + + private analyzeIfStatement( + ifNode: ts.IfStatement, + accessExpr: ts.ElementAccessExpression, + loopVarName: string, + arraySym: ts.Symbol + ): { isValidBoundCheck: boolean; isVarModifiedBeforeAccess: boolean } { + const isValidBoundCheck = ifNode.expression ? + this.checkBoundCondition(ifNode.expression, loopVarName, arraySym) : + false; + + let isVarModifiedBeforeAccess = false; + const statementBlock = ts.isBlock(ifNode.thenStatement) ? ifNode.thenStatement : undefined; + if (statementBlock) { + isVarModifiedBeforeAccess = TypeScriptLinter.checkVarModifiedBeforeNode(statementBlock, accessExpr, loopVarName); + } + + return { isValidBoundCheck, isVarModifiedBeforeAccess }; + } + + private checkBoundCondition(condition: ts.Expression, varName: string, arraySym: ts.Symbol): boolean { + if (!ts.isBinaryExpression(condition)) { + return false; + } + return this.checkBinaryExpressionBound(condition, varName, arraySym); + } + + private checkBinaryExpressionBound(expr: ts.BinaryExpression, varName: string, arraySym: ts.Symbol): boolean { + if (this.checkDirectBoundChecks(expr, varName, arraySym)) { + return true; + } + + if (TypeScriptLinter.checkNumericBoundChecks(expr, varName)) { + return true; + } + + return ( + this.checkBoundCondition(expr.left, varName, arraySym) || this.checkBoundCondition(expr.right, varName, arraySym) + ); + } + + private checkDirectBoundChecks(expr: ts.BinaryExpression, varName: string, arraySym: ts.Symbol): boolean { + const { left, right, operatorToken } = expr; + + if (this.checkVarLessThanArrayLength(left, right, operatorToken, varName, arraySym)) { + return true; + } + + return this.checkArrayLengthGreaterThanVar(left, right, operatorToken, varName, arraySym); + } + + static checkNumericBoundChecks(expr: ts.BinaryExpression, varName: string): boolean { + const { left, right, operatorToken } = expr; + + if (ts.isIdentifier(left) && left.text === varName && ts.isNumericLiteral(right)) { + const value = parseFloat(right.text); + return ( + operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken && value <= 0 || + operatorToken.kind === ts.SyntaxKind.GreaterThanToken && value < 0 + ); + } + + if (ts.isPropertyAccessExpression(left) && left.name.text === LENGTH_IDENTIFIER && ts.isNumericLiteral(right)) { + const constantValue = parseInt(right.text); + return ( + operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0 || + operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0 + ); + } + + return false; + } + + private checkArrayLengthGreaterThanVar( + left: ts.Expression, + right: ts.Expression, + operatorToken: ts.Token, + varName: string, + arraySym: ts.Symbol + ): boolean { + if ( + ts.isPropertyAccessExpression(left) && + left.name.text === LENGTH_IDENTIFIER && + ts.isIdentifier(right) && + right.text === varName + ) { + const leftArraySym = this.tsUtils.trueSymbolAtLocation(left.expression); + if (leftArraySym === arraySym) { + return ( + operatorToken.kind === ts.SyntaxKind.GreaterThanToken || + operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken + ); + } + } + return false; + } + + private checkVarLessThanArrayLength( + left: ts.Expression, + right: ts.Expression, + operatorToken: ts.Token, + varName: string, + arraySym: ts.Symbol + ): boolean { + return ( + ts.isIdentifier(left) && + left.text === varName && + ts.isPropertyAccessExpression(right) && + right.name.text === LENGTH_IDENTIFIER && + (operatorToken.kind === ts.SyntaxKind.LessThanToken || + operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken) && + this.tsUtils.trueSymbolAtLocation(right.expression) === arraySym + ); + } + + private static traverseNodesUntilTarget( + node: ts.Node, + targetNode: ts.Node, + varName: string, + scopeStack: { shadowed: boolean; localVars: Set }[], + state: { targetFound: boolean; modified: boolean } + ): void { + if (node === targetNode) { + state.targetFound = true; + return; + } + + if (state.targetFound) { + return; + } + + const newScope = this.handleNewScope(node, scopeStack); + + TypeScriptLinter.getVariablesFromScope(node, varName, scopeStack); + + if (this.isVariableModified(node, varName, scopeStack)) { + state.modified = true; + } + + ts.forEachChild(node, (child) => { + this.traverseNodesUntilTarget(child, targetNode, varName, scopeStack, state); + }); + + if (newScope) { + scopeStack.pop(); + } + } + + private static handleNewScope( + node: ts.Node, + scopeStack: { shadowed: boolean; localVars: Set }[] + ): { shadowed: boolean; localVars: Set } | null { + if (ts.isBlock(node) || ts.isFunctionLike(node) || ts.isCatchClause(node)) { + const parentScope = scopeStack[scopeStack.length - 1]; + const newScope = { + shadowed: parentScope.shadowed, + localVars: new Set() + }; + scopeStack.push(newScope); + return newScope; + } + return null; + } + + static getVariablesFromScope( + node: ts.Node, + varName: string, + scopeStack: { shadowed: boolean; localVars: Set }[] + ): void { + if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === varName) { + const parent = node.parent; + if ( + ts.isVariableDeclarationList(parent) && + (parent.flags & ts.NodeFlags.Let || parent.flags & ts.NodeFlags.Const) + ) { + scopeStack[scopeStack.length - 1].localVars.add(varName); + } + } + + if (ts.isParameter(node) && ts.isIdentifier(node.name) && node.name.text === varName) { + scopeStack[scopeStack.length - 1].localVars.add(varName); + } + } + + private static isVariableModified( + node: ts.Node, + varName: string, + scopeStack: { shadowed: boolean; localVars: Set }[] + ): boolean { + if (!ts.isBinaryExpression(node) || node.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return false; + } + + if (!ts.isIdentifier(node.left) || node.left.text !== varName) { + return false; + } + + for (let i = scopeStack.length - 1; i >= 0; i--) { + if (scopeStack[i].localVars.has(varName)) { + return false; + } + } + + return true; + } + + static checkVarModifiedBeforeNode(container: ts.Node, targetNode: ts.Node, varName: string): boolean { + const scopeStack: { shadowed: boolean; localVars: Set }[] = []; + scopeStack.push({ shadowed: false, localVars: new Set() }); + + const state = { + targetFound: false, + modified: false + }; + + this.traverseNodesUntilTarget(container, targetNode, varName, scopeStack, state); + return state.modified; + } + + static isFunctionCall(node: ts.Node): boolean { + return ts.isCallExpression(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node); + } + + private isConcatArray(accessedNode: ts.Node): boolean { + if (!ts.isIdentifier(accessedNode)) { + return false; + } + const decl = this.tsUtils.getDeclarationNode(accessedNode); + if (!decl) { + return false; + } + + const type = this.tsTypeChecker.getTypeAtLocation(decl); + return TsUtils.isConcatArrayType(type); + } + + private getArrayAccessInfo(expr: ts.ElementAccessExpression): false | ArrayAccess { + let accessedExpression: ts.Node = expr.expression; + if (ts.isPropertyAccessExpression(accessedExpression)) { + accessedExpression = accessedExpression.name; + } + if (!ts.isIdentifier(accessedExpression)) { + return false; + } + + const baseType = this.tsTypeChecker.getTypeAtLocation(accessedExpression); + if (!this.tsUtils.isArray(baseType) && !this.isConcatArray(accessedExpression)) { + return false; + } + + const accessArgument = expr.argumentExpression; + if (this.isInstanceOfCheck(expr.parent, expr)) { + return false; + } + + if (TypeScriptLinter.isFunctionCall(accessArgument)) { + return false; + } + + if (this.checkNumericType(accessArgument) || this.isEnumMember(accessArgument)) { + return { + pos: expr.getEnd(), + accessingIdentifier: accessArgument, + arrayIdent: accessedExpression + }; + } + + return false; + } + + private checkNumericType(node: ts.Node): boolean { + const argType = this.tsTypeChecker.getTypeAtLocation(node); + return ( + (argType.flags & ts.TypeFlags.NumberLike) !== 0 || + argType.isUnionOrIntersection() && + argType.types.some((t) => { + return t.flags & ts.TypeFlags.NumberLike; + }) + ); + } + + private isEnumMember(node: ts.Node): boolean { + if (ts.isPropertyAccessExpression(node)) { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + return !!symbol && (symbol.flags & ts.SymbolFlags.EnumMember) !== 0; + } + return false; + } + + static isArrayCreatedWithOtherArrayLength(decl: ts.VariableDeclaration): boolean { + if (!decl.initializer || !ts.isNewExpression(decl.initializer)) { + return false; + } + + const newExpr = decl.initializer; + return ( + newExpr.arguments?.some((arg) => { + return ts.isPropertyAccessExpression(arg) && arg.name.text === LENGTH_IDENTIFIER; + }) ?? false + ); + } + + static findArrayDeclaration(sym: ts.Symbol): ts.VariableDeclaration | undefined { + const decls = sym.getDeclarations(); + if (!decls) { + return undefined; + } + + for (const decl of decls) { + if (ts.isVariableDeclaration(decl)) { + return decl; + } + } + return undefined; + } + + private isInstanceOfCheck(node: ts.Node, accessExpr: ts.ElementAccessExpression): boolean { + if (!ts.isBinaryExpression(node)) { + return false; + } + + if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) { + return this.isInstanceOfCheck(node.right, accessExpr); + } + + return ( + ts.isBinaryExpression(node) && + node.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && + node.left === accessExpr + ); + } + + private isLengthCheckCondition(condition: ts.Expression, accessExpr: ts.ElementAccessExpression): boolean { + if (!ts.isBinaryExpression(condition)) { + return false; + } + + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + if (!arrayAccessInfo) { + return false; + } + + const { arrayIdent } = arrayAccessInfo; + const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySym) { + return false; + } + + if ( + ts.isPropertyAccessExpression(condition.left) && + condition.left.name.text === LENGTH_IDENTIFIER && + this.tsUtils.trueSymbolAtLocation(condition.left.expression) === arraySym + ) { + return true; + } + + return false; + } + + private isInLengthCheckedBlock(accessExpr: ts.ElementAccessExpression): boolean { + let parent: ts.Node | undefined = accessExpr.parent; + + while (parent) { + if (ts.isBlock(parent) && ts.isIfStatement(parent.parent)) { + const ifStatement = parent.parent; + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + + if (arrayAccessInfo && this.isArrayLengthCheck(ifStatement.expression, arrayAccessInfo.arrayIdent)) { + return true; + } + } + + parent = parent.parent; + } + + return false; + } + + private isArrayLengthCheck(condition: ts.Expression, arrayIdent: ts.Identifier): boolean { + if (TypeScriptLinter.isAndExpression(condition)) { + const binaryExpr = condition as ts.BinaryExpression; + return ( + this.isArrayLengthCheck(binaryExpr.left, arrayIdent) || this.isArrayLengthCheck(binaryExpr.right, arrayIdent) + ); + } + + if (ts.isBinaryExpression(condition)) { + return TypeScriptLinter.checkBinaryLengthConditions(condition, arrayIdent); + } + + return false; + } + + static isAndExpression(condition: ts.Expression): boolean { + return ts.isBinaryExpression(condition) && condition.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken; + } + + static checkBinaryLengthConditions(condition: ts.BinaryExpression, arrayIdent: ts.Identifier): boolean { + if (TypeScriptLinter.checkSimpleArrayCheck(condition, arrayIdent)) { + return true; + } + + return TypeScriptLinter.checkArrayLengthComparisons(condition, arrayIdent); + } + + static checkSimpleArrayCheck(condition: ts.BinaryExpression, arrayIdent: ts.Identifier): boolean { + return ( + ts.isIdentifier(condition.left) && + condition.left.text === arrayIdent.text && + condition.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken + ); + } + + static checkArrayLengthComparisons(condition: ts.BinaryExpression, arrayIdent: ts.Identifier): boolean { + const { left, right, operatorToken } = condition; + + if ( + !ts.isPropertyAccessExpression(left) || + left.expression.getText() !== arrayIdent.text || + left.name.text !== LENGTH_IDENTIFIER || + !ts.isNumericLiteral(right) + ) { + return false; + } + + if (right.text === '0') { + return ( + operatorToken.kind === ts.SyntaxKind.GreaterThanToken || + operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken + ); + } + + const constantValue = parseInt(right.text); + return ( + operatorToken.kind === ts.SyntaxKind.LessThanToken && constantValue > 0 || + operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken && constantValue >= 0 + ); + } + + private isInMaxLengthControlledLoop(accessExpr: ts.ElementAccessExpression): boolean { + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + if (!arrayAccessInfo) { + return false; + } + + const accessedArrayName = arrayAccessInfo.arrayIdent.text; + return TypeScriptLinter.checkParentLoopForMaxLength(accessExpr, accessedArrayName); + } + + static checkParentLoopForMaxLength(node: ts.Node, arrayName: string): boolean { + let current: ts.Node | undefined = node; + + while (current) { + if (TypeScriptLinter.isValidForStatementWithMaxLength(current, arrayName)) { + return true; + } + current = current.parent; + } + + return false; + } + + static isValidForStatementWithMaxLength(node: ts.Node, arrayName: string): boolean { + if (!ts.isForStatement(node)) { + return false; + } + + const forStmt = node; + if (!forStmt.condition || !ts.isBinaryExpression(forStmt.condition)) { + return false; + } + + const condition = forStmt.condition; + const isValidOperator = + condition.operatorToken.kind === ts.SyntaxKind.LessThanToken || + condition.operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken; + + return isValidOperator && TypeScriptLinter.isMathMaxCallWithArrayLength(condition.right, arrayName); + } + + static isMathMaxCallWithArrayLength(expr: ts.Expression, arrayName: string): boolean { + if (!ts.isCallExpression(expr)) { + return false; + } + + if ( + !( + ts.isPropertyAccessExpression(expr.expression) && + expr.expression.name.text === 'max' && + ts.isIdentifier(expr.expression.expression) && + expr.expression.expression.text === 'Math' + ) + ) { + return false; + } + + return ( + expr.arguments?.some((arg) => { + return ( + ts.isPropertyAccessExpression(arg) && + arg.name.text === LENGTH_IDENTIFIER && + ts.isIdentifier(arg.expression) && + arg.expression.text === arrayName + ); + }) ?? false + ); + } + + static hasDefaultValueProtection(accessExpr: ts.ElementAccessExpression): boolean { + if ( + ts.isBinaryExpression(accessExpr.parent) && + accessExpr.parent.operatorToken.kind === ts.SyntaxKind.BarBarToken + ) { + const defaultValue = accessExpr.parent.right; + return ts.isNumericLiteral(defaultValue) || ts.isIdentifier(defaultValue) && defaultValue.text === 'undefined'; + } + return false; + } + + private isDirectLengthCheckWithNumber(accessExpr: ts.ElementAccessExpression): boolean { + if (!ts.isBlock(accessExpr.parent.parent) || !ts.isIfStatement(accessExpr.parent.parent.parent)) { + return false; + } + + const ifStatement = accessExpr.parent.parent.parent; + + if (!ts.isBinaryExpression(ifStatement.expression)) { + return false; + } + + const condition = ifStatement.expression; + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + if (!arrayAccessInfo) { + return false; + } + + if ( + !ts.isPropertyAccessExpression(condition.left) || + condition.left.name.text !== LENGTH_IDENTIFIER || + !ts.isIdentifier(condition.left.expression) || + condition.left.expression.text !== arrayAccessInfo.arrayIdent.text + ) { + return false; + } + + if (!ts.isNumericLiteral(condition.right)) { + return false; + } + + if (!ts.isNumericLiteral(accessExpr.argumentExpression)) { + return false; + } + + const conditionNumber = parseFloat(condition.right.text); + const accessNumber = parseFloat(accessExpr.argumentExpression.text); + + switch (condition.operatorToken.kind) { + case ts.SyntaxKind.GreaterThanToken: + return accessNumber <= conditionNumber; + case ts.SyntaxKind.GreaterThanEqualsToken: + return accessNumber < conditionNumber; + default: + return false; + } + } + + private isInLoopWithArrayLengthModification(accessExpr: ts.ElementAccessExpression, arrayName: string): boolean { + let current: ts.Node | undefined = accessExpr; + let inLoop = false; + + while (current) { + if (ts.isForStatement(current) || ts.isWhileStatement(current) || ts.isDoStatement(current)) { + inLoop = true; + break; + } + current = current.parent; + } + + if (!inLoop) { + return false; + } + + return this.checkArrayLengthModifiedBeforeAccess(accessExpr, arrayName); + } + + private checkArrayLengthModifiedBeforeAccess(accessExpr: ts.ElementAccessExpression, arrayName: string): boolean { + const container = TypeScriptLinter.findContainingBlock(accessExpr); + if (!container) { + return false; + } + + const state = { foundModification: false, foundAccess: false }; + this.checkForArrayModificationBeforeAccess(container, accessExpr, arrayName, state); + return state.foundModification; + } + + private checkForArrayModificationBeforeAccess( + node: ts.Node, + accessExpr: ts.ElementAccessExpression, + arrayName: string, + state: { foundModification: boolean; foundAccess: boolean } + ): void { + if (node === accessExpr) { + state.foundAccess = true; + return; + } + + if (state.foundAccess || state.foundModification) { + return; + } + + if (TypeScriptLinter.isArrayModification(node, arrayName)) { + state.foundModification = true; + return; + } + + ts.forEachChild(node, (child) => { + this.checkForArrayModificationBeforeAccess(child, accessExpr, arrayName, state); + }); + } + + static isArrayModification(node: ts.Node, arrayName: string): boolean { + return ( + TypeScriptLinter.isArrayModificationCall(node, arrayName) || TypeScriptLinter.isLengthAssignment(node, arrayName) + ); + } + + static isArrayModificationCall(node: ts.Node, arrayName: string): boolean { + if (!ts.isCallExpression(node)) { + return false; + } + const expr = node.expression; + return ( + ts.isPropertyAccessExpression(expr) && + ts.isIdentifier(expr.expression) && + expr.expression.text === arrayName && + ['pop', 'shift', 'splice'].includes(expr.name.text) + ); + } + + static isLengthAssignment(node: ts.Node, arrayName: string): boolean { + if (!ts.isBinaryExpression(node) || node.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return false; + } + return ( + ts.isPropertyAccessExpression(node.left) && + node.left.name.text === LENGTH_IDENTIFIER && + ts.isIdentifier(node.left.expression) && + node.left.expression.text === arrayName + ); + } + + static findContainingBlock(node: ts.Node): ts.Block | undefined { + let current: ts.Node | undefined = node; + while (current) { + if (ts.isBlock(current)) { + return current; + } + current = current.parent; + } + return undefined; + } + + private isObjectPropertyAccess(accessExpr: ts.ElementAccessExpression): boolean { + if (this.isObjectAccess(accessExpr)) { + return true; + } + + let current: ts.Node = accessExpr.expression; + while (current) { + if (ts.isElementAccessExpression(current)) { + if (this.isObjectAccess(current)) { + return true; + } + current = current.expression; + continue; + } + if (ts.isPropertyAccessExpression(current)) { + return true; + } + break; + } + + return false; + } + + private isObjectAccess(accessExpr: ts.ElementAccessExpression): boolean { + const baseType = this.tsTypeChecker.getTypeAtLocation(accessExpr.expression); + + const isObjectType = (baseType.flags & ts.TypeFlags.Object) !== 0; + if (!isObjectType) { + return false; + } + + const indexType = this.tsTypeChecker.getTypeAtLocation(accessExpr.argumentExpression); + const isStringIndex = + (indexType.flags & ts.TypeFlags.StringLike) !== 0 || (indexType.flags & ts.TypeFlags.StringLiteral) !== 0; + + if (isStringIndex) { + return true; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(accessExpr.expression); + if (!symbol) { + return false; + } + + const declarations = symbol.getDeclarations(); + if (!declarations) { + return false; + } + + for (const decl of declarations) { + if (!ts.isParameter(decl) && !ts.isVariableDeclaration(decl)) { + continue; + } + + const typeNode = decl.type; + if (!typeNode || !ts.isTypeReferenceNode(typeNode)) { + continue; + } + + if (ts.isIdentifier(typeNode.typeName) && typeNode.typeName.text === 'Record') { + return true; + } + } + + return false; + } + + private isInStandardLengthControlledLoop(accessExpr: ts.ElementAccessExpression): boolean { + const arrayAccessInfo = this.getArrayAccessInfo(accessExpr); + if (!arrayAccessInfo) { + return false; + } + let parent: ts.Node | undefined = accessExpr; + while (parent && !ts.isForStatement(parent)) { + parent = parent.parent; + } + if (!parent) { + return false; + } + + const forStmt = parent; + + if (!forStmt.condition || !ts.isBinaryExpression(forStmt.condition)) { + return false; + } + + const condition = forStmt.condition; + const isStandardLoop = + (condition.operatorToken.kind === ts.SyntaxKind.LessThanToken || + condition.operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken) && + ts.isPropertyAccessExpression(condition.right) && + condition.right.name.text === LENGTH_IDENTIFIER; + + if (!isStandardLoop) { + return false; + } + + return !this.hasDangerousArrayOperationsInForLoop(forStmt, arrayAccessInfo.arrayIdent.text); + } + + private hasDangerousArrayOperationsInForLoop(forStmt: ts.ForStatement, arrayName: string): boolean { + if (this.checkArrayModifications(forStmt.statement, arrayName)) { + return true; + } + + if (forStmt.initializer && ts.isVariableDeclarationList(forStmt.initializer)) { + const indexVar = forStmt.initializer.declarations[0]?.name.getText(); + if (indexVar && this.checkIndexModifications(forStmt.statement, indexVar)) { + return true; + } + } + + if (this.checkOutOfBoundAccess(forStmt.statement, arrayName)) { + return true; + } + + return false; + } + + private checkArrayModifications(node: ts.Node, arrayName: string): boolean { + let hasModification = false; + ts.forEachChild(node, (child) => { + if (TypeScriptLinter.isArrayModification(child, arrayName)) { + hasModification = true; + } + if (!hasModification) { + hasModification = this.checkArrayModifications(child, arrayName); + } + }); + return hasModification; + } + + private checkIndexModifications(node: ts.Node, indexVar: string): boolean { + let hasModification = false; + ts.forEachChild(node, (child) => { + if ( + ts.isBinaryExpression(child) && + child.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isIdentifier(child.left) && + child.left.text === indexVar + ) { + hasModification = true; + } + if (!hasModification) { + hasModification = this.checkIndexModifications(child, indexVar); + } + }); + return hasModification; + } + + private checkOutOfBoundAccess(node: ts.Node, arrayName: string): boolean { + let hasOutOfBound = false; + ts.forEachChild(node, (child) => { + if ( + ts.isElementAccessExpression(child) && + ts.isIdentifier(child.expression) && + child.expression.text === arrayName && + ts.isNumericLiteral(child.argumentExpression) + ) { + hasOutOfBound = true; + } + if (!hasOutOfBound) { + hasOutOfBound = this.checkOutOfBoundAccess(child, arrayName); + } + }); + return hasOutOfBound; + } + + private handleCallExpressionForRepeat(node: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + + if ( + !ts.isIdentifier(node.expression) || + node.expression.getText() !== CustomInterfaceName.Repeat || + this.isDeclarationInSameFile(node.expression) + ) { + return; + } + + const stmt = ts.findAncestor(node, ts.isExpressionStatement); + if (!stmt || TsUtils.checkStmtHasTargetIdentifier(stmt, VIRTUAL_SCROLL_IDENTIFIER)) { + return; + } + + const autofix = this.autofixer?.fixRepeat(stmt); + this.incrementCounters(node, FaultID.RepeatDisableVirtualScroll, autofix); + } + + private handleNodeForWrappedBuilder(node: ts.TypeReferenceNode | ts.NewExpression | ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + + const identifier = ts.isTypeReferenceNode(node) ? node.typeName : node.expression; + if (this.isDeclarationInSameFile(identifier)) { + return; + } + + switch (identifier.getText()) { + case CustomInterfaceName.WrappedBuilder: + this.incrementCounters(node, FaultID.WrappedBuilderGenericNeedArrowFunc); + break; + case CustomInterfaceName.wrapBuilder: { + const args = node.typeArguments; + if (args && args.length > 0 && ts.isTupleTypeNode(args[0])) { + this.incrementCounters(node, FaultID.WrapBuilderGenericNeedArrowFunc); + } + break; + } + default: + } + } + + private checkImportJsonFile(node: ts.ImportDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const moduleSpecifier = node.moduleSpecifier; + + if (!ts.isStringLiteral(moduleSpecifier)) { + return; + } + + const importPath = moduleSpecifier.text; + + if (importPath.endsWith(EXTNAME_JSON)) { + this.incrementCounters(moduleSpecifier, FaultID.NoImportJsonFile); + } + } + + private handleNoDeprecatedApi( + node: + | ts.TypeReferenceNode + | ts.NewExpression + | ts.VariableDeclaration + | ts.PropertyDeclaration + | ts.ParameterDeclaration + | ts.CallExpression + | ts.BinaryExpression + | ts.ExpressionWithTypeArguments + | ts.Identifier + | ts.MethodDeclaration + | ts.PropertyAssignment + | ts.PropertyAccessExpression + | ts.ElementAccessExpression + | ts.HeritageClause + | ts.TaggedTemplateExpression + ): void { + if (!this.options.arkts2) { + return; + } + switch (node.kind) { + case ts.SyntaxKind.TypeReference: + this.checkTypeReferenceForDeprecatedApi(node); + break; + case ts.SyntaxKind.HeritageClause: + this.checkHeritageClauseForDeprecatedApi(node); + break; + case ts.SyntaxKind.PropertyDeclaration: + this.checkPropertyDeclarationForDeprecatedApi(node); + break; + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.VariableDeclaration: + this.checkDeclarationForDeprecatedApi(node); + break; + case ts.SyntaxKind.MethodDeclaration: + this.checkMethodDeclarationForDeprecatedApi(node); + break; + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.BinaryExpression: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + this.handleNoDeprecatedApiForExpression(node); + break; + default: + } + } + + handleNoDeprecatedApiForExpression( + node: + | ts.NewExpression + | ts.CallExpression + | ts.BinaryExpression + | ts.PropertyAccessExpression + | ts.ElementAccessExpression + | ts.TaggedTemplateExpression + | ts.PropertyAssignment + ): void { + switch (node.kind) { + case ts.SyntaxKind.NewExpression: + this.checkNewExpressionForDeprecatedApi(node); + break; + case ts.SyntaxKind.CallExpression: + this.checkCallExpressionForDeprecatedApi(node); + break; + case ts.SyntaxKind.BinaryExpression: + this.checkBinaryExpressionForDeprecatedApi(node); + break; + case ts.SyntaxKind.PropertyAccessExpression: + this.checkPropertyAccessExpressionForDeprecatedApi(node); + break; + case ts.SyntaxKind.ElementAccessExpression: + this.checkSdkCommonOnElementAccess(node); + break; + case ts.SyntaxKind.TaggedTemplateExpression: + this.checkTaggedTemplateExpressionForBuiltinApi(node); + break; + case ts.SyntaxKind.PropertyAssignment: + this.checkPropertyAssignmentForDeprecatedApi(node); + break; + default: + } + } + + private checkSdkCommonOnElementAccess(elemAccessExp: ts.ElementAccessExpression): void { + const indexAccess = elemAccessExp.argumentExpression; + if (!indexAccess || !ts.isNumericLiteral(indexAccess)) { + return; + } + let express = elemAccessExp.expression; + const isNewExpression = ts.isNewExpression(elemAccessExp.expression); + if (isNewExpression) { + express = elemAccessExp.expression.expression; + } + const exprSym = this.tsUtils.trueSymbolAtLocation(express); + const exprDecl = TsUtils.getDeclaration(exprSym); + if (!exprDecl) { + return; + } + if (exprSym && isNewExpression) { + this.reportForSdkCommonOnElementAccess( + elemAccessExp, + exprSym.name, + path.basename(exprDecl.getSourceFile().fileName) + ); + return; + } + if (!ts.isVariableDeclaration(exprDecl)) { + return; + } + const initializer = exprDecl.initializer; + + if (!initializer || !ts.isNewExpression(initializer)) { + return; + } + const constructorIdentifier = initializer.expression; + if (!constructorIdentifier || !ts.isIdentifier(constructorIdentifier)) { + return; + } + const decl = this.tsUtils.getDeclarationNode(constructorIdentifier); + this.reportForSdkCommonOnElementAccess( + elemAccessExp, + constructorIdentifier.text, + path.basename(decl?.getSourceFile().fileName + '') + ); + } + + private reportForSdkCommonOnElementAccess(node: ts.Node, importName: string, filePath: string): void { + if (TypeScriptLinter.isImportedFromOhos(importName, filePath)) { + this.incrementCounters( + node, + FaultID.SdkCommonApiWhiteList, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(importName, FaultID.SdkCommonApiWhiteList) + ); + } + } + + private checkTypeReferenceForDeprecatedApi(node: ts.TypeReferenceNode): void { + let typeName = node.typeName; + if (ts.isQualifiedName(node.typeName)) { + typeName = node.typeName.right; + } + const sym = this.tsUtils.trueSymbolAtLocation(typeName); + const decl = TsUtils.getDeclaration(sym); + if (sym) { + this.hanldeSdkCommonTypeName(node, sym, sym.name, decl); + } + if (decl && (ts.isInterfaceDeclaration(decl) || ts.isClassDeclaration(decl) || ts.isTypeAliasDeclaration(decl))) { + let parentName = decl.name ? decl.name.text : 'unnamed'; + if (ts.isQualifiedName(node.typeName)) { + parentName = node.typeName.getText(); + } else if (ts.isTypeAliasDeclaration(decl)) { + parentName = ''; + } + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parentName, + undefined, + ts.isTypeAliasDeclaration(decl) ? decl.type.getText() : undefined, + path.basename(decl.getSourceFile().fileName + '') + ); + this.processApiNodeDeprecatedApi(typeName.getText(), typeName, deprecatedApiCheckMap); + this.processApiNodeDeprecatedApi(typeName.getText(), typeName, deprecatedApiCheckMap, undefined, BUILTIN_TYPE); + } + } + + private checkNewExpressionForDeprecatedApi(node: ts.NewExpression): void { + const expression = node.expression; + this.checkNewExpressionForSdkApi(node); + if (ts.isIdentifier(expression)) { + const decl = this.tsUtils.getDeclarationNode(expression); + if (decl && ts.isClassDeclaration(decl)) { + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + decl.name?.text + '', + undefined, + undefined, + path.basename(decl.getSourceFile().fileName + '') + ); + this.processApiNodeDeprecatedApi(expression.text, expression, deprecatedApiCheckMap); + } + } + } + + private checkNewExpressionForSdkApi(newExpr: ts.NewExpression): void { + const type = this.tsTypeChecker.getTypeAtLocation(newExpr.expression); + const resolvedSignature = this.tsTypeChecker.getResolvedSignature(newExpr); + if (!resolvedSignature) { + return; + } + const constructorDeclaration = resolvedSignature.declaration; + const parentName = type.symbol ? + this.tsTypeChecker.getFullyQualifiedName(type.symbol) : + newExpr.expression.getText(); + if (constructorDeclaration) { + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parentName, + constructorDeclaration.parameters as ts.NodeArray, + SDK_COMMON_VOID, + path.basename(constructorDeclaration.getSourceFile().fileName + '') + ); + this.processApiNodeDeprecatedApi( + SDK_COMMON_CONSTRUCTOR, + newExpr.expression, + deprecatedApiCheckMap, + undefined, + SDK_COMMON_TYPE + ); + if (BUILTIN_CALLSIGNATURE_NEWCTOR.includes(newExpr.expression.getText())) { + this.handleNewExpressionForBuiltNewCtor(newExpr.expression, deprecatedApiCheckMap); + } else { + this.processApiNodeDeprecatedApi( + BUILTIN_CONSTRUCTOR_API_NAME, + newExpr.expression, + deprecatedApiCheckMap, + undefined, + BUILTIN_TYPE + ); + } + } + } + + private handleNewExpressionForBuiltNewCtor( + errorNode: ts.Node, + deprecatedApiCheckMap?: Map> + ): void { + if (TypeScriptLinter.builtinNewCtorSet.size === 0 || !deprecatedApiCheckMap) { + return; + } + [...TypeScriptLinter.builtinNewCtorSet].some((item) => { + if (item.api_info.parent_api?.length <= 0) { + return false; + } + const isBuiltinNewConstruct = + BUILTIN_CONSTRUCTOR_API_TYPE.includes(item.api_info.api_type) && + item.api_info.parent_api[0].api_name === deprecatedApiCheckMap?.get(DEPRECATE_CHECK_KEY.PARENT_NAME) + '' && + path.basename(item.file_path) === deprecatedApiCheckMap?.get(DEPRECATE_CHECK_KEY.FILE_NAME) + ''; + if (isBuiltinNewConstruct) { + const problemStr = item.api_info.problem; + if (problemStr.length > 0) { + this.incrementCounters(errorNode, FaultID.BuiltinNewCtor); + } + return true; + } + return false; + }); + } + + private checkHeritageClauseForDeprecatedApi(node: ts.HeritageClause): void { + node.types.forEach((type) => { + let expr = type.expression; + if (ts.isIdentifier(expr)) { + this.checkHeritageClauseForDeprecatedApiOnIdentifier(expr); + } + if (ts.isPropertyAccessExpression(type.expression) && ts.isIdentifier(type.expression.name)) { + expr = type.expression.name; + } + const decl = this.tsUtils.getDeclarationNode(expr); + this.checkHeritageClauseForSdkApiDeprecated(node, decl, SDK_COMMON_TYPE); + this.checkHeritageClauseForSdkApiDeprecated(node, decl, BUILTIN_TYPE); + }); + } + + private checkHeritageClauseForSdkApiDeprecated( + node: ts.HeritageClause, + decl: ts.Node | undefined, + apiType: string + ): void { + if ( + decl && + (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl)) && + ts.isClassDeclaration(node.parent) && + decl.name + ) { + const extendClassName = decl.name.text; + const newSet = TypeScriptLinter.refactorSetWhitSameAsParenName(extendClassName, apiType); + if (newSet && newSet.size > 0) { + const sourceFunlikeArrs = node.parent.members.filter(ts.isFunctionLike); + const sourceProDeclArrs = node.parent.members.filter(ts.isPropertyDeclaration); + this.checkSdkApiInfoWithClassMember(sourceFunlikeArrs, decl, SDK_COMMON_TYPEKEY[0], apiType, newSet); + this.checkSdkApiInfoWithClassMember(sourceProDeclArrs, decl, SDK_COMMON_TYPEKEY[1], apiType, newSet); + } + } + } + + private checkSdkApiInfoWithClassMember( + sourceMembers: ts.ClassElement[] | ts.PropertyDeclaration[], + decl: ts.ClassDeclaration | ts.InterfaceDeclaration, + typeKey: string, + apiType: string, + mergedSet: Set + ): void { + sourceMembers.some((func) => { + if (!func.name || !decl.name) { + return; + } + const funcName = func.name.getText(); + const extendClassName = decl.name.text; + const problemStr = TypeScriptLinter.getFaultIdSdkApiInfoWithClassMember(decl, funcName, typeKey, mergedSet); + if (problemStr) { + let faultID = TypeScriptLinter.getFinalSdkFaultIdByProblem(problemStr, apiType); + if (apiType === SDK_COMMON_TYPE) { + faultID = sdkCommonAllDeprecatedTypeName.has(extendClassName) ? FaultID.SdkCommonApiDeprecated : faultID; + } + if (!faultID) { + return; + } + this.incrementCounters( + func, + faultID, + undefined, + apiType === SDK_COMMON_TYPE ? + TypeScriptLinter.getErrorMsgForSdkCommonApi(extendClassName, faultID) : + undefined + ); + } + }); + } + + private checkHeritageClauseForDeprecatedApiOnIdentifier(node: ts.Identifier): void { + const sym = this.tsUtils.trueSymbolAtLocation(node); + const decl = this.tsUtils.getDeclarationNode(node); + if (decl && (ts.isInterfaceDeclaration(decl) || ts.isClassDeclaration(decl))) { + const fileName = path.basename(decl.getSourceFile().fileName + ''); + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + decl.name?.getText() + '', + undefined, + undefined, + fileName + ); + this.processApiNodeDeprecatedApi(node.getText(), node, deprecatedApiCheckMap); + this.hanldeSdkCommonTypeName(node, sym, decl.name?.getText() + '', decl); + this.hanldeBuiltinFinalClassOnHeritageClause(node, fileName); + } + } + + private hanldeBuiltinFinalClassOnHeritageClause(node: ts.Node, fileName: string): void { + let isMatch = false; + for (const item of TypeScriptLinter.builtinFinalClassSet) { + isMatch = item.api_info.api_name === node.getText() && path.basename(item.file_path) === fileName; + if (isMatch) { + this.incrementCounters(node, FaultID.BuiltinFinalClass); + break; + } + } + } + + private checkDeclarationForDeprecatedApi( + node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + const expression = node.initializer; + const getParaExcute = (expression: ts.Expression): void => { + if (expression && ts.isIdentifier(expression)) { + const funSymbol = this.tsUtils.trueSymbolAtLocation(expression); + const decl = TsUtils.getDeclaration(funSymbol); + const parName = this.tsUtils.getParentSymbolName(funSymbol); + if (decl && (ts.isFunctionLike(decl) || ts.isVariableDeclaration(decl))) { + const returnType = decl.type?.getText(); + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName + '', + undefined, + returnType, + path.basename(decl.getSourceFile().fileName) + ); + this.processApiNodeDeprecatedApi(expression.text, expression, deprecatedApiCheckMap); + } + } + }; + + if (expression && ts.isIdentifier(expression)) { + getParaExcute(expression); + } else if (expression && ts.isObjectLiteralExpression(expression)) { + const properties = expression.properties; + for (const prop of properties) { + const propExpression = ts.isPropertyAssignment(prop) && prop.initializer; + if (propExpression && ts.isIdentifier(propExpression)) { + getParaExcute(propExpression); + } + } + } + } + + private checkCallExpressionForDeprecatedApi(node: ts.CallExpression): void { + let name: ts.Identifier | undefined; + if (ts.isIdentifier(node.expression)) { + name = node.expression; + } else if (ts.isPropertyAccessExpression(node.expression)) { + name = ts.isIdentifier(node.expression.name) ? node.expression.name : undefined; + } + if (!name) { + return; + } + let funSymbol = this.tsUtils.trueSymbolAtLocation(name); + if (!funSymbol && ts.isPropertyAccessExpression(node.expression)) { + funSymbol = this.tsTypeChecker.getSymbolAtLocation(node.expression.expression); + } + const isNeedGetResolvedSignature = funSymbol?.declarations && funSymbol.declarations.length > 1; + const decl = TsUtils.getDeclaration(funSymbol); + const parName = this.tsUtils.getParentSymbolName(funSymbol); + this.handleCallExpressionBufferIndexOf(node, name, parName + '', funSymbol, decl); + const deprecatedApiCheckMap = TypeScriptLinter.getDeprecatedApiCheckMapForCallExpression(decl, parName); + this.reportDeprecatedApi(node, name, deprecatedApiCheckMap); + this.checkCallExpressionForSdkApi(node, name, parName, !!isNeedGetResolvedSignature, deprecatedApiCheckMap); + this.checkSpecialApiForDeprecatedApi(node, name, decl); + } + + private static getDeprecatedApiCheckMapForCallExpression( + decl: ts.Node | undefined, + parName: string | undefined + ): Map> | undefined { + if (decl && (ts.isFunctionLike(decl) || ts.isVariableDeclaration(decl))) { + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName + '', + ts.isFunctionLike(decl) ? decl.parameters : undefined, + decl.type?.getText() === undefined ? 'any' : decl.type?.getText() + '', + path.basename(decl.getSourceFile().fileName) + ); + return deprecatedApiCheckMap; + } + return undefined; + } + + private checkCallExpressionForSdkApi( + node: ts.CallExpression, + name: ts.Identifier, + parName: string | undefined, + isNeedGetResolvedSignature: boolean, + deprecatedApiCheckMap: Map> | undefined + ): void { + if (isNeedGetResolvedSignature) { + this.checkCallExpressionForSdkApiWithSignature(node, name, parName); + } else { + this.reportDeprecatedApi(node, name, deprecatedApiCheckMap, SDK_COMMON_TYPE); + this.reportDeprecatedApi(node, name, deprecatedApiCheckMap, BUILTIN_TYPE); + } + } + + private checkCallExpressionForSdkApiWithSignature( + node: ts.CallExpression, + name: ts.Identifier, + parName: string | undefined + ): void { + const signature = this.tsTypeChecker.getResolvedSignature(node); + if (!signature?.declaration) { + return; + } + const functionSymbol = this.getFunctionSymbol(signature.declaration); + const functionDeclaration = functionSymbol?.valueDeclaration; + let returnType = this.tsTypeChecker.typeToString(signature.getReturnType()); + let isSpecialTypeForBuiltIn = false; + if (!functionDeclaration) { + const signatureDecl = signature.getDeclaration(); + if (signatureDecl && ts.isFunctionLike(signatureDecl) && signatureDecl.type) { + returnType = signatureDecl.type.getText(); + if (!parName && BUILTIN_CALLSIGNATURE_NEWCTOR.includes(name.text)) { + const type = this.tsTypeChecker.getTypeAtLocation(name); + parName = this.tsTypeChecker.typeToString(type); + isSpecialTypeForBuiltIn = !!parName; + } + } + } + const fileName = signature.getDeclaration().getSourceFile().fileName; + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? '' : parName + '', + TypeScriptLinter.getParameterDeclarationsBySignature(signature), + returnType, + path.basename(fileName) + ); + this.reportDeprecatedApi(node, name, deprecatedApiCheckMap, SDK_COMMON_TYPE); + if (isSpecialTypeForBuiltIn) { + this.processApiNodeDeprecatedApi( + BUILTIN_CONSTRUCTOR_API_NAME, + name, + deprecatedApiCheckMap, + undefined, + BUILTIN_TYPE + ); + } else { + this.reportDeprecatedApi(node, name, deprecatedApiCheckMap, BUILTIN_TYPE); + } + } + + private reportDeprecatedApi( + node: ts.CallExpression, + name: ts.Identifier, + deprecatedApiCheckMap?: Map>, + apiType?: string + ): void { + const problemStr = this.getFaultIdWithMatchedDeprecatedApi(name.text, deprecatedApiCheckMap, apiType); + if (problemStr.length > 0) { + const autofix = this.autofixer?.fixDeprecatedApiForCallExpression(node); + if (autofix) { + this.interfacesNeedToImport.add('getUIContext'); + } + const isSdkCommon = apiType === SDK_COMMON_TYPE; + const faultID = TypeScriptLinter.getFinalSdkFaultIdByProblem(problemStr, apiType); + if (!faultID) { + return; + } + this.incrementCounters( + name, + faultID, + isSdkCommon || apiType === BUILTIN_TYPE ? undefined : autofix, + isSdkCommon || apiType === undefined ? + TypeScriptLinter.getErrorMsgForSdkCommonApi(name.text, faultID) : + undefined + ); + } + } + + private static getFinalSdkFaultIdByProblem(problem: string, apiType: string | undefined): number | undefined { + let sdkFaultId: number | undefined = FaultID.NoDeprecatedApi; + if (apiType === SDK_COMMON_TYPE) { + sdkFaultId = SdkCommonApiProblemInfos.get(problem); + return sdkFaultId ? sdkFaultId : FaultID.SdkCommonApiWhiteList; + } else if (apiType === BUILTIN_TYPE) { + sdkFaultId = BuiltinProblemInfos.get(problem); + return sdkFaultId ? sdkFaultId : undefined; + } + return sdkFaultId; + } + + private checkSpecialApiForDeprecatedApi( + node: ts.CallExpression, + name: ts.Identifier, + decl: ts.Declaration | undefined + ): void { + if (('mask' === name.getText() || 'clip' === name.getText()) && node.arguments.length === 1) { + const types = ['CircleAttribute', 'EllipseAttribute', ' PathAttribute', 'RectAttribute']; + const arg = node.arguments[0]; + const argType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(arg)); + if (types.includes(argType)) { + if (name.getText() === 'clip') { + const typeMapping = { + CircleAttribute: 'CircleShape', + EllipseAttribute: 'EllipseShape', + PathAttribute: 'PathShape', + RectAttribute: 'RectShape' + } as const; + + if (argType in typeMapping) { + this.interfacesNeedToImport.add(typeMapping[argType as keyof typeof typeMapping]); + } + + const autofix = this.autofixer?.fixSpecialDeprecatedApiForCallExpression(node, name); + this.incrementCounters(name, FaultID.NoDeprecatedApi, autofix); + return; + } + this.incrementCounters(name, FaultID.NoDeprecatedApi); + return; + } + } + if (decl?.parent && ts.isClassDeclaration(decl.parent) && 'onScroll' === name.getText()) { + let parentName = ''; + decl.parent.heritageClauses?.forEach((clause) => { + clause.types.forEach((type) => { + if (ts.isExpressionWithTypeArguments(type)) { + parentName = type.expression.getText(); + } + }); + }); + if (parentName === 'ScrollableCommonMethod') { + this.incrementCounters(name, FaultID.NoDeprecatedApi); + } + } + } + + private checkBinaryExpressionForDeprecatedApi(node: ts.BinaryExpression): void { + const expression = node.right; + if (ts.isIdentifier(expression)) { + this.processApiNodeDeprecatedApi(expression.text, expression); + } + } + + private checkMethodDeclarationForDeprecatedApi(node: ts.MethodDeclaration): void { + const expression = node.name; + if (!ts.isIdentifier(expression)) { + return; + } + if ( + (expression.getText() === 'onLayout' || expression.getText() === 'onMeasure') && + node.type?.getText() === 'void' && + node.parent && + ts.isStructDeclaration(node.parent) + ) { + const argsType = ['LayoutChild[]', 'ConstraintSizeOptions']; + const parameters = node.parameters; + if (parameters && parameters.length === 2) { + let paramMatch = true; + for (let i = 0; i < parameters.length; i++) { + if (this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(parameters[i])) !== argsType[i]) { + paramMatch = false; + break; + } + } + if (paramMatch) { + this.incrementCounters( + expression, + FaultID.NoDeprecatedApi, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(expression.getText(), FaultID.NoDeprecatedApi) + ); + return; + } + } + } + this.processApiNodeDeprecatedApi(expression.text, expression); + } + + private checkPropertyAssignmentForDeprecatedApi(node: ts.PropertyAssignment): void { + const expression = node.name; + const contextualType = this.tsTypeChecker.getContextualType(node.parent); + if (contextualType) { + this.processApiNodeDeprecatedApi( + expression.getText(), + expression, + this.getPropertyTypeForPropertyAssignment(node, contextualType) + ); + this.processApiNodeDeprecatedApi( + expression.getText(), + expression, + this.getPropertyTypeForPropertyAssignment(node, contextualType, true), + undefined, + SDK_COMMON_TYPE + ); + this.processApiNodeDeprecatedApi( + expression.getText(), + expression, + this.getPropertyTypeForPropertyAssignment(node, contextualType), + undefined, + BUILTIN_TYPE + ); + } + } + + private checkPropertyAccessExpressionForDeprecatedApi(node: ts.PropertyAccessExpression): void { + this.handleSymbolIteratorForSdkCommon(node); + node.forEachChild((expression) => { + if (!ts.isIdentifier(expression)) { + return; + } + const funSymbol = this.tsUtils.trueSymbolAtLocation(expression); + const decl = TsUtils.getDeclaration(funSymbol); + let parName = this.tsUtils.getParentSymbolName(funSymbol); + this.hanldeSdkCommonTypeName(expression, funSymbol, parName ? parName : expression.text, decl); + if (decl && TypeScriptLinter.checkIsAppropriateTypeWithNode(decl)) { + let returnType: string | undefined = this.tsTypeChecker.typeToString( + this.tsTypeChecker.getTypeAtLocation(decl) + ); + if (ts.isPropertySignature(decl) && decl.type) { + returnType = decl.type.getText(); + } else if (ts.isEnumMember(decl)) { + returnType = TypeScriptLinter.getReturnTypeForEnumMember(decl); + } else if (!parName && ts.isEnumDeclaration(decl)) { + parName = decl.name.text; + returnType = undefined; + } + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName + '', + undefined, + returnType, + path.basename(decl.getSourceFile().fileName) + ); + this.processApiNodeDeprecatedApi(expression.text, expression, deprecatedApiCheckMap); + this.processApiNodeDeprecatedApi( + expression.text, + expression, + deprecatedApiCheckMap, + undefined, + SDK_COMMON_TYPE + ); + this.processApiNodeDeprecatedApi(expression.text, expression, deprecatedApiCheckMap, undefined, BUILTIN_TYPE); + } + }); + } + + private static checkIsAppropriateTypeWithNode(decl: ts.Node): boolean { + return ( + ts.isPropertyDeclaration(decl) || + ts.isPropertySignature(decl) || + ts.isEnumMember(decl) || + ts.isEnumDeclaration(decl) + ); + } + + private hanldeSdkCommonTypeName( + node: ts.Node, + symbol: ts.Symbol | undefined, + parentName: string, + decl?: ts.Declaration | undefined + ): void { + const filePath = decl?.getSourceFile().fileName; + const newName = sdkCommonAllDeprecatedFullTypeName.has(symbol?.name + '') ? symbol?.name + '' : parentName; + const isParentNameMatch = sdkCommonAllDeprecatedFullTypeName.has(newName); + const newFilePath = path.basename(filePath + ''); + let isFilePathMatch = false; + for (const item of TypeScriptLinter.sdkCommonAllDeprecatedTypeNameSet) { + isFilePathMatch = path.basename(item.file_path) === newFilePath; + if (isFilePathMatch) { + break; + } + } + const isMatch = isParentNameMatch && isFilePathMatch; + if (isMatch || TypeScriptLinter.isJsonTransformer(decl)) { + this.incrementCounters( + node, + FaultID.SdkCommonApiDeprecated, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(newName, FaultID.SdkCommonApiDeprecated) + ); + } + } + + private handleCallExpressionBufferIndexOf( + callExpr: ts.CallExpression, + node: ts.Node, + parentName: string, + symbol?: ts.Symbol, + decl?: ts.Declaration + ): void { + if (!symbol || !decl) { return; } - const moduleSpecifier = importDecl.moduleSpecifier; - if (!ts.isStringLiteral(moduleSpecifier)) { - return; - } - if (moduleSpecifier.text !== ARKUI_PACKAGE_NAME && moduleSpecifier.text !== ARKUI_STATE_MANAGEMENT) { + const isIndexOfWithEmptyString = TypeScriptLinter.checkIsIndexOfWithEmptyString(callExpr); + if (!isIndexOfWithEmptyString) { + return; + } + const isNameMatch = symbol.name === SDK_COMMON_BUFFER_API.indexof && parentName === SDK_COMMON_BUFFER_API.full_api; + const isPathMatch = TypeScriptLinter.isImportedFromOhos( + SDK_COMMON_BUFFER_API.apiName, + path.basename(decl.getSourceFile().fileName) + ); + if (isNameMatch && isPathMatch) { + this.incrementCounters( + node, + FaultID.SdkCommonApiBehaviorChange, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(SDK_COMMON_BUFFER_API.indexof, FaultID.SdkCommonApiBehaviorChange) + ); + } + } + + private static checkIsIndexOfWithEmptyString(callExpr: ts.CallExpression): boolean { + const isIndexOfCall = + ts.isPropertyAccessExpression(callExpr.expression) && + SDK_COMMON_BUFFER_API.indexof === callExpr.expression.name.text; + const hasEmptyStringArgument = + callExpr.arguments.length === 1 && ts.isStringLiteral(callExpr.arguments[0]) && callExpr.arguments[0].text === ''; + + const hasNoArguments = callExpr.arguments.length === 0; + + return isIndexOfCall && (hasEmptyStringArgument || hasNoArguments); + } + + private static isJsonTransformer(decl: ts.Declaration | undefined): boolean { + if ( + decl && + ts.isTypeAliasDeclaration(decl) && + ts.isFunctionTypeNode(decl.type) && + decl.name.getText() === SDK_COMMON_TRANSFORMER + ) { + return decl.type.parameters.length > 0 && decl.type.parameters[0].name.getText() === 'this'; + } + return false; + } + + private handleSymbolIteratorForSdkCommon(decl: ts.PropertyAccessExpression): boolean { + if ( + this.checkPropertyAccessExpressionForSdkCommonSymbotIter( + decl, + SDK_COMMON_SYMBOL_ITERATOR, + TypeScriptLinter.sdkCommonSymbotIterSet + ) + ) { + this.incrementCounters( + decl, + FaultID.SdkCommonApiWhiteList, + undefined, + TypeScriptLinter.getErrorMsgForSdkCommonApi(SDK_COMMON_SYMBOL_ITERATOR, FaultID.SdkCommonApiWhiteList) + ); + return true; + } + return false; + } + + private checkPropertyAccessExpressionForSdkCommonSymbotIter( + node: ts.PropertyAccessExpression, + name: string, + set: Set + ): boolean { + if (set.size === 0 || node.getText() !== name) { + return false; + } + let isFileMatch = false; + if (node.parent && ts.isElementAccessExpression(node.parent)) { + let decl = this.tsUtils.getDeclarationNode(node.parent.expression); + if (decl && ts.isVariableDeclaration(decl) && decl.initializer && ts.isNewExpression(decl.initializer)) { + decl = this.tsUtils.getDeclarationNode(decl.initializer.expression); + } + if (ts.isNewExpression(node.parent.expression)) { + decl = this.tsUtils.getDeclarationNode(node.parent.expression.expression); + } + const fileName = path.basename(decl?.getSourceFile().fileName + ''); + for (const item of set) { + isFileMatch = path.basename(item.file_path) === fileName; + if (isFileMatch) { + break; + } + } + } + return isFileMatch; + } + + private checkTaggedTemplateExpressionForBuiltinApi(node: ts.TaggedTemplateExpression): void { + const expression = node.tag; + if (ts.isPropertyAccessExpression(expression)) { + const funSymbol = this.tsUtils.trueSymbolAtLocation(expression.name); + const decl = TsUtils.getDeclaration(funSymbol); + const parName = this.tsUtils.getParentSymbolName(funSymbol); + if (decl) { + const returnType: string | undefined = this.tsTypeChecker.typeToString( + this.tsTypeChecker.getTypeAtLocation(decl) + ); + const deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + parName === undefined ? DEPRECATE_UNNAMED : parName + '', + undefined, + expression.name.text === 'raw' ? 'string' : returnType, + path.basename(decl.getSourceFile().fileName) + ); + this.processApiNodeDeprecatedApi( + expression.name.text, + expression.name, + deprecatedApiCheckMap, + undefined, + BUILTIN_TYPE + ); + } + } + } + + private checkPropertyDeclarationForDeprecatedApi(node: ts.PropertyDeclaration): void { + const expression = node.name; + if (ts.isIdentifier(expression)) { + this.processApiNodeDeprecatedApi(expression.text, expression); + } + } + + private processApiNodeDeprecatedApi( + apiName: string, + errorNode: ts.Node, + deprecatedApiCheckMap?: Map>, + autofix?: Autofix[], + apiType?: string + ): void { + const problemStr = this.getFaultIdWithMatchedDeprecatedApi(apiName, deprecatedApiCheckMap, apiType); + if (problemStr.length > 0) { + const isSdkCommon = apiType === SDK_COMMON_TYPE; + const faultID = TypeScriptLinter.getFinalSdkFaultIdByProblem(problemStr, apiType); + if (!faultID) { + return; + } + this.incrementCounters( + errorNode, + faultID, + isSdkCommon || apiType === BUILTIN_TYPE ? undefined : autofix, + isSdkCommon || apiType === undefined ? TypeScriptLinter.getErrorMsgForSdkCommonApi(apiName, faultID) : undefined + ); + } + } + + private getFaultIdWithMatchedDeprecatedApi( + apiName: string, + deprecatedApiCheckMap?: Map>, + apiType?: string + ): string { + void this; + if (!apiType) { + apiType = DEPRECATE_TYPE; + } + const setApiListItem = apiType && TypeScriptLinter.getApiListItemSetFromAllWhiteList(apiType); + if (!setApiListItem || !deprecatedApiCheckMap) { + return ''; + } + const apiNamesArr = [...setApiListItem]; + const isSpecial = apiType === SDK_COMMON_TYPE || apiType === BUILTIN_TYPE; + let problem = ''; + apiNamesArr.some((apiInfoItem) => { + if (!apiInfoItem.api_info.api_name && !apiName || BUILTIN_CONSTRUCTOR_API_NAME === apiName) { + problem = TypeScriptLinter.getFaultIdWithMatchedBuiltinConstructApi( + apiInfoItem, + deprecatedApiCheckMap?.get(DEPRECATE_CHECK_KEY.PARENT_NAME) + '' + ); + if (problem) { + return true; + } + } + const isSameApi = this.checkIsSameApiWithSdkList(apiInfoItem, apiName, deprecatedApiCheckMap, apiType); + const fileName = deprecatedApiCheckMap?.get(DEPRECATE_CHECK_KEY.FILE_NAME) + ''; + const isSameFile = fileName.endsWith(path.basename(apiInfoItem.file_path)); + const res = isSameApi && isSameFile; + if (res) { + problem = isSpecial ? apiInfoItem.api_info.problem : DeprecateProblem.NoDeprecatedApi; + } + return res; + }); + return problem; + } + + private checkIsSameApiWithSdkList( + apiInfoItem: ApiListItem, + apiName: string, + deprecatedApiCheckMap: Map>, + apiType?: string + ): boolean { + let isSameApi = apiInfoItem.api_info.api_name === apiName; + isSameApi &&= TypeScriptLinter.checkParentNameUnderSdkList( + apiInfoItem, + deprecatedApiCheckMap.get(DEPRECATE_CHECK_KEY.PARENT_NAME) + '', + apiType === SDK_COMMON_TYPE || apiType === BUILTIN_TYPE + ); + const return_type = this.getReturnTypeByApiInfoItem( + apiInfoItem, + apiType === SDK_COMMON_TYPE || apiType === BUILTIN_TYPE + ); + const actual_return_type = this.normalizeTypeString(deprecatedApiCheckMap.get(DEPRECATE_CHECK_KEY.RETURN_TYPE)); + isSameApi &&= return_type === actual_return_type; + const api_func_args = apiInfoItem.api_info.api_func_args; + const params = deprecatedApiCheckMap.get(DEPRECATE_CHECK_KEY.PARAM_SET); + if (api_func_args && params) { + const isParametersEqual = TypeScriptLinter.areParametersEqualForDeprecated( + api_func_args, + params as ts.NodeArray + ); + isSameApi &&= isParametersEqual; + } + return isSameApi; + } + + private static getFaultIdWithMatchedBuiltinConstructApi(apiInfoItem: ApiListItem, parentName: string): string { + if (apiInfoItem.api_info.parent_api?.length <= 0) { + return ''; + } + const isBuiltinConstruct = + BUILTIN_CONSTRUCTOR_API_TYPE.includes(apiInfoItem.api_info.api_type) && + apiInfoItem.api_info.parent_api[0].api_name === parentName; + return isBuiltinConstruct ? apiInfoItem.api_info.problem : ''; + } + + private getReturnTypeByApiInfoItem( + apiInfoItem: ApiListItem, + isSpecial: boolean | undefined + ): string | ts.NodeArray | undefined { + let return_type = this.normalizeTypeString(apiInfoItem.api_info.method_return_type); + if (isSpecial) { + return_type = apiInfoItem.api_info.method_return_type ? + this.normalizeTypeString(apiInfoItem.api_info.method_return_type) : + this.normalizeTypeString(apiInfoItem.api_info.api_property_type); + } + return return_type; + } + + private static checkParentNameUnderSdkList( + apiInfoItem: ApiListItem, + sourceParentName: string, + isSpecial?: boolean + ): boolean { + const parentApis = apiInfoItem.api_info.parent_api; + const possibleNames: string[] = []; + const primaryParentName = parentApis[0]?.api_name || ''; + + if (primaryParentName) { + possibleNames.push(primaryParentName); + if (!!isSpecial && parentApis.length > 1) { + const secondaryParentName = parentApis[1]?.api_name || ''; + possibleNames.push(`${secondaryParentName}.${primaryParentName}`); + } + } + return possibleNames.includes(sourceParentName) || parentApis.length === 0 && !sourceParentName; + } + + private getPropertyTypeForPropertyAssignment( + propertyAssignment: ts.PropertyAssignment, + contextualType: ts.Type, + isSpecial?: boolean + ): Map> | undefined { + const propertyName = propertyAssignment.name.getText(); + if (contextualType.isUnion()) { + for (const type of contextualType.types) { + const deprecatedApiCheckMap = this.getPropertyInfoByContextualType( + type, + propertyName, + propertyAssignment, + isSpecial + ); + if (deprecatedApiCheckMap) { + return deprecatedApiCheckMap; + } + } + } + return this.getPropertyInfoByContextualType(contextualType, propertyName, propertyAssignment, isSpecial); + } + + private getPropertyInfoByContextualType( + type: ts.Type, + propertyName: string, + node: ts.Node, + isSpecial?: boolean + ): Map> | undefined { + const propertySymbol = type.getProperty(propertyName); + if (!propertySymbol) { + return undefined; + } + const propertyDecl = TsUtils.getDeclaration(propertySymbol); + let deprecatedApiCheckMap = new Map>(); + if (propertyDecl && ts.isPropertySignature(propertyDecl) && propertyDecl.type) { + deprecatedApiCheckMap = TypeScriptLinter.updateDeprecatedApiCheckMap( + type.getSymbol()?.name + '', + undefined, + propertyDecl.type.getText(), + path.basename(propertyDecl.getSourceFile().fileName + '') + ); + if (isSpecial) { + this.hanldeSdkCommonTypeName(node, type.getSymbol(), type.getSymbol()?.name + '', propertyDecl); + } + } + return deprecatedApiCheckMap; + } + + private static updateDeprecatedApiCheckMap( + parentName: string, + parames: ts.NodeArray | undefined, + returnType: string | undefined, + fileName: string + ): Map> { + const deprecatedApiCheckMap = new Map>(); + deprecatedApiCheckMap.set(DEPRECATE_CHECK_KEY.PARENT_NAME, parentName); + if (parames) { + deprecatedApiCheckMap.set(DEPRECATE_CHECK_KEY.PARAM_SET, parames); + } + if (returnType) { + deprecatedApiCheckMap.set(DEPRECATE_CHECK_KEY.RETURN_TYPE, returnType); + } + deprecatedApiCheckMap.set(DEPRECATE_CHECK_KEY.FILE_NAME, fileName); + return deprecatedApiCheckMap; + } + + private static getReturnTypeForEnumMember(node: ts.EnumMember): string { + const enumDecl = node.parent; + if (!enumDecl?.members || enumDecl.members.length === 0) { + return ''; + } + for (let i = 0; i < enumDecl.members.length; i++) { + if (enumDecl.members[i].name.getText() === node.name.getText()) { + return i + ''; + } + } + return ''; + } + + private normalizeTypeString( + typeStr: string | ts.NodeArray | undefined + ): string | ts.NodeArray | undefined { + void this; + if (typeof typeStr === 'string') { + return typeStr.replace(/\s+/g, ''); + } + return typeStr; + } + + private static areParametersEqualForDeprecated( + sdkFuncArgs: { name: string; type: string }[], + memberParams: ts.NodeArray + ): boolean { + const apiParamCout = sdkFuncArgs.length; + const memberParamCout = memberParams.length; + if (apiParamCout > memberParamCout && sdkFuncArgs[memberParamCout]) { + return false; + } + for (let i = 0; i < apiParamCout; i++) { + const typeName = memberParams[i]?.type?.getText(); + const newtypeName = typeName?.replace(/\s+/g, ''); + const sdkArgName = sdkFuncArgs[i].type.replace(/\s+/g, ''); + if (newtypeName !== sdkArgName) { + return false; + } + } + return true; + } + + private handleESObjectUsage(typeRef: ts.TypeReferenceNode): void { + if (!this.options.arkts2) { return; } - this.incrementCounters(node, FaultID.MakeObservedIsNotSupported); + if ( + ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === ES_OBJECT || + ts.isQualifiedName(typeRef.typeName) && typeRef.typeName.right.text === ES_OBJECT + ) { + this.incrementCounters(typeRef, FaultID.NoESObjectSupport); + } } - private handlePropertyDeclarationForProp(node: ts.PropertyDeclaration): void { + private handleNodeForBuilderNode(node: ts.TypeReferenceNode | ts.NewExpression): void { if (!this.options.arkts2) { return; } - const decorators = ts.getDecorators(node); - if (!decorators || decorators.length === 0) { + const identifier = ts.isTypeReferenceNode(node) ? node.typeName : node.expression; + if ( + identifier.getText() !== CustomInterfaceName.BuilderNode || + !this.isDeclInTargetFile(identifier, BUILDERNODE_D_TS) + ) { return; } - 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 firstArg = node.typeArguments?.[0]; + if (firstArg && ts.isTupleTypeNode(firstArg)) { + this.incrementCounters(node, FaultID.BuilderNodeGenericNoTuple); } + } - if (!decoratorName || !deepCopyDecoratorName.has(decoratorName)) { - return; + private isDeclInTargetFile(node: ts.Node, targetFile: string): boolean { + const decl = this.tsUtils.getDeclarationNode(node); + const file = decl?.getSourceFile(); + if (file !== undefined) { + const fileName = path.basename(file.fileName); + if (fileName !== targetFile) { + return false; + } } - this.incrementCounters(node, FaultID.PropDecoratorsAndInterfacesAreNotSupported); + return true; } - private handleVariableDeclarationForProp(node: ts.VariableDeclaration): void { + private handlePropertyAccessExprForBuilderNode(node: ts.PropertyAccessExpression): void { if (!this.options.arkts2) { return; } - const callExpr = node.initializer; - if (!callExpr || !ts.isCallExpression(callExpr)) { - return; - } - - const propertyAccessExpr = callExpr.expression; - if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { + const identifier = node.name; + if (!ts.isIdentifier(identifier) || !this.isDeclInTargetFile(identifier, BUILDERNODE_D_TS)) { return; } - const storage = propertyAccessExpr.expression; - if ( - !ts.isIdentifier(storage) || - !this.isTargetStorageType(storage, [StorageTypeName.LocalStorage, StorageTypeName.AppStorage]) - ) { + const name = identifier.getText(); + const callExpr = ts.findAncestor(node, ts.isCallExpression); + if (!callExpr) { return; } - const functionName = propertyAccessExpr.name; - if (!deepCopyFunctionName.has(functionName.getText())) { - return; + switch (name) { + case BuilderNodeFunctionName.Update: + if (callExpr.arguments.length !== 0 && this.checkArgumentIsLiteral(callExpr.arguments[0])) { + this.incrementCounters(callExpr, FaultID.BuilderNodeUpdateNoLiteral); + } + break; + case BuilderNodeFunctionName.Build: { + const hasTargetParam = callExpr.arguments.filter(ts.isObjectLiteralExpression).some((literal) => { + return literal.properties.some((prop) => { + return prop.name?.getText() === NESTING_BUILDER_SUPPORTED; + }); + }); + if (hasTargetParam) { + this.incrementCounters(callExpr, FaultID.BuilderNodeNoNestingBuilderSupported); + } + break; + } + default: } - - this.incrementCounters(node, FaultID.PropDecoratorsAndInterfacesAreNotSupported); } - private isTargetStorageType(storage: ts.Identifier, targetTypes: string[]): boolean { - const decl = this.tsUtils.getDeclarationNode(storage); - if (!decl) { - if (targetTypes.includes(storage.getText())) { + private checkArgumentIsLiteral(node: ts.Node): boolean { + switch (node.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: return true; - } - return false; + case ts.SyntaxKind.Identifier: + return this.checkIdentifierIsLiteral(node as ts.Identifier); + case ts.SyntaxKind.ConditionalExpression: + return this.checkConditionalExprIsLiteral(node as ts.ConditionalExpression); + case ts.SyntaxKind.CallExpression: + return this.checkCallExprIsLiteral(node as ts.CallExpression); + default: + return false; } + } - if (!ts.isVariableDeclaration(decl)) { + private checkIdentifierIsLiteral(node: ts.Identifier): boolean { + const decl = this.tsUtils.getDeclarationNode(node); + const initalizer = decl && ts.isVariableDeclaration(decl) ? decl.initializer : undefined; + if (!initalizer) { return false; } + return this.checkArgumentIsLiteral(initalizer); + } - 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; - } + private checkConditionalExprIsLiteral(node: ts.ConditionalExpression): boolean { + return this.checkArgumentIsLiteral(node.whenTrue) || this.checkArgumentIsLiteral(node.whenFalse); + } + + private checkCallExprIsLiteral(node: ts.CallExpression): boolean { + const callExpr = node; + let identifier: ts.Identifier | undefined; + if (ts.isIdentifier(callExpr.expression)) { + identifier = callExpr.expression; + } else if (ts.isPropertyAccessExpression(callExpr.expression) && ts.isIdentifier(callExpr.expression.name)) { + identifier = callExpr.expression.name; } - if (!storageType || !ts.isIdentifier(storageType)) { + if (!identifier) { return false; } - - return targetTypes.includes(storageType.getText()); - } - - private handleAwaitExpression(node: ts.Node): void { - if (!this.options.arkts2 || !this.useStatic) { - return + const funcDecl = this.tsUtils.getDeclarationNode(identifier); + const body = + funcDecl && (ts.isFunctionDeclaration(funcDecl) || ts.isMethodDeclaration(funcDecl)) ? funcDecl.body : undefined; + if (!body) { + return false; } - 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; + for (const stmt of body.statements) { + if (ts.isReturnStatement(stmt) && stmt.expression) { + return this.checkArgumentIsLiteral(stmt.expression); } - return false; - }; - const expr = awaitExpr.expression; - checkAndReportJsImportAwait(expr); - if (ts.isCallExpression(expr)) { - checkAndReportJsImportAwait(expr.expression); } + return false; } - private handleNotsLikeSmartType(classDecl: ts.ClassDeclaration): void { + private handlePromiseTupleGeneric(node: ts.CallExpression): void { if (!this.options.arkts2) { return; } - const className = classDecl.name?.getText(); - classDecl.members.forEach(member => { - if (ts.isMethodDeclaration(member)) { - this.checkMethod(member, className); - } - }) - } - 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); - }); - } + if ( + ts.isPropertyAccessExpression(node.expression) && + ts.isIdentifier(node.expression.expression) && + node.expression.expression.text === PROMISE + ) { + const methodName = node.expression.name.text; - const isStaticPropertyAccess=(node: ts.Expression, className: string): boolean => { - return ts.isPropertyAccessExpression(node) && - ts.isIdentifier(node.expression) && - node.expression.text === className; - } + if (!PROMISE_METHODS_WITH_NO_TUPLE_SUPPORT.has(methodName)) { + return; + } - const isInstancePropertyAccess=(node: ts.Expression): boolean=> { - return ts.isPropertyAccessExpression(node) && - node.expression.kind === ts.SyntaxKind.ThisKeyword; - } + const typeArguments = node.typeArguments; + if (!typeArguments || typeArguments.length === 0) { + return; + } - this.checkReturnStatements(returnStatements, className, isStaticPropertyAccess, isInstancePropertyAccess); + const firstArg = typeArguments[0]; + if (ts.isTupleTypeNode(firstArg)) { + this.incrementCounters(firstArg, FaultID.NotSupportTupleGenericValidation); + } + } } - 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); - } + private static getParameterDeclarationsBySignature(signature: ts.Signature): ts.NodeArray { + const validParameters = signature.parameters. + map((paramSymbol) => { + const declarations = paramSymbol.getDeclarations(); + const paramDeclaration = declarations?.[0]; + return paramDeclaration && ts.isParameter(paramDeclaration) ? paramDeclaration : undefined; + }). + filter((param): param is ts.ParameterDeclaration => { + return param !== undefined; }); + return ts.factory.createNodeArray(validParameters); + } + + private static isImportedFromOhos(importName: string, filePath: string): boolean { + const classPaths = TypeScriptLinter.sdkCommonIndexClassSet.get(importName); + return ( + !!classPaths && + classPaths.some((p) => { + return path.basename(p) === filePath; + }) + ); + } + + private static mergeSdkCommonApiListInfo(): Set { + return new Set([ + ...TypeScriptLinter.sdkCommonApiInfo, + ...TypeScriptLinter.sdkCommonSymbotIterSet, + ...TypeScriptLinter.sdkCommonAllDeprecatedTypeNameSet + ]); + } + + private static getFaultIdSdkApiInfoWithConstructorDecl(extendClassName: string, apiType: string): string { + const mergedSet = TypeScriptLinter.getApiListItemSetFromAllWhiteList( + apiType, + apiType === SDK_COMMON_TYPE ? true : undefined + ); + if (!mergedSet) { + return ''; + } + let api_types = ['']; + if (apiType === SDK_COMMON_TYPE) { + api_types = SDK_COMMON_CONSTRUCTORLIKE; + } else if (apiType === BUILTIN_TYPE) { + api_types = BUILTIN_CONSTRUCTOR_API_TYPE; + } + let problem = ''; + for (const item of mergedSet) { + if (item.api_info.parent_api?.length <= 0) { + continue; + } + const isCompare = + item.api_info.parent_api[0].api_name === extendClassName && api_types.includes(item.api_info.api_type); + if (isCompare) { + problem = item.api_info.problem; + break; + } } + return problem; + } - if (ts.isReturnStatement(node)) { - returnStatements.push(node); + private static getFaultIdSdkApiInfoWithClassMember( + decl: ts.ClassDeclaration | ts.InterfaceDeclaration, + targetName: string, + typeKey: string, + mergedSet: Set + ): string { + const extendClassName = decl.name?.text; + const fileName = path.basename(decl.getSourceFile().fileName); + if (!extendClassName || !fileName) { + return ''; + } + const memberLike = typeKey === SDK_COMMON_TYPEKEY[0] ? SDK_COMMON_FUNCTIONLIKE : SDK_COMMON_PROPERTYLIKE; + let problem = ''; + const apiFilePath = this.getApiFilePathsFromSdkList(mergedSet); + for (const item of mergedSet) { + if (item.api_info.parent_api?.length <= 0) { + continue; + } + const isFunLikeCompare = + item.api_info.parent_api[0].api_name === extendClassName && + memberLike.includes(item.api_info.api_type) && + item.api_info.api_name === targetName && + apiFilePath.includes(fileName); + if (isFunLikeCompare) { + problem = item.api_info.problem; + break; + } } + return problem; + } - ts.forEachChild(node, (child) => { - this.visitMethodBody(child, variableDeclarations, returnStatements); + private static getApiFilePathsFromSdkList(mergedSet: Set): string[] { + const apiFilePath: string[] = []; + mergedSet.forEach((mem) => { + apiFilePath.push(path.basename(mem.file_path)); }); + return apiFilePath; } - 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; - } - - if (className && isStaticPropertyAccess(returnStmt.expression, className)) { - this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); - } - - if (isInstancePropertyAccess(returnStmt.expression)) { - this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); + private static refactorSetWhitSameAsParenName(targetName: string, apiType: string): Set | undefined { + const mergedSet = TypeScriptLinter.getApiListItemSetFromAllWhiteList( + apiType, + apiType === SDK_COMMON_TYPE ? true : undefined + ); + if (!mergedSet) { + return undefined; + } + const newMergedSet = new Set(); + for (const item of mergedSet) { + if (item.api_info.parent_api?.length <= 0) { + continue; } - }); + if (item.api_info.parent_api[0].api_name === targetName) { + newMergedSet.add(item); + } + } + return newMergedSet; } - - private handleNumericBigintCompare(node: ts.BinaryExpression): void { + + private static getApiListItemSetFromAllWhiteList( + type: string, + isMergeSdkCommonApi?: boolean + ): Set | undefined { + if (type === DEPRECATE_TYPE) { + return TypeScriptLinter.deprecatedApiInfo; + } else if (type === SDK_COMMON_TYPE) { + return isMergeSdkCommonApi ? TypeScriptLinter.mergeSdkCommonApiListInfo() : TypeScriptLinter.sdkCommonApiInfo; + } else if (type === BUILTIN_TYPE) { + return TypeScriptLinter.builtApiInfo; + } + return undefined; + } + + private checkArrayInitialization(tsNewExpr: ts.NewExpression): void { if (!this.options.arkts2) { return; } - switch(node.operatorToken.kind) { - case ts.SyntaxKind.LessThanEqualsToken: - case ts.SyntaxKind.EqualsEqualsToken: - case ts.SyntaxKind.GreaterThanEqualsToken: - case ts.SyntaxKind.ExclamationEqualsToken: - case ts.SyntaxKind.ExclamationEqualsEqualsToken: - case ts.SyntaxKind.EqualsEqualsEqualsToken: - case ts.SyntaxKind.GreaterThanToken: - case ts.SyntaxKind.LessThanToken: - this.reportNumericBigintCompare(node); - break; - default: + if (!tsNewExpr.arguments || tsNewExpr.arguments.length !== 1) { + return; + } + const newExprType = this.tsTypeChecker.getTypeAtLocation(tsNewExpr); + const argType = this.tsTypeChecker.getTypeAtLocation(tsNewExpr.arguments[0]); + if (this.tsUtils.isGenericArrayType(newExprType) && this.tsUtils.isNumberLikeType(argType)) { + this.incrementCounters(tsNewExpr, FaultID.UninitializedArrayElements); } } - private reportNumericBigintCompare(node: ts.BinaryExpression): void { - const leftType = this.tsTypeChecker.getTypeAtLocation(node.left); - const rightType = this.tsTypeChecker.getTypeAtLocation(node.right); + private handleBuiltinIteratorResult(propAccessExpr: ts.PropertyAccessExpression): void { + if (!this.options.arkts2 || !TypeScriptLinter.builtApiInfo || propAccessExpr.name.getText() !== 'value') { + return; + } - const isLeftNumber = (leftType.flags & ts.TypeFlags.Number) !== 0; - const isLeftBigInt = (leftType.flags & ts.TypeFlags.BigInt) !== 0; + const type = this.tsTypeChecker.getTypeAtLocation(propAccessExpr.expression); + const aliasSymbol = type.aliasSymbol; + const declaration = aliasSymbol?.declarations?.[0]; + if (!declaration || !ts.isTypeAliasDeclaration(declaration)) { + return; + } - const isRightNumber = (rightType.flags & ts.TypeFlags.Number) !== 0; - const isRightBigInt = (rightType.flags & ts.TypeFlags.BigInt) !== 0; + const name = declaration.name.getText(); + const typeStr = declaration.type.getText(); + const fileName = declaration.getSourceFile().fileName; + this.processApiNodeDeprecatedApi( + name, + propAccessExpr, + TypeScriptLinter.updateDeprecatedApiCheckMap('', undefined, typeStr, path.basename(fileName)), + undefined, + BUILTIN_TYPE + ); + } - const valid = (isLeftNumber && isRightBigInt) || (isLeftBigInt && isRightNumber); - if (valid) { - this.incrementCounters(node, FaultID.NumericBigintCompare); + private handleBuiltinDisableDecorator(decorator: ts.Decorator): void { + if (!this.options.arkts2 || !TypeScriptLinter.builtApiInfo) { + return; } + const type = this.tsTypeChecker.getTypeAtLocation(decorator.expression); + const aliasSymbol = type.aliasSymbol; + const declaration = aliasSymbol?.declarations?.[0]; + if (!declaration || !ts.isTypeAliasDeclaration(declaration) || !ts.isFunctionLike(declaration.type)) { + return; + } + const name = declaration.name.getText(); + const params = declaration.type.parameters; + const typeStr = declaration.type.type?.getText(); + const fileName = declaration.getSourceFile().fileName; + this.processApiNodeDeprecatedApi( + name, + decorator, + TypeScriptLinter.updateDeprecatedApiCheckMap('', params, typeStr, path.basename(fileName)), + undefined, + BUILTIN_TYPE + ); } - - private handleBigIntLiteral(node: ts.BigIntLiteral): void { + + private handleUnsignedShiftOnNegative(node: ts.BinaryExpression): void { if (!this.options.arkts2) { return; } - const literalText = node.getText(); - if ((/^0[box]/i).test(literalText)) { - this.incrementCounters(node, FaultID.NondecimalBigint); + if (!TypeScriptLinter.isUnsignedShiftByZero(node)) { + return; + } + + if (TsUtils.isNegativeNumericLiteral(node.left)) { + this.incrementCounters(node, FaultID.NumericUnsignedShiftBehaviorChange); + } + + if (ts.isIdentifier(node.left)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node.left); + const decl = symbol?.valueDeclaration; + if (!decl || !ts.isVariableDeclaration(decl)) { + return; + } + + const init = decl.initializer; + if (init && TsUtils.isNegativeNumericLiteral(init)) { + this.incrementCounters(node, FaultID.NumericUnsignedShiftBehaviorChange); + } } } - private handleStructDeclarationForLayout(node: ts.StructDeclaration): void { + private static isUnsignedShiftByZero(node: ts.BinaryExpression): boolean { + return ( + node.operatorToken.kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken && + ts.isNumericLiteral(node.right) && + node.right.text === '0' + ); + } + + private handleCallExpressionForSerialization(node: ts.CallExpression): void { if (!this.options.arkts2) { return; } - if (!node.name) { + const propertyAccess = node.expression; + if (!ts.isPropertyAccessExpression(propertyAccess)) { return; } - let hasTargetFunc = false; + const persistentClass = propertyAccess.expression; + if (!ts.isIdentifier(persistentClass)) { + return; + } - const members = node.members; - for (const member of members) { - if (!ts.isMethodDeclaration(member)) { + switch (persistentClass.getText()) { + case StorageTypeName.PersistentStorage: + if (this.isDeclInTargetFile(persistentClass, COMMON_TS_ETS_API_D_TS)) { + this.handleCallExpressionForPersistentStorage(node, propertyAccess); + } + break; + case StorageTypeName.PersistenceV2: + if (this.isDeclInTargetFile(persistentClass, UI_STATE_MANAGEMENT_D_TS)) { + this.handleCallExpressionForPersistenceV2(node, propertyAccess); + } + break; + default: + } + } + + private handleCallExpressionForPersistentStorage( + callExpr: ts.CallExpression, + propertyAccess: ts.PropertyAccessExpression + ): void { + const funcName = propertyAccess.name.getText(); + + switch (funcName) { + case PERSIST_PROP_FUNC_NAME: + if (!this.checkPersistPropForSerialization(callExpr)) { + this.incrementCounters(callExpr, FaultID.PersistentPropNeedImplementMethod); + } + break; + case PERSIST_PROPS_FUNC_NAME: + if (!this.checkPersistPropsForSerialization(callExpr)) { + this.incrementCounters(callExpr, FaultID.PersistentPropsNeedImplementMethod); + } + break; + default: + } + } + + private checkPersistPropForSerialization(callExpr: ts.CallExpression): boolean { + const arg = callExpr.arguments?.[1]; + return !arg || this.checkArgumentForSerialization(arg); + } + + private checkPersistPropsForSerialization(callExpr: ts.CallExpression): boolean { + const arg = callExpr.arguments?.[0]; + if (!arg || !ts.isArrayLiteralExpression(arg)) { + return true; + } + + const literals = arg.elements; + let serializable: boolean = true; + for (const literal of literals) { + if (!ts.isObjectLiteralExpression(literal)) { continue; } - - if (customLayoutFunctionName.has(member.name.getText())) { - hasTargetFunc = true; + const property = literal.properties?.[1]; + if (!property || !ts.isPropertyAssignment(property)) { + continue; + } + if (!this.checkArgumentForSerialization(property.initializer)) { + serializable = false; break; } } - if (!hasTargetFunc) { + return serializable; + } + + private checkArgumentForSerialization(arg: ts.Node): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(arg); + + if (type.isUnion()) { + if ( + type.types.some((type) => { + return !this.isSpecificTypeOfSerialization(type); + }) + ) { + return false; + } + return true; + } + + return this.isSpecificTypeOfSerialization(type); + } + + private isSpecificTypeOfSerialization(type: ts.Type): boolean { + const typeName = this.tsTypeChecker.typeToString(type); + return serializationTypeFlags.has(type.flags) || serializationTypeName.has(typeName); + } + + private handleCallExpressionForPersistenceV2( + callExpr: ts.CallExpression, + propertyAccess: ts.PropertyAccessExpression + ): void { + const funcName = propertyAccess.name.getText(); + if (funcName !== GLOBAL_CONNECT_FUNC_NAME && funcName !== CONNECT_FUNC_NAME) { return; } - const decorators = ts.getDecorators(node); - if (decorators) { - for (const decorator of decorators) { - const decoratorName = TsUtils.getDecoratorName(decorator); - if (decoratorName && decoratorName === CustomDecoratorName.Layoutable) { - return; - } - } + const errorMsg = + `When calling the "${funcName}" method, the parameter list of the methods needs to include ` + + '"toJson" and "fromJson" (arkui-persistencev2-connect-serialization)'; + this.incrementCounters(callExpr, FaultID.PersistenceV2ConnectNeedAddParam, undefined, errorMsg); + } + + private handleRestType(node: ts.Node): void { + if (!this.options.arkts2) { + return; } + if (node.parent && ts.isTupleTypeNode(node.parent)) { + this.incrementCounters(node, FaultID.unfixedTuple); + } + } - const autofix = this.autofixer?.fixCustomLayout(node); - this.incrementCounters(node.name, FaultID.CustomLayoutNeedAddDecorator, autofix); + private handleSuperKeyword(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + const staticContext = ts.findAncestor(node, (parent) => { + return ( + parent && + (ts.canHaveModifiers(parent) && TsUtils.hasModifier(parent.modifiers, ts.SyntaxKind.StaticKeyword) || + ts.isClassStaticBlockDeclaration(parent)) + ); + }); + if (staticContext) { + this.incrementCounters(node, FaultID.SuperInStaticContext); + } } } diff --git a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts index 6a0d3826c6e2e4bd59c518fa3ecd79d0ca177da1..dd3096cc61e605dc85be56b3389eefe6687626a4 100644 --- a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts +++ b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts @@ -38,10 +38,9 @@ export const cookBookRefToFixTitle: Map = new Map([ [177, 'Add \'Sendable\' decorator'], [180, 'Remove the decorator'], [189, 'Add type annotations to numerical variables'], + [192, 'Use "undefined" instead "void"'], [193, 'Replace with arrow function'], - [206, 'Replace with a special library to call'], [209, 'Transform "number" to "int"'], - [238, 'Replace with explicit static initializer'], [251, 'Transform "!!" to "$$()"'], [252, 'Transform "$$" to "$$()"'], [253, '"$value" transform to "this.value"'], @@ -53,14 +52,18 @@ export const cookBookRefToFixTitle: Map = new Map([ [260, '"@Entry" annotaion fixed'], [263, '"@Provide" annotation fixed'], [275, 'Custom layout need add decorator'], + [281, '"@Prop" transform to "@PropRef"'], + [282, '"@StorageProp" transform to "@StoragePropRef"'], + [283, '"@LocalStorageProp" transform to "@LocalStoragePropRef"'], [300, 'Replace calling method of the TS-like `Function` type'], - [330, 'Convert import named objects from JS to ESObject'], - [332, 'Using the ESObject interface to access properties'], + [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 \'ESObject\' interface call'], + [339, 'Using \'ESValue\' interface call'], [341, 'Create JS objects using instantite'], [358, 'Replace missing attribute'], - [359, '"@LocalBuilder" transform to "@Builder"'] + [359, '"@LocalBuilder" transform to "@Builder"'], + [360, '"Repeat" disable default "virtualScroll"'], + [381, 'StateStyles needs arrow function block'] ]); diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index 5a368e5400323eff607a49806cc4b87b838487b2..8fec7929155ac0f77718d1d8be18ce7ddb29172c 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -20,8 +20,8 @@ import { NameGenerator } from '../utils/functions/NameGenerator'; import { isAssignmentOperator } from '../utils/functions/isAssignmentOperator'; import { SymbolCache } from './SymbolCache'; import { SENDABLE_DECORATOR } from '../utils/consts/SendableAPI'; +import { ARKTSUTILS_LOCKS_MEMBER } from '../utils/consts/LimitedStdAPI'; 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, THIS_IDENTIFIER, @@ -29,8 +29,8 @@ import { INSTANCE_IDENTIFIER, COMMON_METHOD_IDENTIFIER, APPLY_STYLES_IDENTIFIER, - CustomDecoratorName, - ARKUI_PACKAGE_NAME, + CustomInterfaceName, + ARKUI_MODULE, VALUE_IDENTIFIER, INDENT_STEP, ENTRY_DECORATOR_NAME, @@ -39,22 +39,32 @@ import { GET_LOCAL_STORAGE_FUNC_NAME, PROVIDE_DECORATOR_NAME, PROVIDE_ALIAS_PROPERTY_NAME, - PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME + PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME, + NEW_PROP_DECORATOR_SUFFIX, + VIRTUAL_SCROLL_IDENTIFIER, + DISABLE_VIRTUAL_SCROLL_IDENTIFIER, + USE_STATIC_STATEMENT } from '../utils/consts/ArkuiConstants'; -import { ES_OBJECT } from '../utils/consts/ESObject'; +import { ES_VALUE } from '../utils/consts/ESObject'; +import type { IncrementDecrementNodeInfo } from '../utils/consts/InteropAPI'; import { - LOAD, - GET_PROPERTY_BY_NAME, - SET_PROPERTY_BY_NAME, - GET_PROPERTY_BY_INDEX, - SET_PROPERTY_BY_INDEX, + GET_PROPERTY, + SET_PROPERTY, ARE_EQUAL, ARE_STRICTLY_EQUAL, WRAP, INSTANTIATE, - TO_NUMBER + TO_NUMBER, + TO_PROMISE, + INVOKE, + INVOKE_METHOD, + LENGTH, + IS_INSTANCE_OF } from '../utils/consts/InteropAPI'; -import { ESLIB_SHAREDARRAYBUFFER } from '../utils/consts/ConcurrentAPI'; +import path from 'node:path'; +import { isStdLibrarySymbol } from '../utils/functions/IsStdLibrary'; +import { propertyAccessReplacements, identifierReplacements } from '../utils/consts/DeprecatedApi'; +import { ARKTS_COLLECTIONS_MODULE, BIT_VECTOR } from '../utils/consts/CollectionsAPI'; const UNDEFINED_NAME = 'undefined'; @@ -81,8 +91,8 @@ const GENERATED_DESTRUCT_OBJECT_TRESHOLD = 1000; const GENERATED_DESTRUCT_ARRAY_NAME = 'GeneratedDestructArray_'; const GENERATED_DESTRUCT_ARRAY_TRESHOLD = 1000; -const GENERATED_IMPORT_VARIABLE_NAME = 'GeneratedImportVar_'; -const GENERATED_IMPORT_VARIABLE_TRESHOLD = 1000; +const GENERATED_TMP_VARIABLE_NAME = 'tmp_'; +const GENERATED_TMP_VARIABLE_TRESHOLD = 1000; const SPECIAL_LIB_NAME = 'specialAutofixLib'; @@ -143,12 +153,11 @@ export class Autofixer { GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD ); - private readonly importVarNameGenerator = new NameGenerator( - GENERATED_IMPORT_VARIABLE_NAME, - GENERATED_IMPORT_VARIABLE_TRESHOLD + private readonly tmpVariableNameGenerator = new NameGenerator( + GENERATED_TMP_VARIABLE_NAME, + GENERATED_TMP_VARIABLE_TRESHOLD ); - private modVarName: string = ''; private readonly lastImportEndMap = new Map(); private readonly symbolCache: SymbolCache; @@ -200,7 +209,6 @@ export class Autofixer { * @param variableDeclarationMap - Map of property names to variable names. * @param newObjectName - Name of the new object to destructure. * @param declarationFlags - Flags for the variable declaration. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ @@ -208,7 +216,6 @@ export class Autofixer { variableDeclarationMap: Map, newObjectName: string, declarationFlags: ts.NodeFlags, - printer: ts.Printer, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -235,7 +242,7 @@ export class Autofixer { ); // Print the variable statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); destructElementText += text + this.getNewLine(); }); @@ -251,7 +258,7 @@ export class Autofixer { */ private genAutofixForObjDecls( variableDeclaration: ts.VariableDeclaration, - newObjectName: string | undefined, + newObjectName: string, destructElementText: string, isIdentifier: boolean ): Autofix[] | undefined { @@ -270,7 +277,7 @@ export class Autofixer { } else { // Create autofix suggestions for both variable name and destructuring variableNameReplaceText = { - replacementText: newObjectName as string, + replacementText: newObjectName, start: variableDeclaration.name.getStart(), end: variableDeclaration.name.getEnd() }; @@ -292,18 +299,18 @@ 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(variableDeclaration: ts.VariableDeclaration): boolean { + private static passBoundaryCheckForObjDecls(bindingPattern: ts.BindingPattern, intializer: ts.Expression): boolean { // Check if the fault ID is for a destructuring parameter or if the declaration has a spread operator if ( - TsUtils.destructuringDeclarationHasSpreadOperator(variableDeclaration.name as ts.BindingPattern) || - TsUtils.destructuringDeclarationHasDefaultValue(variableDeclaration.name as ts.BindingPattern) + TsUtils.destructuringDeclarationHasSpreadOperator(bindingPattern) || + TsUtils.destructuringDeclarationHasDefaultValue(bindingPattern) ) { return false; } // If the initializer is an object literal expression, check its properties - if (ts.isObjectLiteralExpression(variableDeclaration.initializer as ts.Node)) { - const len = (variableDeclaration.initializer as ts.ObjectLiteralExpression).properties.length; + if (ts.isObjectLiteralExpression(intializer)) { + const len = intializer.properties.length; if (len === 0) { // Return false if there are no properties return false; @@ -321,24 +328,32 @@ export class Autofixer { * @returns Array of autofix suggestions or undefined. */ fixObjectBindingPatternDeclarations(variableDeclaration: ts.VariableDeclaration): Autofix[] | undefined { - if (!Autofixer.passBoundaryCheckForObjDecls(variableDeclaration)) { + if (!ts.isObjectBindingPattern(variableDeclaration.name) || !variableDeclaration.initializer) { + return undefined; + } + + if (!Autofixer.passBoundaryCheckForObjDecls(variableDeclaration.name, variableDeclaration.initializer)) { return undefined; } + // Map to hold variable names and their corresponding property names const variableDeclarationMap: Map = new Map(); - // If the declaration is an object binding pattern, extract names - if (ts.isObjectBindingPattern(variableDeclaration.name)) { - variableDeclaration.name.elements.forEach((element) => { - if (!element.propertyName) { - variableDeclarationMap.set(element.name.getText(), element.name.getText()); - } else { - variableDeclarationMap.set((element.propertyName as ts.Identifier).text, element.name.getText()); + + // Extract property names + for (const element of variableDeclaration.name.elements) { + if (!element.propertyName) { + variableDeclarationMap.set(element.name.getText(), element.name.getText()); + } else { + if (!ts.isIdentifier(element.propertyName)) { + return undefined; } - }); + variableDeclarationMap.set(element.propertyName.text, element.name.getText()); + } } const sourceFile = variableDeclaration.getSourceFile(); let newObjectName: string | undefined; - const isIdentifier = ts.isIdentifier(variableDeclaration.initializer as ts.Node); + const isIdentifier = ts.isIdentifier(variableDeclaration.initializer); + // If it is identifer, use its text as the new object name; otherwise, generate a unique name if (isIdentifier) { newObjectName = variableDeclaration.initializer?.getText(); @@ -353,7 +368,6 @@ export class Autofixer { variableDeclarationMap, newObjectName, declarationFlags, - this.printer, sourceFile ); @@ -366,7 +380,6 @@ export class Autofixer { * @param variableNames - Array of variable names corresponding to array elements. * @param newArrayName - Name of the new array to destructure. * @param declarationFlags - Flags for the variable declaration. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ @@ -374,7 +387,6 @@ export class Autofixer { variableNames: string[], newArrayName: string, declarationFlags: ts.NodeFlags, - printer: ts.Printer, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -405,7 +417,7 @@ export class Autofixer { ); // Print the variable statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); destructElementText += text + this.getNewLine(); } @@ -421,7 +433,7 @@ export class Autofixer { */ private genAutofixForArrayDecls( variableDeclaration: ts.VariableDeclaration, - newArrayName: string | undefined, + newArrayName: string, destructElementText: string, isIdentifierOrElementAccess: boolean ): Autofix[] { @@ -440,7 +452,7 @@ export class Autofixer { } else { // Create autofix suggestions for both variable name and destructuring variableNameReplaceText = { - replacementText: newArrayName as string, + replacementText: newArrayName, start: variableDeclaration.name.getStart(), end: variableDeclaration.name.getEnd() }; @@ -463,27 +475,28 @@ export class Autofixer { * @returns A boolean indicating if the declaration passes the boundary checks. */ private static passBoundaryCheckForArrayDecls( - variableDeclaration: ts.VariableDeclaration, + bindingPattern: ts.ArrayBindingPattern, + initializer: ts.Expression, isArrayOrTuple: boolean ): boolean { // If it's not an array/tuple or the declaration has a spread operator in destructuring if ( !isArrayOrTuple || - TsUtils.destructuringDeclarationHasSpreadOperator(variableDeclaration.name as ts.BindingPattern) || - TsUtils.destructuringDeclarationHasDefaultValue(variableDeclaration.name as ts.BindingPattern) + TsUtils.destructuringDeclarationHasSpreadOperator(bindingPattern) || + TsUtils.destructuringDeclarationHasDefaultValue(bindingPattern) ) { // Return false if it fails the boundary check return false; } // Check if the array binding pattern has any empty elements - if (TsUtils.checkArrayBindingHasEmptyElement(variableDeclaration.name as ts.ArrayBindingPattern)) { + if (TsUtils.checkArrayBindingHasEmptyElement(bindingPattern)) { // Return false if it contains empty elements return false; } // Check if the initializer has the same dimension as expected - if (!TsUtils.isSameDimension(variableDeclaration.initializer as ts.Node)) { + if (!TsUtils.isSameDimension(initializer)) { return false; } @@ -502,28 +515,29 @@ export class Autofixer { variableDeclaration: ts.VariableDeclaration, isArrayOrTuple: boolean ): Autofix[] | undefined { - if (!Autofixer.passBoundaryCheckForArrayDecls(variableDeclaration, isArrayOrTuple)) { + if (!ts.isArrayBindingPattern(variableDeclaration.name) || !variableDeclaration.initializer) { return undefined; } - const variableNames: string[] = []; - // If the declaration is an array binding pattern, extract variable names - if (ts.isArrayBindingPattern(variableDeclaration.name)) { - variableDeclaration.name.elements.forEach((element) => { - variableNames.push(element.getText()); - }); + if ( + !Autofixer.passBoundaryCheckForArrayDecls( + variableDeclaration.name, + variableDeclaration.initializer, + isArrayOrTuple + ) + ) { + return undefined; } + const variableNames: string[] = Autofixer.getVarNamesFromArrayBindingPattern(variableDeclaration.name); - const sourceFile = variableDeclaration.getSourceFile(); let newArrayName: string | undefined = ''; // Check if the initializer is either an identifier or an element access expression const isIdentifierOrElementAccess = - ts.isIdentifier(variableDeclaration.initializer as ts.Node) || - ts.isElementAccessExpression(variableDeclaration.initializer as ts.Node); + ts.isIdentifier(variableDeclaration.initializer) || ts.isElementAccessExpression(variableDeclaration.initializer); // If it is, use its text as the new array name; otherwise, generate a unique name if (isIdentifierOrElementAccess) { - newArrayName = variableDeclaration.initializer?.getText(); + newArrayName = variableDeclaration.initializer.getText(); } else { - newArrayName = TsUtils.generateUniqueName(this.destructArrayNameGenerator, sourceFile); + newArrayName = TsUtils.generateUniqueName(this.destructArrayNameGenerator, variableDeclaration.getSourceFile()); } if (!newArrayName) { return undefined; @@ -536,8 +550,7 @@ export class Autofixer { variableNames, newArrayName, declarationFlags, - this.printer, - sourceFile + variableDeclaration.getSourceFile() ); // Generate and return autofix suggestions for the array declarations @@ -549,18 +562,26 @@ export class Autofixer { ); } + private static getVarNamesFromArrayBindingPattern(bindingPattern: ts.ArrayBindingPattern): string[] { + const variableNames: string[] = []; + if (ts.isArrayBindingPattern(bindingPattern)) { + bindingPattern.elements.forEach((element) => { + variableNames.push(element.getText()); + }); + } + return variableNames; + } + /** * Generates the text representation for destructuring assignments in an array. * @param variableNames - Array of variable names corresponding to array elements. * @param newArrayName - Name of the new array to use for destructuring. - * @param printer - TypeScript printer instance. * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring assignment text. */ private genDestructElementTextForArrayAssignment( variableNames: string[], - newArrayName: string | undefined, - printer: ts.Printer, + newArrayName: string, sourceFile: ts.SourceFile ): string { let destructElementText: string = ''; @@ -572,7 +593,7 @@ export class Autofixer { // Create an element access expression for the new array const elementAccessExpr = ts.factory.createElementAccessExpression( - ts.factory.createIdentifier(newArrayName as string), + ts.factory.createIdentifier(newArrayName), ts.factory.createNumericLiteral(i) ); @@ -587,7 +608,7 @@ export class Autofixer { const expressionStatement = ts.factory.createExpressionStatement(assignmentExpr); // Print the expression statement to text and append it - const text = printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); + const text = this.printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); destructElementText += text + this.getNewLine(); } @@ -603,7 +624,7 @@ export class Autofixer { */ private genAutofixForArrayAssignment( assignmentExpr: ts.BinaryExpression, - newArrayName: string | undefined, + newArrayName: string, destructElementText: string, isIdentifierOrElementAccess: boolean ): Autofix[] { @@ -650,21 +671,21 @@ export class Autofixer { isArrayOrTuple: boolean ): boolean { // Return false if the assignment is not for an array or tuple - if (!isArrayOrTuple) { + if (!isArrayOrTuple || !ts.isArrayLiteralExpression(assignmentExpr.left)) { return false; } // Check if the left side of the assignment is an array literal expression with a spread operator - if (TsUtils.destructuringAssignmentHasSpreadOperator(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasSpreadOperator(assignmentExpr.left)) { return false; } - if (TsUtils.destructuringAssignmentHasDefaultValue(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasDefaultValue(assignmentExpr.left)) { return false; } // Check if the left side of the assignment has an empty element - if (TsUtils.checkArrayLiteralHasEmptyElement(assignmentExpr.left as ts.ArrayLiteralExpression)) { + if (TsUtils.checkArrayLiteralHasEmptyElement(assignmentExpr.left)) { return false; } @@ -701,7 +722,7 @@ export class Autofixer { const sourceFile = assignmentExpr.getSourceFile(); let newArrayName: string | undefined = ''; const isIdentifierOrElementAccess = - ts.isIdentifier(assignmentExpr.right) || ts.isElementAccessExpression(assignmentExpr.right as ts.Node); + ts.isIdentifier(assignmentExpr.right) || ts.isElementAccessExpression(assignmentExpr.right); if (isIdentifierOrElementAccess) { newArrayName = assignmentExpr.right.getText(); } else { @@ -712,12 +733,7 @@ export class Autofixer { } // Generate the text for destructuring assignments - const destructElementText = this.genDestructElementTextForArrayAssignment( - variableNames, - newArrayName, - this.printer, - sourceFile - ); + const destructElementText = this.genDestructElementTextForArrayAssignment(variableNames, newArrayName, sourceFile); return this.genAutofixForArrayAssignment( assignmentExpr, @@ -732,25 +748,29 @@ export class Autofixer { * @param binaryExpr - The binary expression containing the object literal. * @returns An object containing the variable declaration map and needParentheses indicating if property initializers are object literals. */ - private static genTsVarDeclMapAndFlags(binaryExpr: ts.BinaryExpression): { - tsVarDeclMap: Map; - needParentheses: boolean[]; - } { + private static genTsVarDeclMapAndFlags(objLiteralExpr: ts.ObjectLiteralExpression): + | { + tsVarDeclMap: Map; + needParentheses: boolean[]; + } + | undefined { const tsVarDeclMap: Map = new Map(); const needParentheses: boolean[] = []; - // Check if the left side of the binary expression is an object literal - if (ts.isObjectLiteralExpression(binaryExpr.left)) { - binaryExpr.left.properties.forEach((property) => { - // Handle property assignments with initializer - if (ts.isPropertyAssignment(property)) { - tsVarDeclMap.set(property.name?.getText(), property.initializer.getText()); - needParentheses.push(ts.isObjectLiteralExpression(property.initializer)); - } else if (ts.isShorthandPropertyAssignment(property)) { - tsVarDeclMap.set(property.name?.getText(), property.name.getText()); - needParentheses.push(false); - } - }); + for (const property of objLiteralExpr.properties) { + // Handle property assignments with initializer + if (!property.name || !ts.isIdentifier(property.name)) { + return undefined; + } + if (ts.isPropertyAssignment(property)) { + tsVarDeclMap.set(property.name.getText(), property.initializer.getText()); + needParentheses.push(ts.isObjectLiteralExpression(property.initializer)); + } else if (ts.isShorthandPropertyAssignment(property)) { + tsVarDeclMap.set(property.name.getText(), property.name.getText()); + needParentheses.push(false); + } else { + return undefined; + } } return { tsVarDeclMap, needParentheses }; @@ -762,15 +782,13 @@ export class Autofixer { * @param needParentheses - Array of needParentheses indicating if property initializers are object literals. * @param newObjName - The name of the new object to use for destructuring. * @param binaryExpr - The binary expression representing the destructuring. - * @param printer - TypeScript printer instance for printing nodes. * @returns The generated text for destructuring assignments. */ private genDestructElementTextForObjAssignment( tsVarDeclMap: Map, needParentheses: boolean[], newObjName: string, - binaryExpr: ts.BinaryExpression, - printer: ts.Printer + binaryExpr: ts.BinaryExpression ): string { let destructElementText: string = ''; let index: number = 0; @@ -795,7 +813,7 @@ export class Autofixer { // Append the generated text for the destructuring assignment destructElementText += - printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); + this.printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); index++; }); @@ -807,14 +825,9 @@ export class Autofixer { * Creates the replacement text for the variable declaration name. * @param binaryExpr - The binary expression containing the object literal or call expression. * @param newObjName - The new object name to be used in the replacement. - * @param printer - TypeScript printer instance for printing nodes. * @returns The replacement text for the variable declaration name. */ - private static genDeclNameReplaceTextForObjAssignment( - binaryExpr: ts.BinaryExpression, - newObjName: string, - printer: ts.Printer - ): string { + private genDeclNameReplaceTextForObjAssignment(binaryExpr: ts.BinaryExpression, newObjName: string): string { let declNameReplaceText = ''; // create variableDeclList and get declNameReplaceText text @@ -825,7 +838,7 @@ export class Autofixer { binaryExpr.right ); const variableDeclList = ts.factory.createVariableDeclarationList([variableDecl], ts.NodeFlags.Let); - declNameReplaceText = printer.printNode(ts.EmitHint.Unspecified, variableDeclList, binaryExpr.getSourceFile()); + declNameReplaceText = this.printer.printNode(ts.EmitHint.Unspecified, variableDeclList, binaryExpr.getSourceFile()); return declNameReplaceText; } @@ -879,12 +892,16 @@ export class Autofixer { * @returns A boolean indicating if the assignment passes the boundary checks. */ private static passBoundaryCheckForObjAssignment(binaryExpr: ts.BinaryExpression): boolean { + if (!ts.isObjectLiteralExpression(binaryExpr.left)) { + return false; + } + // Check for spread operator in destructuring assignment on the left side - if (TsUtils.destructuringAssignmentHasSpreadOperator(binaryExpr.left as ts.ObjectLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasSpreadOperator(binaryExpr.left)) { return false; } - if (TsUtils.destructuringAssignmentHasDefaultValue(binaryExpr.left as ts.ObjectLiteralExpression)) { + if (TsUtils.destructuringAssignmentHasDefaultValue(binaryExpr.left)) { return false; } @@ -906,8 +923,18 @@ export class Autofixer { if (!Autofixer.passBoundaryCheckForObjAssignment(binaryExpr)) { return undefined; } + + // Check if the left side of the binary expression is an object literal + if (!ts.isObjectLiteralExpression(binaryExpr.left)) { + return undefined; + } + // Create a mapping of variable declarations and needParentheses - const { tsVarDeclMap, needParentheses } = Autofixer.genTsVarDeclMapAndFlags(binaryExpr); + const varDeclMapFlags = Autofixer.genTsVarDeclMapAndFlags(binaryExpr.left); + if (!varDeclMapFlags) { + return undefined; + } + const { tsVarDeclMap, needParentheses } = varDeclMapFlags; const sourceFile = binaryExpr.getSourceFile(); let newObjName: string | undefined = ''; @@ -926,12 +953,11 @@ export class Autofixer { tsVarDeclMap, needParentheses, newObjName, - binaryExpr, - this.printer + binaryExpr ); // Create the replacement text for the variable declaration name - const declNameReplaceText = Autofixer.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName, this.printer); + const declNameReplaceText = this.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName); // Generate autofix suggestions return this.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); @@ -960,7 +986,59 @@ export class Autofixer { return this.renameSymbolAsIdentifier(symbol, enumMember); } + renameAsObjectElementAccessExpression(node: ts.ElementAccessExpression): Autofix[] | undefined { + const parenExpr = ts.isParenthesizedExpression(node.expression) ? node.expression : undefined; + const asExpr = parenExpr && ts.isAsExpression(parenExpr.expression) ? parenExpr.expression : undefined; + if (!asExpr) { + return undefined; + } + + const argument = node.argumentExpression; + const propertyName = ts.isStringLiteral(argument) ? argument.text : undefined; + if (!propertyName) { + return undefined; + } + + const propertyChain: string[] = [propertyName]; + let current: ts.Node = node; + + while (current.parent && ts.isElementAccessExpression(current.parent)) { + const parentArg = current.parent.argumentExpression; + if (ts.isStringLiteral(parentArg)) { + propertyChain.push(parentArg.text); + } + current = current.parent; + } + const realObj = asExpr.expression; + const type = this.typeChecker.getTypeAtLocation(realObj); + + let currentType = type; + for (const prop of propertyChain) { + const property = this.typeChecker.getPropertyOfType(currentType, prop); + if (!property) { + return undefined; + } + currentType = this.typeChecker.getTypeOfSymbolAtLocation(property, node); + } + const replacementText = realObj.getText() + '.' + propertyChain.join('.'); + + return [ + { + replacementText, + start: node.getStart(), + end: current.getEnd() + } + ]; + } + fixPropertyAccessByIndex(node: ts.ElementAccessExpression): Autofix[] | undefined { + if (ts.isParenthesizedExpression(node.expression) && ts.isAsExpression(node.expression.expression)) { + const assertedType = this.typeChecker.getTypeAtLocation(node.expression.expression.type); + if (this.typeChecker.typeToString(assertedType) === 'object') { + return this.renameAsObjectElementAccessExpression(node); + } + } + const symbol = this.typeChecker.getSymbolAtLocation(node.argumentExpression); if (symbol === undefined) { return undefined; @@ -973,8 +1051,10 @@ export class Autofixer { if (this.renameSymbolAsIdentifierCache.has(symbol)) { return this.renameSymbolAsIdentifierCache.get(symbol); } - - if (!TsUtils.isPropertyOfInternalClassOrInterface(symbol)) { + if ( + !TsUtils.isPropertyOfInternalClassOrInterface(symbol) && + !(enumMember?.parent && ts.isEnumDeclaration(enumMember.parent)) + ) { this.renameSymbolAsIdentifierCache.set(symbol, undefined); return undefined; } @@ -1981,7 +2061,7 @@ export class Autofixer { !objectLiteralExpr.parent.type ) { const text = ': ' + newInterfaceName; - const pos = Autofixer.getDeclarationTypePositionForObjectLiteral(objectLiteralExpr.parent); + const pos = Autofixer.getDeclarationTypePosition(objectLiteralExpr.parent); return { start: pos, end: pos, replacementText: text }; } @@ -1997,7 +2077,7 @@ export class Autofixer { return { start: objectLiteralExpr.getStart(), end: objectLiteralExpr.getEnd(), replacementText: text }; } - private static getDeclarationTypePositionForObjectLiteral( + private static getDeclarationTypePosition( decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration ): number { if (ts.isPropertyDeclaration(decl)) { @@ -2011,7 +2091,8 @@ export class Autofixer { private fixObjectLiteralAsClass( objectLiteralExpr: ts.ObjectLiteralExpression, typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, - enclosingStmt: ts.Node + enclosingStmt: ts.Node, + typeNode?: ts.TypeReferenceNode ): Autofix[] | undefined { if (this.utils.nodeCapturesValueFromEnclosingLocalScope(objectLiteralExpr, enclosingStmt)) { return undefined; @@ -2030,9 +2111,9 @@ export class Autofixer { const classDeclAndCtorInitProps = this.createClassDeclForObjectLiteral( objectLiteralExpr, enclosingStmt, - newClassName, - newInitInterfaceName, - typeDecl + { className: newClassName, initInterfaceName: newInitInterfaceName }, + typeDecl, + typeNode ); if (!classDeclAndCtorInitProps) { return undefined; @@ -2061,10 +2142,11 @@ export class Autofixer { private createClassDeclForObjectLiteral( objectLiteralExpr: ts.ObjectLiteralExpression, enclosingStmt: ts.Node, - newClassName: string, - newInitInterfaceName: string, - typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + names: { className: string; initInterfaceName: string }, + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + typeNode?: ts.TypeReferenceNode ): { classDecl: ts.ClassDeclaration; ctorInitProps: ts.PropertyAssignment[] } | undefined { + const { className, initInterfaceName } = names; const classFields: ts.PropertyDeclaration[] = []; const classMethods: (ts.MethodDeclaration | ts.AccessorDeclaration)[] = []; const ctorBodyStmts: ts.Statement[] = []; @@ -2094,14 +2176,14 @@ export class Autofixer { const classElements: ts.ClassElement[] = [...classFields]; if (ctorInitProps.length) { - classElements.push(Autofixer.createClassConstructorForObjectLiteral(newInitInterfaceName, ctorBodyStmts)); + classElements.push(Autofixer.createClassConstructorForObjectLiteral(initInterfaceName, ctorBodyStmts)); } classElements.push(...classMethods); - const heritageClauses = Autofixer.createHeritageClausesForObjectLiteralClass(typeDecl); + const heritageClauses = Autofixer.createHeritageClausesForObjectLiteralClass(typeDecl, typeNode); return { - classDecl: ts.factory.createClassDeclaration(undefined, newClassName, undefined, heritageClauses, classElements), + classDecl: ts.factory.createClassDeclaration(undefined, className, undefined, heritageClauses, classElements), ctorInitProps }; } @@ -2160,20 +2242,32 @@ export class Autofixer { } private static createHeritageClausesForObjectLiteralClass( - typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + typeNode?: ts.TypeReferenceNode ): ts.HeritageClause[] | undefined { if (!typeDecl?.name) { return undefined; } + const heritageTypeExpression = typeNode ? + Autofixer.entityNameToExpression(typeNode.typeName) : + ts.factory.createIdentifier(typeDecl.name.text); + return [ ts.factory.createHeritageClause( ts.isClassDeclaration(typeDecl) ? ts.SyntaxKind.ExtendsKeyword : ts.SyntaxKind.ImplementsKeyword, - [ts.factory.createExpressionWithTypeArguments(typeDecl.name, undefined)] + [ts.factory.createExpressionWithTypeArguments(heritageTypeExpression, undefined)] ) ]; } + private static entityNameToExpression(name: ts.EntityName): ts.Expression { + if (ts.isQualifiedName(name)) { + return ts.factory.createPropertyAccessExpression(Autofixer.entityNameToExpression(name.left), name.right); + } + return ts.factory.createIdentifier(name.text); + } + private static createClassConstructorForObjectLiteral( newInitInterfaceName: string, ctorBodyStmts: ts.Statement[] @@ -2240,7 +2334,8 @@ export class Autofixer { return undefined; } - return this.fixObjectLiteralAsClass(objectLiteralExpr, typeDecl, enclosingStmt); + const typeNode = (objectLiteralExpr.parent as ts.VariableDeclaration).type as ts.TypeReferenceNode | undefined; + return this.fixObjectLiteralAsClass(objectLiteralExpr, typeDecl, enclosingStmt, typeNode); } private hasMethodOverridingProperty( @@ -2359,20 +2454,14 @@ export class Autofixer { return [{ start: node.getStart(), end: node.getEnd(), replacementText }]; } - removeImportSpecifier( - specToRemove: ts.ImportSpecifier, - importDeclaration: ts.ImportDeclaration - ): Autofix[] | undefined { - if (!importDeclaration) { - return undefined; - } - - const importClause = importDeclaration.importClause; - if (!importClause?.namedBindings || !ts.isNamedImports(importClause.namedBindings)) { + removeImportSpecifier(specToRemove: ts.ImportSpecifier, importDecl: ts.ImportDeclaration): Autofix[] | undefined { + const importClause = importDecl.importClause; + const namedBindings = importClause?.namedBindings; + if (!importClause || !namedBindings || !ts.isNamedImports(namedBindings)) { return undefined; } - const namedBindings = importClause.namedBindings; + const fixes: Autofix[] = []; const allSpecifiers = namedBindings.elements; const remainingSpecifiers = allSpecifiers.filter((spec) => { return spec !== specToRemove; @@ -2380,48 +2469,94 @@ export class Autofixer { // 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 specIndex = allSpecifiers.findIndex((spec) => { - return spec === specToRemove; - }); - const isLast = specIndex === allSpecifiers.length - 1; - const isFirst = specIndex === 0; + fixes.push({ + start: importClause.name ? importClause.name.end : importDecl.getStart(), + end: importClause.name ? namedBindings.end : importDecl.getEnd(), + replacementText: '' + }); + } else { + 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(); + let start = specToRemove.getStart(); + let end = specToRemove.getEnd(); - if (!isLast) { - end = allSpecifiers[specIndex + 1].getStart(); - } else if (!isFirst) { - const prev = allSpecifiers[specIndex - 1]; - start = prev.getEnd(); + if (!isLast) { + end = allSpecifiers[specIndex + 1].getStart(); + } else if (!isFirst) { + const prev = allSpecifiers[specIndex - 1]; + start = prev.getEnd(); + } + fixes.push({ start: start, end: end, replacementText: '' }); } - return [{ start, end, replacementText: '' }]; + const alias = specToRemove.name; + const original = specToRemove.propertyName; + if (original) { + const replacements = this.replaceIdentifierUsages(alias, original.getText()); + fixes.push(...replacements); + } + return fixes; } - removeDefaultImport(importDecl: ts.ImportDeclaration, defaultImport: ts.Identifier): Autofix[] | undefined { + removeDefaultImport( + importDecl: ts.ImportDeclaration, + defaultImport: ts.Identifier, + replacementName: string + ): Autofix[] | undefined { const importClause = importDecl.importClause; if (!importClause || !defaultImport) { return undefined; } - + const fixes: Autofix[] = []; const namedBindings = importClause.namedBindings; + fixes.push({ + start: namedBindings ? defaultImport.getStart() : importDecl.getStart(), + end: namedBindings ? namedBindings.getStart() : importDecl.getEnd(), + replacementText: '' + }); + + const replacements = this.replaceIdentifierUsages(defaultImport, replacementName); + fixes.push(...replacements); - if (!namedBindings) { - return this.removeNode(importDecl); + return fixes; + } + + replaceIdentifierUsages(importedIdentifier: ts.Identifier, replacementName: string): Autofix[] { + const fixes: Autofix[] = []; + const file = importedIdentifier.getSourceFile(); + const originalSymbol = this.typeChecker.getSymbolAtLocation(importedIdentifier); + if (!originalSymbol) { + return fixes; } - const start = defaultImport.getStart(); - const end = namedBindings.getStart(); - return [{ start, end, replacementText: '' }]; + const visit = (node: ts.Node): void => { + if (ts.isIdentifier(node) && !ts.isImportClause(node.parent) && !ts.isImportSpecifier(node.parent)) { + const nodeSymbol = this.typeChecker.getSymbolAtLocation(node); + if (nodeSymbol === originalSymbol) { + // Skip any identifier that is part of a 'locks' qualification + const parent = node.parent; + if ( + ts.isQualifiedName(parent) && parent.right.text === ARKTSUTILS_LOCKS_MEMBER || + ts.isPropertyAccessExpression(parent) && parent.name.text === ARKTSUTILS_LOCKS_MEMBER + ) { + return; + } + fixes.push({ + start: node.getStart(), + end: node.getEnd(), + replacementText: replacementName + }); + } + } + ts.forEachChild(node, visit); + }; + + visit(file); + return fixes; } fixSendableExplicitFieldType(node: ts.PropertyDeclaration): Autofix[] | undefined { @@ -2481,12 +2616,6 @@ export class Autofixer { return undefined; } - fixGlobalThisGet(node: ts.PropertyAccessExpression): Autofix[] { - void this; - const replacement = `${SPECIAL_LIB_NAME}.globalThis.get("${node.name.text}")`; - return [{ start: node.getStart(), end: node.getEnd(), replacementText: replacement }]; - } - fixVoidOperator(voidExpr: ts.VoidExpression): Autofix[] { let newExpr = voidExpr.expression; @@ -2617,12 +2746,6 @@ export class Autofixer { return { pattern, flag }; } - fixDebuggerStatement(debuggerStmt: ts.DebuggerStatement): Autofix[] { - void this; - const text = SPECIAL_LIB_NAME + '.debugger();'; - return [{ start: debuggerStmt.getStart(), end: debuggerStmt.getEnd(), replacementText: text }]; - } - /* * "unsafe" (result is not common subset) autofixes */ @@ -2694,6 +2817,7 @@ export class Autofixer { fixCustomBidirectionalBinding( originalExpr: ts.ObjectLiteralExpression, + type: ts.TypeNode | undefined, currentParam: ts.Identifier, customParam: ts.Identifier ): Autofix[] | undefined { @@ -2714,14 +2838,7 @@ export class Autofixer { ], true ); - const parameter = ts.factory.createParameterDeclaration( - undefined, - undefined, - value, - undefined, - undefined, - undefined - ); + const parameter = ts.factory.createParameterDeclaration(undefined, undefined, value, undefined, type, undefined); const arrowFunc = ts.factory.createArrowFunction( undefined, undefined, @@ -2802,7 +2919,7 @@ export class Autofixer { const newFuncDecl = Autofixer.createFunctionDeclaration(funcDecl, undefined, parameDecl, returnType, newBlock); let text = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); if (preserveDecorator) { - text = '@' + CustomDecoratorName.AnimatableExtend + this.getNewLine() + text; + text = '@' + CustomInterfaceName.AnimatableExtend + this.getNewLine() + text; } return [{ start: funcDecl.getStart(), end: funcDecl.getEnd(), replacementText: text }]; } @@ -3061,141 +3178,429 @@ export class Autofixer { } } - fixVariableDeclaration(node: ts.VariableDeclaration, isEnum: boolean): Autofix[] | undefined { - const initializer = node.initializer; - const name = node.name; - const sym = this.typeChecker.getSymbolAtLocation(name); - if (!sym) { - return undefined; + private getVariableName(node: ts.Node): string | undefined { + let variableName: string | undefined; + + switch (node.kind) { + case ts.SyntaxKind.BinaryExpression: { + const binaryExpr = node as ts.BinaryExpression; + if (binaryExpr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return undefined; + } + + variableName = binaryExpr.left.getText(); + break; + } + case ts.SyntaxKind.VariableDeclaration: { + const variableDecl = node as ts.VariableDeclaration; + variableName = variableDecl.name.getText(); + break; + } + case ts.SyntaxKind.ExpressionStatement: { + variableName = TsUtils.generateUniqueName(this.tmpVariableNameGenerator, this.sourceFile); + break; + } + default: { + return undefined; + } } - const type = this.typeChecker.getTypeOfSymbolAtLocation(sym, name); - const typeText = this.typeChecker.typeToString(type); - const typeFlags = type.flags; + return variableName; + } + + private getNewNodesForIncrDecr(variableName: string, operator: number): IncrementDecrementNodeInfo | undefined { + let update: string | undefined; + let updateNode: ts.BinaryExpression | undefined; - if (!TsUtils.isNumberLike(type, typeText, isEnum)) { - return undefined; + switch (operator) { + case ts.SyntaxKind.MinusMinusToken: { + const { varAssignText, addOrDecrOperation } = this.createNewIncrDecrNodes( + variableName, + ts.SyntaxKind.MinusToken + ); + update = varAssignText; + updateNode = addOrDecrOperation; + break; + } + case ts.SyntaxKind.PlusPlusToken: { + const { varAssignText, addOrDecrOperation } = this.createNewIncrDecrNodes( + variableName, + ts.SyntaxKind.PlusToken + ); + update = varAssignText; + updateNode = addOrDecrOperation; + break; + } + default: + return undefined; } - let typeNode: ts.TypeNode; - if (typeText === STRINGLITERAL_NUMBER || (typeFlags & ts.TypeFlags.NumberLiteral) !== 0 || isEnum) { - typeNode = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); - } else if (typeText === STRINGLITERAL_NUMBER_ARRAY) { - typeNode = ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)); - } else { + return { varAssignText: update, addOrDecrOperation: updateNode }; + } + + fixUnaryIncrDecr( + node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression, + pan: ts.PropertyAccessExpression + ): Autofix[] | undefined { + const parent = node.parent; + const grandParent = parent.parent; + + const { expression, name } = pan; + const { operator } = node; + const isVariableDeclaration = ts.isVariableDeclaration(node.parent); + + const variableName = this.getVariableName(node.parent); + + if (!variableName) { return undefined; } - const newVarDecl = ts.factory.createVariableDeclaration(name, undefined, typeNode, initializer); - const parent = node.parent; - if (!ts.isVariableDeclarationList(parent)) { + const updateNodes = this.getNewNodesForIncrDecr(variableName, operator); + + if (!updateNodes?.varAssignText || !updateNodes.addOrDecrOperation) { return undefined; } - const text = this.printer.printNode(ts.EmitHint.Unspecified, newVarDecl, node.getSourceFile()); - return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; - } - fixPropertyDeclarationNumericSemanticsArray(node: ts.PropertyDeclaration): Autofix[] { - const newProperty = ts.factory.createPropertyDeclaration( - node.modifiers, - node.name, - undefined, - ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)), - node.initializer + const replacementText = this.getReplacementTextForPrefixAndPostfixUnary( + node, + updateNodes, + expression, + name, + variableName ); - const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, newProperty, node.getSourceFile()); + if (!replacementText) { + return undefined; + } - return [ - { - start: node.getStart(), - end: node.getEnd(), - replacementText: replacementText + if (isVariableDeclaration) { + const start = grandParent.getStart(); + const end = grandParent.getEnd(); + return [{ replacementText, start, end }]; + } + + const start = parent.getStart(); + const end = parent.getEnd(); + return [{ replacementText, start, end }]; + } + + private getReplacementTextForPrefixAndPostfixUnary( + node: ts.Node, + updateNodes: IncrementDecrementNodeInfo, + expression: ts.LeftHandSideExpression, + name: ts.MemberName, + variableName: string + ): string | undefined { + const { varAssignText, addOrDecrOperation } = updateNodes; + const converted: ts.Node = this.createGetPropertyForIncrDecr(expression.getText(), name.text); + let convertedAssigned = ''; + if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + convertedAssigned = this.wrapPropertyAccessInBinaryExpr(variableName, converted); + } else { + convertedAssigned = this.wrapPropertyAccessInVariableDeclaration(variableName, converted); + } + let replacementText = ''; + + switch (node.kind) { + case ts.SyntaxKind.PrefixUnaryExpression: { + const assign = this.createSetProperty( + expression.getText(), + name.text, + ts.factory.createIdentifier(variableName) + ); + replacementText = `${convertedAssigned}\n${varAssignText}\n${assign}\n`; + break; } - ]; + case ts.SyntaxKind.PostfixUnaryExpression: { + const assign = this.createSetProperty(expression.getText(), name.text, addOrDecrOperation as ts.Expression); + replacementText = `${convertedAssigned}\n${assign}\n${varAssignText}\n`; + break; + } + default: { + return undefined; + } + } + + return 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) + private wrapPropertyAccessInVariableDeclaration(variableName: string, wrappedNode: ts.Node): string { + const node = ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(variableName), + undefined, + undefined, + wrappedNode as ts.Expression + ) + ], + ts.NodeFlags.Let ); - const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); - return [{ start: express.getStart(), end: express.getEnd(), replacementText: replacementText }]; + + return this.printer.printNode(ts.EmitHint.Unspecified, node, this.sourceFile); } - createArgs(args: ts.NodeArray | undefined): ts.Expression[] | undefined { + private wrapPropertyAccessInBinaryExpr(variableName: string, wrappedNode: ts.Node): string { + const node = ts.factory.createBinaryExpression( + ts.factory.createIdentifier(variableName), + ts.SyntaxKind.EqualsToken, + wrappedNode as ts.Expression + ); + + return this.printer.printNode(ts.EmitHint.Unspecified, node, this.sourceFile); + } + + private createGetPropertyForIncrDecr(expression: string, name: string): ts.Node { void this; - if (args && args.length > 0) { - return args.map((arg) => { - return ts.factory.createCallExpression( + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(ES_OBJECT), - ts.factory.createIdentifier(WRAP) + ts.factory.createIdentifier(expression), + ts.factory.createIdentifier(GET_PROPERTY) ), undefined, - [ts.factory.createIdentifier(arg.getText())] - ); - }); - } - return undefined; + [ts.factory.createStringLiteral(name)] + ), + ts.factory.createIdentifier(TO_NUMBER) + ), + undefined, + [] + ); } - fixParameter(param: ts.ParameterDeclaration): Autofix[] { - const newParam = ts.factory.createParameterDeclaration( - param.modifiers, - param.dotDotDotToken, - param.name, - param.questionToken, - ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), - param.initializer + private createNewIncrDecrNodes(variableName: string, token: number): IncrementDecrementNodeInfo { + const update = ts.factory.createBinaryExpression( + ts.factory.createIdentifier(variableName), + ts.factory.createToken(token), + ts.factory.createNumericLiteral('1') ); - const text = this.printer.printNode(ts.EmitHint.Unspecified, newParam, param.getSourceFile()); - return [ - { - start: param.getStart(), - end: param.getEnd(), - replacementText: text - } - ]; + + const node = ts.factory.createBinaryExpression( + ts.factory.createIdentifier(variableName), + ts.factory.createToken(ts.SyntaxKind.EqualsToken), + update + ); + + return { + addOrDecrOperation: update, + varAssignText: this.printer.printNode(ts.EmitHint.Unspecified, node, this.sourceFile) + }; } - fixPropertyDeclaration(node: ts.PropertyDeclaration): Autofix[] | undefined { - const initializer = node.initializer; - if (initializer === undefined) { - return undefined; + private createSetProperty(expression: string, field: string, value: ts.Expression): string { + const node = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(expression), + ts.factory.createIdentifier(SET_PROPERTY) + ), + undefined, + [ts.factory.createIdentifier(field), value] + ); + + return this.printer.printNode(ts.EmitHint.Unspecified, node, this.sourceFile); + } + + fixNumericSemanticsForDeclaration( + node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration, + type: ts.Type + ): Autofix[] | undefined { + const typeNode = this.getTypeForNumericSemantics(type); + const text = ': ' + this.printer.printNode(ts.EmitHint.Unspecified, typeNode, node.getSourceFile()); + const pos = Autofixer.getDeclarationTypePosition(node); + return [{ start: pos, end: pos, replacementText: text }]; + } + + private getTypeForNumericSemantics(type: ts.Type): ts.TypeNode { + if (this.utils.isGenericArrayType(type)) { + return ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)); } - const propType = this.typeChecker.getTypeAtLocation(node); - let propTypeNode: ts.TypeNode; - if (propType.flags & ts.TypeFlags.NumberLike) { - propTypeNode = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + } + + /** + * 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 { - const inferredTypeNode = this.typeChecker.typeToTypeNode(propType, undefined, ts.NodeBuilderFlags.None); + return undefined; + } - if (!inferredTypeNode || !this.utils.isSupportedType(inferredTypeNode)) { - return undefined; + const replacementText = this.nonCommentPrinter.printNode( + ts.EmitHint.Unspecified, + replacement, + expression.getSourceFile() + ); + return [{ start: expression.getStart(), end: expression.getEnd(), replacementText }]; + } + + /** + * Convert a JS-imported `for...of` over an array into an indexed `for` loop. + * + * @param forOf - The `ForOfStatement` node to transform. + */ + applyForOfJsArrayFix(forOf: ts.ForOfStatement): Autofix[] | undefined { + const loopDecl = (forOf.initializer as ts.VariableDeclarationList).declarations[0]; + const elementName = (loopDecl.name as ts.Identifier).text; + + const indexName = TsUtils.generateUniqueName(this.tmpVariableNameGenerator, forOf.getSourceFile()) ?? '_i'; + + const fixes: Autofix[] = []; + fixes.push(this.buildForOfHeaderFix(forOf, indexName)); + fixes.push(...this.buildForOfBodyFixes(forOf, elementName, indexName)); + return fixes.length > 0 ? fixes : undefined; + } + + /** + * Build an Autofix for replacing the for-of loop header. + */ + private buildForOfHeaderFix(forOf: ts.ForOfStatement, indexName: string): Autofix { + const arrText = forOf.expression.getText(); + + const initializer = ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(indexName), + undefined, + undefined, + ts.factory.createNumericLiteral('0') + ) + ], + ts.NodeFlags.Let + ); + + // condition: i < arr.getProperty('length').toNumber() + const condition = ts.factory.createBinaryExpression( + ts.factory.createIdentifier(indexName), + ts.SyntaxKind.LessThanToken, + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(arrText), + ts.factory.createIdentifier(GET_PROPERTY) + ), + undefined, + [ts.factory.createStringLiteral(LENGTH, true)] + ), + ts.factory.createIdentifier('toNumber') + ), + undefined, + [] + ) + ); + + const incrementor = ts.factory.createPrefixUnaryExpression( + ts.SyntaxKind.PlusPlusToken, + ts.factory.createIdentifier(indexName) + ); + + return this.createReplacementTextForOfHeader(forOf, initializer, condition, incrementor); + } + + private createReplacementTextForOfHeader( + forOf: ts.ForOfStatement, + initializer: ts.VariableDeclarationList, + condition: ts.BinaryExpression, + incrementor: ts.PrefixUnaryExpression + ): Autofix { + // Render just the "(initializer; condition; incrementor)" text: + const replacementText = [ + this.printer.printNode(ts.EmitHint.Unspecified, initializer, forOf.getSourceFile()), + '; ', + this.printer.printNode(ts.EmitHint.Unspecified, condition, forOf.getSourceFile()), + '; ', + this.printer.printNode(ts.EmitHint.Unspecified, incrementor, forOf.getSourceFile()) + ].join(''); + + return { start: forOf.initializer.getStart(), end: forOf.expression.getEnd(), replacementText }; + } + + /** + * Build fixes for replacing loop-variable references inside the for-of body. + */ + private buildForOfBodyFixes(forOf: ts.ForOfStatement, elementName: string, indexName: string): Autofix[] { + const fixes: Autofix[] = []; + const arrExpr = forOf.expression; + + const visit = (node: ts.Node): void => { + if (ts.isIdentifier(node) && node.text === elementName) { + const callExpr = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(arrExpr.getText()), + ts.factory.createIdentifier(GET_PROPERTY) + ), + undefined, + [ts.factory.createIdentifier(indexName)] + ); + + // Print and append proper conversion suffix + const printed = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, forOf.getSourceFile()); + const replacementText = printed + this.utils.findTypeOfNodeForConversion(node); + + fixes.push({ start: node.getStart(), end: node.getEnd(), replacementText }); } - propTypeNode = inferredTypeNode; - } + ts.forEachChild(node, visit); + }; + + visit(forOf.statement); + return fixes; + } - const questionOrExclamationToken = node.questionToken ?? node.exclamationToken ?? undefined; - const newPropDecl = ts.factory.createPropertyDeclaration( - node.modifiers, - node.name, - questionOrExclamationToken, - propTypeNode, - initializer + 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 }]; + } - const text = this.printer.printNode(ts.EmitHint.Unspecified, newPropDecl, node.getSourceFile()); - return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + 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; } fixFunctionDeclarationly( @@ -3306,7 +3711,7 @@ export class Autofixer { fixInterfaceImport( interfacesNeedToImport: Set, interfacesAlreadyImported: Set, - sourceFile: ts.SourceFile + file: ts.SourceFile ): Autofix[] { const importSpecifiers: ts.ImportSpecifier[] = []; interfacesNeedToImport.forEach((interfaceName) => { @@ -3319,30 +3724,64 @@ export class Autofixer { const importDeclaration = ts.factory.createImportDeclaration( undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(importSpecifiers)), - ts.factory.createStringLiteral(ARKUI_PACKAGE_NAME, true), + ts.factory.createStringLiteral(ARKUI_MODULE, true), undefined ); - const leadingComments = ts.getLeadingCommentRanges(sourceFile.getFullText(), 0); + const leadingComments = ts.getLeadingCommentRanges(file.getFullText(), 0); let annotationEndLine = 0; let annotationEndPos = 0; if (leadingComments && leadingComments.length > 0) { annotationEndPos = leadingComments[leadingComments.length - 1].end; - annotationEndLine = sourceFile.getLineAndCharacterOfPosition(annotationEndPos).line; + annotationEndLine = file.getLineAndCharacterOfPosition(annotationEndPos).line; } - let text = this.printer.printNode(ts.EmitHint.Unspecified, importDeclaration, sourceFile); + const stmt = file?.statements[0]; + const isUseStaticAtStart = stmt ? Autofixer.checkUseStaticAtStart(stmt) : false; + annotationEndLine = isUseStaticAtStart ? file.getLineAndCharacterOfPosition(stmt.end).line : annotationEndLine; + annotationEndPos = isUseStaticAtStart ? stmt.end : annotationEndPos; + + let text = Autofixer.formatImportStatement( + this.printer.printNode(ts.EmitHint.Unspecified, importDeclaration, file) + ); if (annotationEndPos !== 0) { - text = this.getNewLine() + this.getNewLine() + text; + text = this.getNewLine() + (isUseStaticAtStart ? '' : this.getNewLine()) + text; } - const codeStartLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.getStart()).line; + const codeStartLine = isUseStaticAtStart ? + annotationEndLine + 1 : + file.getLineAndCharacterOfPosition(file.getStart()).line; for (let i = 2; i > codeStartLine - annotationEndLine; i--) { text = text + this.getNewLine(); } + return [{ start: annotationEndPos, end: annotationEndPos, replacementText: text }]; } + private static formatImportStatement(stmt: string): string { + return stmt.replace(/\{([^}]+)\}/, (match, importList) => { + const items = importList.split(',').map((item) => { + return item.trim(); + }); + + if (items.length > 1) { + const formattedList = items. + map((item) => { + return ` ${item.trim()},`; + }). + join('\n'); + return `{\n${formattedList}\n}`; + } + return `{${importList}}`; + }); + } + + private static checkUseStaticAtStart(stmt: ts.Statement): boolean { + return stmt.getText().trim(). + replace(/^'|'$/g, ''). + endsWith(USE_STATIC_STATEMENT); + } + fixStylesDecoratorGlobal( funcDecl: ts.FunctionDeclaration, calls: ts.Identifier[], @@ -3380,6 +3819,10 @@ export class Autofixer { const parameters: ts.MemberName[] = []; const values: ts.Expression[][] = []; const statements = block?.statements; + const type = ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier(CustomInterfaceName.CustomStyles), + undefined + ); Autofixer.getParamsAndValues(statements, parameters, values); const newBlock = Autofixer.createBlock(parameters, values, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); const parameDecl = ts.factory.createParameterDeclaration( @@ -3398,7 +3841,10 @@ export class Autofixer { ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), newBlock ); - const expr = ts.factory.createPropertyDeclaration(undefined, methodDecl.name, undefined, undefined, arrowFunc); + const newModifiers = ts.getModifiers(methodDecl)?.filter((modifier) => { + return !(ts.isDecorator(modifier) && TsUtils.getDecoratorName(modifier) === CustomInterfaceName.Styles); + }); + const expr = ts.factory.createPropertyDeclaration(newModifiers, methodDecl.name, undefined, type, arrowFunc); needImport.add(COMMON_METHOD_IDENTIFIER); let text = this.printer.printNode(ts.EmitHint.Unspecified, expr, methodDecl.getSourceFile()); const startPos = this.sourceFile.getLineAndCharacterOfPosition(methodDecl.getStart()).character; @@ -3535,7 +3981,7 @@ export class Autofixer { fixDataObservation(classDecls: ts.ClassDeclaration[]): Autofix[] | undefined { const autofixes: Autofix[] = []; classDecls.forEach((classDecl) => { - const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Observed)); + const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomInterfaceName.Observed)); const sourceFile = classDecl.getSourceFile(); const text = this.printer.printNode(ts.EmitHint.Unspecified, observedDecorator, sourceFile) + this.getNewLine(); const autofix = { start: classDecl.getStart(), end: classDecl.getStart(), replacementText: text }; @@ -3552,11 +3998,35 @@ export class Autofixer { void this; const base = lhs.expression.getText(); const prop = lhs.name.text; - const replacementText = `${base}.setPropertyByName('${prop}',ESObject.wrap(${rhs.getText()}))`; + const replacementText = `${base}.setProperty('${prop}',ESValue.wrap(${rhs.getText()}))`; return [{ start: binaryExpr.getStart(), end: binaryExpr.getEnd(), replacementText }]; } + /** + * Autofix for `foo instanceof Foo` → `foo.isInstanceOf(Foo)`. + * + * @param node The binary `instanceof` expression node. + * @returns A single Autofix replacing the entire `foo instanceof Foo` text. + */ + fixInteropJsInstanceOfExpression(node: ts.BinaryExpression): Autofix[] { + // left-hand and right-hand operands of the `instanceof` + const leftExpr = node.left; + const rightExpr = node.right; + + // build: leftExpr.isInstanceOf(rightExpr) + const callExpr = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(leftExpr, ts.factory.createIdentifier(IS_INSTANCE_OF)), + undefined, + [rightExpr] + ); + + // render back to source text + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, node.getSourceFile()); + + return [{ replacementText, start: node.getStart(), end: node.getEnd() }]; + } + createReplacementForJsIndirectImportPropertyAccessExpression(node: ts.PropertyAccessExpression): Autofix[] { // Bypass eslint-check void this; @@ -3566,7 +4036,7 @@ export class Autofixer { let start = node.getStart(); let end = node.getEnd(); - let replacementText = `${objName}.getPropertyByName('${propName}')`; + let replacementText = `${objName}.${GET_PROPERTY}('${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) { @@ -3585,78 +4055,141 @@ export class Autofixer { const start = node.getStart(); const end = node.getEnd(); - const replacement = `${objName}.getPropertyByName('${propName}')${this.utils.findTypeOfNodeForConversion(node)}`; + const typeTag = this.utils.findTypeOfNodeForConversion(node); + const replacement = `${objName}.${GET_PROPERTY}('${propName}')${typeTag}`; 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},` + - ` ESObject.wrap(${elementAccessExpr.parent.right.getText()}))` : - `${identifier.text}.getPropertyByIndex(${exprText})` + - this.utils.findTypeOfNodeForConversion(elementAccessExpr); - return [{ replacementText, start, end }]; - } + /** + * Converts a JS element access (e.g. `arr[index]`) into the corresponding + * interop call: + * - On assignment (`arr[index] = value`), emits `arr.setProperty(index, ESValue.wrap(value))` + * - On read, emits `arr.getProperty(index)` plus any type conversion suffix + * + * @param elementAccessExpr The original `ElementAccessExpression` node. + * @returns An array with a single `Autofix` describing the replacement range and text. + */ + fixJsImportElementAccessExpression(elementAccessExpr: ts.ElementAccessExpression): Autofix[] { + const parent = elementAccessExpr.parent; - fixSharedArrayBufferConstructor(node: ts.NewExpression): Autofix[] | undefined { - void this; + const isAssignment = + parent !== undefined && ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken; - // Ensure it's a constructor call to SharedArrayBuffer - if (!ts.isIdentifier(node.expression) || node.expression.text !== ESLIB_SHAREDARRAYBUFFER) { - return undefined; + // array identifier (e.g. "arr") + const identifierNode = elementAccessExpr.expression as ts.Identifier; + + let replacementText: string; + if (isAssignment) { + // arr.setProperty(index, ESValue.wrap(value)) + const wrapped = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(ES_VALUE), + ts.factory.createIdentifier(WRAP) + ), + undefined, + [parent.right] + ); + + const callExpr = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(identifierNode, ts.factory.createIdentifier(SET_PROPERTY)), + undefined, + [elementAccessExpr.argumentExpression, wrapped] + ); + + replacementText = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, elementAccessExpr.getSourceFile()); + } else { + // arr.getProperty(index) plus conversion + const callExpr = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(identifierNode, ts.factory.createIdentifier(GET_PROPERTY)), + undefined, + [elementAccessExpr.argumentExpression] + ); + + replacementText = + this.printer.printNode(ts.EmitHint.Unspecified, callExpr, elementAccessExpr.getSourceFile()) + + this.utils.findTypeOfNodeForConversion(elementAccessExpr); } - // Construct replacement - const replacementText = 'ArrayBuffer'; + const start = isAssignment ? (parent as ts.Node).getStart() : elementAccessExpr.getStart(); + const end = isAssignment ? (parent as ts.Node).getEnd() : elementAccessExpr.getEnd(); - return [{ replacementText, start: node.expression.getStart(), end: node.expression.getEnd() }]; + return [{ replacementText, start, end }]; } - fixSharedArrayBufferTypeReference(node: ts.TypeReferenceNode): Autofix[] | undefined { - void this; - - if (!ts.isIdentifier(node.typeName) || node.typeName.text !== ESLIB_SHAREDARRAYBUFFER) { + fixConcurrencyLock(locksProp: ts.PropertyAccessExpression): Autofix[] | undefined { + // 1) Ensure the next property is `.AsyncLock` + const asyncLockProp = locksProp.parent; + if (!ts.isPropertyAccessExpression(asyncLockProp)) { return undefined; } - const replacementText = 'ArrayBuffer'; + const className = asyncLockProp.name.getText(); - return [{ replacementText, start: node.getStart(), end: node.getEnd() }]; + // 2a) Handle static method calls on AsyncLock (e.g. AsyncLock.request, AsyncLock.acquire, etc.) + const methodProp = asyncLockProp.parent; + if (ts.isPropertyAccessExpression(methodProp)) { + const methodName = methodProp.name.getText(); + const callExpr = methodProp.parent; + if (!ts.isCallExpression(callExpr)) { + return undefined; + } + + const fixes: Autofix[] = []; + // Type fix for variable declaration, if necessary + const varDecl = Autofixer.findParentVariableDeclaration(callExpr); + const typeFix = varDecl ? this.buildConcurrencyLockTypeFix(varDecl, className) : undefined; + if (typeFix) { + fixes.push(typeFix); + } + + // build AsyncLock.(...) + const fixCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(className), + ts.factory.createIdentifier(methodName) + ), + undefined, + callExpr.arguments + ); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, fixCall, callExpr.getSourceFile()); + fixes.push({ start: callExpr.getStart(), end: callExpr.getEnd(), replacementText }); + return fixes; + } + + // 2b) Handle `new ArkTSUtils.locks.AsyncLock()` + const newExpr = asyncLockProp.parent; + if (!ts.isNewExpression(newExpr)) { + return undefined; + } + // build `new AsyncLock()` + const replacement = ts.factory.createNewExpression(ts.factory.createIdentifier(className), undefined, []); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, replacement, newExpr.getSourceFile()); + return [{ start: newExpr.getStart(), end: newExpr.getEnd(), replacementText }]; } - fixAppStorageCallExpression(callExpr: ts.CallExpression): Autofix[] | undefined { - const varDecl = Autofixer.findParentVariableDeclaration(callExpr); - if (!varDecl || varDecl.type) { + /** + * If the variable declaration has a qualified type `*.locks.ClassName`, build a fix to simplify it to `ClassName`. + */ + private buildConcurrencyLockTypeFix(varDecl: ts.VariableDeclaration, className: string): Autofix | undefined { + const typeNode = varDecl.type; + + if (!typeNode || !ts.isTypeReferenceNode(typeNode) || !ts.isQualifiedName(typeNode.typeName)) { return undefined; } - const updatedVarDecl = ts.factory.updateVariableDeclaration( - varDecl, - varDecl.name, - undefined, - ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), - varDecl.initializer - ); + const qn = typeNode.typeName; + const left = qn.left; + const right = qn.right; - const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, updatedVarDecl, varDecl.getSourceFile()); + // ensure it's of form *.locks.ClassName + if (ts.isQualifiedName(left) && left.right.text === ARKTSUTILS_LOCKS_MEMBER && right.text === className) { + const simple = ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(className), undefined); + const text = this.printer.printNode(ts.EmitHint.Unspecified, simple, varDecl.getSourceFile()); + return { start: typeNode.getStart(), end: typeNode.getEnd(), replacementText: text }; + } - return [ - { - replacementText, - start: varDecl.getStart(), - end: varDecl.getEnd() - } - ]; + return undefined; } private static findParentVariableDeclaration(node: ts.Node): ts.VariableDeclaration | undefined { @@ -3669,166 +4202,65 @@ export class Autofixer { 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 `ESObject.wrap(${arg.getText()})`; - }). - join(', '); + fixAppStorageCallExpression(varDecl: ts.VariableDeclaration): Autofix[] | undefined { + const typeNode = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + const text = ': ' + this.printer.printNode(ts.EmitHint.Unspecified, typeNode, varDecl.getSourceFile()); + const pos = Autofixer.getDeclarationTypePosition(varDecl); + return [{ start: pos, end: pos, replacementText: text }]; } - private fixInterOpImportJsProcessNode(node: ts.Node): string { + private fixInterOpImportJsProcessNode(node: ts.Node): string | undefined { 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})`; + const newArgs = this.createArgs(node.arguments); + const callee = node.expression; + switch (callee.kind) { + case ts.SyntaxKind.PropertyAccessExpression: { + const propertyAccessExpr = node.expression as ts.PropertyAccessExpression; + const newCallExpr = this.createJSInvokeCallExpression(propertyAccessExpr.expression, INVOKE_METHOD, [ + ts.factory.createStringLiteral(propertyAccessExpr.name.text), + ...newArgs || [] + ]); + + if (!newCallExpr) { + return undefined; + } + return this.printer.printNode(ts.EmitHint.Unspecified, newCallExpr, node.getSourceFile()); + } + default: { + const callExpr = this.createJSInvokeCallExpression(node.expression, INVOKE, [...newArgs || []]); + + if (!callExpr) { + return undefined; + } + + return this.printer.printNode(ts.EmitHint.Unspecified, callExpr, node.getSourceFile()); + } + } } else if (ts.isPropertyAccessExpression(node)) { const base = this.fixInterOpImportJsProcessNode(node.expression); + if (!base) { + return undefined; + } const propName = node.name.text; - return `${base}.getPropertyByName('${propName}')`; + return `${base}.${GET_PROPERTY}('${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_OBJECT, 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; - } + const newArgs = this.createArgs(node.arguments); + const newCallExpr = this.createJSInvokeCallExpression(node.expression, INSTANTIATE, [...newArgs || []]); - private getLastImportEnd(): number { - let lastImportEnd = 0; - this.sourceFile.statements.forEach((statement) => { - if (ts.isImportDeclaration(statement)) { - lastImportEnd = statement.getEnd(); + if (!newCallExpr) { + return undefined; } - }); - return lastImportEnd; + return this.printer.printNode(ts.EmitHint.Unspecified, newCallExpr, node.getSourceFile()); + } + return undefined; } 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)), + ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY)), undefined, [ts.factory.createStringLiteral(express.name.getText())] ); @@ -3850,14 +4282,14 @@ export class Autofixer { const statements = ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( ts.factory.createIdentifier(objectName), - ts.factory.createIdentifier(SET_PROPERTY_BY_NAME) + ts.factory.createIdentifier(SET_PROPERTY) ), undefined, [ ts.factory.createStringLiteral(propertyName), ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(ES_OBJECT), + ts.factory.createIdentifier(ES_VALUE), ts.factory.createIdentifier(WRAP) ), undefined, @@ -3869,30 +4301,129 @@ export class Autofixer { return [{ start: express.getStart(), end: express.getEnd(), replacementText: replacementText }]; } - fixInteropArrayElementAccessExpression(express: ts.ElementAccessExpression): Autofix[] | undefined { - const statements = ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY_BY_INDEX)), + 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)), undefined, - [express.argumentExpression] + [ts.factory.createStringLiteral(express.name.getText())] ); - 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) - ), + 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 + } + ]; + } + + fixInteropOperators(expr: ts.Expression): Autofix[] | undefined { + if (ts.isPropertyAccessExpression(expr)) { + return this.fixPropertyAccessToNumber(expr); + } + + if (ts.isIdentifier(expr)) { + const symbol = this.utils.trueSymbolAtLocation(expr); + + if (this.utils.isJsImport(expr)) { + const toNumberCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(expr, ts.factory.createIdentifier(TO_NUMBER)), + undefined, + [] + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, toNumberCall, expr.getSourceFile()); + + return [ + { + start: expr.getStart(), + end: expr.getEnd(), + replacementText + } + ]; + } + + const decl = symbol?.declarations?.find(ts.isVariableDeclaration); + if (decl?.initializer && ts.isPropertyAccessExpression(decl.initializer)) { + return this.fixPropertyAccessToNumber(decl.initializer); + } + } + + return undefined; + } + + private fixPropertyAccessToNumber(expr: ts.PropertyAccessExpression): Autofix[] { + const getPropCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(expr.expression, ts.factory.createIdentifier(GET_PROPERTY)), + undefined, + [ts.factory.createStringLiteral(expr.name.getText())] + ); + + const toNumberCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(getPropCall, ts.factory.createIdentifier(TO_NUMBER)), + undefined, + [] + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, toNumberCall, expr.getSourceFile()); + + return [ + { + start: expr.getStart(), + end: expr.getEnd(), + replacementText + } + ]; + } + + fixInteropArrayElementAccessExpression(express: ts.ElementAccessExpression): Autofix[] | undefined { + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY)), + 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) + ), undefined, [ left.argumentExpression, ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(ES_OBJECT), + ts.factory.createIdentifier(ES_VALUE), ts.factory.createIdentifier(WRAP) ), undefined, @@ -3909,8 +4440,11 @@ export class Autofixer { const start = typeofExpress.getStart(); const end = typeofExpress.getEnd(); const processed = this.fixInterOpImportJsProcessNode(node); + if (!processed) { + return undefined; + } const replacementText = `${processed}.typeOf()`; - return replacementText ? [{ start, end, replacementText }] : undefined; + return [{ start, end, replacementText }]; } fixInteropInterfaceConvertNum(express: ts.PrefixUnaryExpression): Autofix[] | undefined { @@ -3918,7 +4452,7 @@ export class Autofixer { const getPropertyCall = ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( ts.factory.createIdentifier(propertyAccess.expression.getText()), - ts.factory.createIdentifier(GET_PROPERTY_BY_NAME) + ts.factory.createIdentifier(GET_PROPERTY) ), undefined, [ts.factory.createStringLiteral(propertyAccess.name.getText())] @@ -3953,16 +4487,8 @@ export class Autofixer { } fixImportClause(tsImportClause: ts.ImportClause): Autofix[] { - const newImportClause = ts.factory.createImportClause( - tsImportClause.isTypeOnly, - tsImportClause.name, - tsImportClause.namedBindings - ); - const replacementText = this.printer.printNode( - ts.EmitHint.Unspecified, - newImportClause, - tsImportClause.getSourceFile() - ); + void this; + const replacementText = tsImportClause.getText().replace(/\blazy\b\s*/, ''); return [{ start: tsImportClause.getStart(), end: tsImportClause.getEnd(), replacementText }]; } @@ -3977,6 +4503,21 @@ export class Autofixer { return undefined; } + createInteropPropertyAccess(exp: ts.Expression): string { + let text: string; + if (!ts.isPropertyAccessExpression(exp)) { + text = exp.getText(); + return text; + } + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(exp.expression, ts.factory.createIdentifier(GET_PROPERTY)), + undefined, + [ts.factory.createStringLiteral(exp.name.getText())] + ); + text = this.printer.printNode(ts.EmitHint.Unspecified, statements, exp.getSourceFile()); + return text; + } + replaceInteropEqualityOperator( tsBinaryExpr: ts.BinaryExpression, binaryOperator: ts.BinaryOperator @@ -3987,14 +4528,20 @@ export class Autofixer { } const tsLhsExpr = tsBinaryExpr.left; + const left = this.createInteropPropertyAccess(tsLhsExpr); const tsRhsExpr = tsBinaryExpr.right; + const right = this.createInteropPropertyAccess(tsRhsExpr); + if (!left || !right) { + return undefined; + } + const callExpression = ts.factory.createCallExpression( ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(tsLhsExpr.getText()), + ts.factory.createIdentifier(left), ts.factory.createIdentifier(info.functionName) ), undefined, - [ts.factory.createIdentifier(tsRhsExpr.getText())] + [ts.factory.createIdentifier(right)] ); let text = this.printer.printNode(ts.EmitHint.Unspecified, callExpression, tsBinaryExpr.getSourceFile()); @@ -4042,139 +4589,24 @@ export class Autofixer { return [{ start: argExpr.getStart(), end: argExpr.getEnd(), replacementText: `${argExpr.getText()} as int` }]; } - fixNoTsLikeFunctionCall(identifier: ts.Node): Autofix[] { + fixNoTsLikeFunctionCall(callExpr: ts.CallExpression): Autofix[] { void this; - const funcName = identifier.getText(); - const replacementText = `${funcName}.unSafeCall`; - return [ - { - replacementText, - start: identifier.getStart(), - end: identifier.getEnd() - } - ]; - } + const expr = callExpr.expression; + const hasOptionalChain = !!callExpr.questionDotToken; - fixStaticPropertyInitializer(propDecl: ts.PropertyDeclaration): Autofix[] | undefined { - const srcFile = propDecl.getSourceFile(); - const startPos = srcFile.getLineAndCharacterOfPosition(propDecl.getStart()).character; - - const newPropDecl = Autofixer.createUltimateFixedProperty(propDecl); - if (!newPropDecl) { - return undefined; - } - let text = this.printer.printNode(ts.EmitHint.Unspecified, newPropDecl, srcFile); - text = this.adjustIndentation(text, startPos); + const replacementText = hasOptionalChain ? + `${expr.getText()}${callExpr.questionDotToken.getText()}unsafeCall` : + `${expr.getText()}.unsafeCall`; return [ { - start: propDecl.getStart(), - end: propDecl.getEnd(), - replacementText: text + start: expr.getStart(), + end: hasOptionalChain ? callExpr.questionDotToken.getEnd() : expr.getEnd(), + replacementText } ]; } - private static createUltimateFixedProperty(propDecl: ts.PropertyDeclaration): ts.PropertyDeclaration | undefined { - const type = propDecl.type; - - if (!type) { - return undefined; - } - - switch (type.kind) { - case ts.SyntaxKind.TypeLiteral: - return Autofixer.handleTypeLiteralProperty(propDecl, type as ts.TypeLiteralNode); - case ts.SyntaxKind.TypeReference: - return Autofixer.handleTypeReferenceProperty(propDecl, type as ts.TypeReferenceNode); - case ts.SyntaxKind.ArrayType: - return Autofixer.handleArrayTypeProperty(propDecl, type as ts.ArrayTypeNode); - case ts.SyntaxKind.StringKeyword: - return Autofixer.handleStringProperty(propDecl, type); - default: - return undefined; - } - } - - private static handleTypeLiteralProperty( - propDecl: ts.PropertyDeclaration, - type: ts.TypeLiteralNode - ): ts.PropertyDeclaration { - return ts.factory.updatePropertyDeclaration( - propDecl, - propDecl.modifiers, - propDecl.name, - propDecl.questionToken, - type, - Autofixer.createExactObjectInitializer(type) - ); - } - - private static handleTypeReferenceProperty( - propDecl: ts.PropertyDeclaration, - type: ts.TypeReferenceNode - ): ts.PropertyDeclaration | undefined { - if (Autofixer.isUserDefinedClass(type)) { - return Autofixer.handleCustomClassProperty(propDecl, type); - } - const newInit = Autofixer.createBuiltInTypeInitializer(type); - if (!newInit) { - return undefined; - } - return ts.factory.updatePropertyDeclaration( - propDecl, - propDecl.modifiers, - propDecl.name, - propDecl.questionToken, - type, - newInit - ); - } - - private static handleCustomClassProperty( - propDecl: ts.PropertyDeclaration, - type: ts.TypeReferenceNode - ): ts.PropertyDeclaration | undefined { - const nullableType = ts.factory.createUnionTypeNode([ - type, - ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword) - ]); - - return ts.factory.updatePropertyDeclaration( - propDecl, - propDecl.modifiers, - propDecl.name, - undefined, - nullableType, - ts.factory.createIdentifier('undefined') - ); - } - - private static handleArrayTypeProperty( - propDecl: ts.PropertyDeclaration, - type: ts.ArrayTypeNode - ): ts.PropertyDeclaration { - return ts.factory.updatePropertyDeclaration( - propDecl, - propDecl.modifiers, - propDecl.name, - propDecl.questionToken, - type, - ts.factory.createArrayLiteralExpression([], false) - ); - } - - private static handleStringProperty(propDecl: ts.PropertyDeclaration, type: ts.TypeNode): ts.PropertyDeclaration { - return ts.factory.updatePropertyDeclaration( - propDecl, - propDecl.modifiers, - propDecl.name, - propDecl.questionToken, - type, - ts.factory.createStringLiteral('') - ); - } - private static createBuiltInTypeInitializer(type: ts.TypeReferenceNode): ts.Expression | undefined { const typeName = type.typeName.getText(); @@ -4252,25 +4684,407 @@ export class Autofixer { return !builtInTypes.has(type.typeName.getText()); } - fixGenericCallNoTypeArgs(node: ts.NewExpression): Autofix[] | undefined { + /** + * Fixes function declarations/expressions that return `void` as part of a union. + * Replaces `void` with `undefined` in the return type, + * replaces `return;` with `return undefined;`, + * and adds `return undefined;` if the function has no returns. + */ + fixLimitedVoidTypeFunction(fn: ts.FunctionLikeDeclaration): Autofix[] | undefined { + const fixes: Autofix[] = []; + const returnType = fn.type; + if (!returnType || !ts.isUnionTypeNode(returnType) || !TsUtils.typeContainsVoid(returnType)) { + return undefined; + } + + const updatedTypes = returnType.types.map((t) => { + return t.kind === ts.SyntaxKind.VoidKeyword ? ts.factory.createTypeReferenceNode(UNDEFINED_NAME) : t; + }); + + const newType = ts.factory.createUnionTypeNode(updatedTypes); + fixes.push({ + start: returnType.getStart(), + end: returnType.getEnd(), + replacementText: this.printer.printNode(ts.EmitHint.Unspecified, newType, fn.getSourceFile()) + }); + + let hasReturn = false; + function visit(node: ts.Node): void { + if (ts.isReturnStatement(node)) { + hasReturn = true; + if (!node.expression) { + fixes.push({ + start: node.getStart(), + end: node.getEnd(), + replacementText: 'return undefined;' + }); + } + } + ts.forEachChild(node, visit); + } + if (fn.body) { + visit(fn.body); + if (ts.isBlock(fn.body)) { + const statements = fn.body.statements; + const lastExpr = statements.length > 0 ? statements[statements.length - 1] : undefined; + if (hasReturn && lastExpr && !ts.isReturnStatement(lastExpr) || !hasReturn) { + const text = this.createUndefinedReturnStatement(fn, lastExpr); + fixes.push({ + start: lastExpr ? lastExpr.getEnd() : fn.body.getEnd() - 1, + end: lastExpr ? lastExpr.getEnd() : fn.body.getEnd() - 1, + replacementText: text + }); + } + } + } + return fixes; + } + + private createUndefinedReturnStatement(fn: ts.FunctionLikeDeclaration, lastExpr: ts.Statement | undefined): string { + const returnStatement = ts.factory.createReturnStatement(ts.factory.createIdentifier(UNDEFINED_NAME)); + if (lastExpr) { + const startPos = lastExpr.getStart(); + const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(startPos); + const indent = lineAndCharacter.character; + return ( + this.getNewLine() + + ' '.repeat(indent) + + this.printer.printNode(ts.EmitHint.Unspecified, returnStatement, fn.getSourceFile()) + ); + } + const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(fn.getStart()); + const indent = lineAndCharacter.character + INDENT_STEP; + return ( + this.getNewLine() + + ' '.repeat(indent) + + this.printer.printNode(ts.EmitHint.Unspecified, returnStatement, fn.getSourceFile()) + + this.getNewLine() + + ' '.repeat(lineAndCharacter.character) + ); + } + + private fixGenericCallNoTypeArgsWithContextualType( + node: ts.NewExpression | ts.CallExpression + ): Autofix[] | undefined { + const contextualType = this.typeChecker.getContextualType(node); + if (!contextualType) { + return undefined; + } + + const typeArgs = this.getTypeArgumentsFromType(contextualType); + if (typeArgs.length === 0) { + return undefined; + } + const reference = typeArgs.map((arg) => { + return ts.factory.createTypeReferenceNode(this.typeChecker.typeToString(arg)); + }); + return this.generateGenericTypeArgumentsAutofix(node, reference); + } + + fixGenericCallNoTypeArgs(node: ts.NewExpression | ts.CallExpression): Autofix[] | undefined { const typeNode = this.getTypeNodeForNewExpression(node); - if (!typeNode || !ts.isTypeReferenceNode(typeNode) || typeNode.typeName.getText() !== node.expression.getText()) { + if (!typeNode) { + return this.fixGenericCallNoTypeArgsWithContextualType(node); + } + let nodeExpressionText = node.expression.getText(); + if (ts.isCallExpression(node)) { + const returnTypeText = this.getReturnTypeFromMethodDeclaration(node); + if (!returnTypeText) { + return undefined; + } + nodeExpressionText = returnTypeText; + } + if (ts.isUnionTypeNode(typeNode)) { + return this.fixGenericCallNoTypeArgsForUnionType(node, typeNode, nodeExpressionText); + } + if (ts.isArrayTypeNode(typeNode)) { + return this.fixGenericCallNoTypeArgsForArrayType(node, typeNode); + } + if (!ts.isTypeReferenceNode(typeNode) || typeNode.typeName.getText() !== nodeExpressionText) { + return undefined; + } + + const srcFile = node.getSourceFile(); + const typeArgsText = this.printGenericCallTypeArgs(srcFile, typeNode.typeArguments); + if (!typeArgsText) { + return undefined; + } + const insertPos = node.expression.getEnd(); + return [{ start: insertPos, end: insertPos, replacementText: typeArgsText }]; + } + + fixGenericCallNoTypeArgsForUnknown(node: ts.CallExpression): Autofix[] | undefined { + if (ts.isPropertyAccessExpression(node.parent)) { + const insertPos = node.expression.getEnd(); + return [{ start: insertPos, end: insertPos, replacementText: '' }]; + } + + const typeNode = this.getTypeNodeForNewExpression(node); + if (!typeNode) { return undefined; } - const reference: ts.TypeReferenceNode[] = []; - typeNode.typeArguments?.forEach((arg) => { - return reference.push(ts.factory.createTypeReferenceNode(arg.getText())); + const nodeExpressionText = ts.isVariableDeclaration(node.parent) ? + this.getReturnTypeFromMethodDeclaration(node) ?? node.expression.getText() : + node.expression.getText(); + + if (ts.isUnionTypeNode(typeNode)) { + const targetTypeRef = typeNode.types.find((t): t is ts.TypeReferenceNode => { + return ts.isTypeReferenceNode(t) && t.typeName.getText() === nodeExpressionText; + }); + if (!targetTypeRef) { + return undefined; + } + return this.createFixWithTypeArgs(node, targetTypeRef.typeArguments); + } + + if (ts.isTypeReferenceNode(typeNode) && typeNode.typeName.getText() === nodeExpressionText) { + return this.createFixWithTypeArgs(node, typeNode.typeArguments); + } + + return undefined; + } + + private createFixWithTypeArgs( + node: ts.CallExpression, + typeArguments: ts.NodeArray | undefined + ): Autofix[] | undefined { + const typeArgsText = this.printGenericCallTypeArgs(node.getSourceFile(), typeArguments); + return typeArgsText ? + [ + { + start: node.expression.getEnd(), + end: node.expression.getEnd(), + replacementText: typeArgsText + } + ] : + undefined; + } + + getReturnTypeFromMethodDeclaration(node: ts.CallExpression): string | undefined { + if (ts.isPropertyAccessExpression(node.expression)) { + const propertyAccess = node.expression; + const methodName = propertyAccess.name.text; + const receiver = propertyAccess.expression; + const receiverType = this.typeChecker.getTypeAtLocation(receiver); + const methodSymbol = this.typeChecker.getPropertyOfType(receiverType, methodName); + + if (!methodSymbol) { + return undefined; + } + const methodDecl = methodSymbol.declarations?.[0] as ts.MethodSignature; + if (!methodDecl.type || !ts.isTypeReferenceNode(methodDecl.type) && !ts.isUnionTypeNode(methodDecl.type)) { + return undefined; + } + if (ts.isTypeReferenceNode(methodDecl.type)) { + return methodDecl.type.typeName.getText(); + } + if (ts.isUnionTypeNode(methodDecl.type)) { + const typeNode = this.getTypeNodeForNewExpression(node); + if (!typeNode) { + return undefined; + } + const targetTypeName = this.getTargetTypeName(typeNode, methodDecl.type); + + if (ts.isUnionTypeNode(typeNode)) { + return targetTypeName; + } + const targetTypeNode = methodDecl.type.types.find((type) => { + return ts.isTypeReferenceNode(type) && type.typeName.getText() === targetTypeName; + }) as ts.TypeReferenceNode; + if (!targetTypeNode) { + return undefined; + } + return targetTypeNode.typeName.getText(); + } + } + return undefined; + } + + private getTargetTypeName(typeNode: ts.TypeNode, methodDeclType: ts.UnionTypeNode): string | undefined { + if (ts.isTypeReferenceNode(typeNode)) { + return typeNode.typeName.getText(); + } + + if (!ts.isUnionTypeNode(typeNode)) { + return undefined; + } + + const hasGenericType = methodDeclType.types.some((type) => { + return this.isGenericTypeParameter(type); + }); + const typeNames = new Set(typeNode.types.map(Autofixer.getTypeName).filter(Boolean)); + + const candidateNames = hasGenericType ? + typeNode.types.map(Autofixer.getTypeName) : + methodDeclType.types.map(Autofixer.getTypeName); + const targetTypeName = candidateNames.find((name) => { + return name && name !== 'undefined' && (hasGenericType || typeNames.has(name)); }); + return targetTypeName; + } + + private isGenericTypeParameter(type: ts.TypeNode): boolean { + const getType = this.typeChecker.getTypeFromTypeNode(type); + return getType.isTypeParameter(); + } + + private static getTypeName(type: ts.TypeNode): string { + if (ts.isTypeReferenceNode(type)) { + return type.typeName.getText(); + } + if (ts.isLiteralTypeNode(type)) { + return type.literal.getText(); + } + const typeNameMap = { + [ts.SyntaxKind.StringKeyword]: 'string', + [ts.SyntaxKind.NumberKeyword]: 'number', + [ts.SyntaxKind.BooleanKeyword]: 'boolean', + [ts.SyntaxKind.UndefinedKeyword]: 'undefined', + [ts.SyntaxKind.NullKeyword]: 'null' + }; + return typeNameMap[type.kind] || ''; + } + + private fixGenericCallNoTypeArgsForArrayType( + node: ts.NewExpression | ts.CallExpression, + arrayTypeNode: ts.ArrayTypeNode + ): Autofix[] | undefined { + const elementTypeNode = arrayTypeNode.elementType; + const srcFile = node.getSourceFile(); + const typeArgsText = this.printGenericCallTypeArgs(srcFile, elementTypeNode); + if (!typeArgsText) { + return undefined; + } + const insertPos = node.expression.getEnd(); + return [{ start: insertPos, end: insertPos, replacementText: typeArgsText }]; + } + + private fixGenericCallNoTypeArgsForUnionType( + node: ts.NewExpression | ts.CallExpression, + unionType: ts.UnionTypeNode, + nodeExpressionText: string + ): Autofix[] | undefined { + const matchingTypes = unionType.types.filter((type) => { + return Autofixer.getTypeName(type) === nodeExpressionText; + }); + + if (matchingTypes.length === 1) { + const matchingType = matchingTypes[0]; + if (ts.isTypeReferenceNode(matchingType)) { + if (matchingType.typeArguments) { + const srcFile = node.getSourceFile(); + const typeArgsText = this.printGenericCallTypeArgs(srcFile, matchingType.typeArguments); + if (!typeArgsText) { + return undefined; + } + const insertPos = node.expression.getEnd(); + return [{ start: insertPos, end: insertPos, replacementText: typeArgsText }]; + } + } else { + const insertPos = node.expression.getEnd(); + return [{ start: insertPos, end: insertPos, replacementText: `<${nodeExpressionText}>` }]; + } + } + return undefined; + } + + private printGenericCallTypeArgs( + sourceFile: ts.SourceFile, + typeArg: ts.TypeNode | readonly ts.Node[] | undefined + ): string | undefined { + if (Array.isArray(typeArg)) { + if ( + typeArg.some((arg) => { + return !this.isTypeArgumentAccessible(sourceFile, arg as ts.TypeNode); + }) + ) { + return undefined; + } + return `<${typeArg. + map((arg) => { + ts.setEmitFlags(arg, ts.EmitFlags.SingleLine); + return this.nonCommentPrinter.printNode(ts.EmitHint.Unspecified, arg, sourceFile); + }). + join(', ')}>`; + } + if (!typeArg || !this.isTypeArgumentAccessible(sourceFile, typeArg as ts.TypeNode)) { + return undefined; + } + ts.setEmitFlags(typeArg as ts.TypeNode, ts.EmitFlags.SingleLine); + return `<${this.nonCommentPrinter.printNode(ts.EmitHint.Unspecified, typeArg as ts.TypeNode, sourceFile)}>`; + } + + private isTypeArgumentAccessible(sourceFile: ts.SourceFile, arg: ts.TypeNode): boolean { + const type = this.typeChecker.getTypeFromTypeNode(arg); + const symbol = type.symbol || type.aliasSymbol; + const decl = TsUtils.getDeclaration(symbol); + const fileName = decl?.getSourceFile().fileName; + const isStdLib = isStdLibrarySymbol(symbol); + const isMatchPathOnSourceAndDecl = decl && path.normalize(sourceFile.fileName) === path.normalize(fileName!); + if (!decl || isMatchPathOnSourceAndDecl || isStdLib) { + return true; + } + let result = false; + ts.forEachChild(sourceFile, (node) => { + if (ts.isImportDeclaration(node)) { + if (node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) { + node.importClause.namedBindings.elements.some((element) => { + result = this.isTypeArgImport(arg, element.name, symbol); + return result; + }); + } + if (node.importClause?.name) { + result = this.isTypeArgImport(arg, node.importClause.name, symbol); + } + } + return result; + }); + return result; + } + + private isTypeArgImport(arg: ts.Node, importName: ts.Identifier, typeArgSym: ts.Symbol): boolean { + if (arg.getText() !== importName.text) { + return false; + } + const importSym = this.utils.trueSymbolAtLocation(importName); + return importSym === typeArgSym; + } + + private generateGenericTypeArgumentsAutofix( + node: ts.NewExpression | ts.CallExpression, + typeArgs: ts.TypeReferenceNode[] + ): Autofix[] | undefined { 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 }]; + const hasValidArgs = typeArgs.some((arg) => { + return arg?.typeName && ts.isIdentifier(arg.typeName); + }); + if (!hasValidArgs) { + return undefined; + } + const hasAnyType = typeArgs.some((arg) => { + return ts.isIdentifier(arg?.typeName) && arg.typeName.text === 'any'; + }); + if (hasAnyType) { + return undefined; + } + const typeArgsText = this.printGenericCallTypeArgs(srcFile, typeArgs); + if (!typeArgsText) { + return undefined; + } + return [{ start: identifier.getEnd(), end: identifier.getEnd(), replacementText: typeArgsText }]; + } + + private getTypeArgumentsFromType(type: ts.Type): ts.Type[] { + const typeReference = this.utils.getNonNullableType(type) as ts.TypeReference; + if (typeReference.typeArguments) { + return [...typeReference.typeArguments]; + } + return []; } - private getTypeNodeForNewExpression(node: ts.NewExpression): ts.TypeNode | undefined { + private getTypeNodeForNewExpression(node: ts.NewExpression | ts.CallExpression): ts.TypeNode | undefined { if (ts.isVariableDeclaration(node.parent) || ts.isPropertyDeclaration(node.parent)) { return node.parent.type; } else if (ts.isBinaryExpression(node.parent)) { @@ -4293,6 +5107,80 @@ export class Autofixer { return undefined; } + private createJSInvokeCallExpression( + ident: ts.Expression, + method: string, + args: ts.Expression[] | undefined + ): ts.CallExpression | undefined { + if (ts.isNewExpression(ident)) { + const instantiatedClass = this.createJSInvokeCallExpression( + ident.expression, + INSTANTIATE, + this.createArgs(ident.arguments) + ); + if (!instantiatedClass) { + return undefined; + } + return this.createJSInvokeCallExpression(instantiatedClass, method, args); + } + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(ident, ts.factory.createIdentifier(method)), + undefined, + args + ); + } + + fixAwaitJsCallExpression(ident: ts.Identifier, args: ts.NodeArray | undefined): Autofix[] | undefined { + const newArgs = this.createArgs(args); + + const newCallExpr = this.createJSInvokeCallExpression(ident, INVOKE, newArgs); + if (!newCallExpr) { + return undefined; + } + + const replacedNode = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(newCallExpr, ts.factory.createIdentifier(TO_PROMISE)), + undefined, + undefined + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, replacedNode, ident.getSourceFile()); + return [{ start: ident.parent.getStart(), end: ident.parent.getEnd(), replacementText }]; + } + + fixAwaitJsMethodCallExpression( + ident: ts.Identifier, + args: ts.NodeArray | undefined + ): Autofix[] | undefined { + const propertyAccessExpr = ident.parent as ts.PropertyAccessExpression; + const accessedProperty = propertyAccessExpr.expression; + const newArgs = this.createArgs(args); + + const newCallExpr = this.createJSInvokeCallExpression(accessedProperty, INVOKE_METHOD, [ + ts.factory.createStringLiteral(ident.text), + ...newArgs || [] + ]); + + if (!newCallExpr) { + return undefined; + } + + const replacedNode = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(newCallExpr, ts.factory.createIdentifier(TO_PROMISE)), + undefined, + undefined + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, replacedNode, ident.getSourceFile()); + return [{ start: propertyAccessExpr.parent.getStart(), end: propertyAccessExpr.parent.getEnd(), replacementText }]; + } + + fixAwaitJsPromise(ident: ts.Identifier): Autofix[] { + void this; + const replacementText = `${ident.text}.toPromise()`; + return [{ start: ident.getStart(), end: ident.getEnd(), replacementText }]; + } + fixMissingAttribute(node: ts.PropertyAccessExpression): Autofix[] { const exprName = node.expression.getText(); const propertyAccessExpr = ts.factory.createPropertyAccessExpression( @@ -4311,7 +5199,7 @@ export class Autofixer { fixCustomLayout(node: ts.StructDeclaration): Autofix[] { const startPos = Autofixer.getStartPositionWithoutDecorators(node); - const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Layoutable)); + const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomInterfaceName.CustomLayout)); const text = this.getNewLine() + this.printer.printNode(ts.EmitHint.Unspecified, decorator, node.getSourceFile()); return [{ start: startPos, end: startPos, replacementText: text }]; @@ -4325,4 +5213,219 @@ export class Autofixer { return decorators[decorators.length - 1].getEnd(); } + + fixNumericLiteralIntToNumber(node: ts.NumericLiteral): Autofix[] | undefined { + void this; + let replacementText = node.getText(); + const parent = node.parent; + + if (ts.isPrefixUnaryExpression(parent) && parent.operator === ts.SyntaxKind.MinusToken) { + replacementText = `-${replacementText}.0`; + return [ + { + start: parent.getStart(), + end: node.getEnd(), + replacementText + } + ]; + } + + return [ + { + start: node.getStart(), + end: node.getEnd(), + replacementText: `${replacementText}.0` + } + ]; + } + + fixPropDecorator(node: ts.Identifier, decoratorName: string): Autofix[] { + const newDecorator = ts.factory.createIdentifier(decoratorName + NEW_PROP_DECORATOR_SUFFIX); + + const text = this.printer.printNode(ts.EmitHint.Unspecified, newDecorator, node.getSourceFile()); + return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + } + + importBitVector(node: ts.Node, lastImportDeclaration: ts.Node | undefined): Autofix | undefined { + const importDeclaration = ts.factory.createImportDeclaration( + undefined, + ts.factory.createImportClause( + false, + undefined, + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(BIT_VECTOR)) + ]) + ), + ts.factory.createStringLiteral(ARKTS_COLLECTIONS_MODULE), + undefined + ); + // find the last import statement; + + let replacementText: string = this.nonCommentPrinter.printNode( + ts.EmitHint.Unspecified, + importDeclaration, + node.getSourceFile() + ); + let start: number = 0; + let end: number = 0; + + if (lastImportDeclaration) { + start = end = lastImportDeclaration.getEnd(); + replacementText = this.getNewLine() + replacementText + this.getNewLine(); + } + + return { start, end, replacementText }; + } + + fixRepeat(stmt: ts.ExpressionStatement): Autofix[] { + const newExpr = ts.factory.createCallExpression(ts.factory.createIdentifier(VIRTUAL_SCROLL_IDENTIFIER), undefined, [ + ts.factory.createObjectLiteralExpression( + [ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier(DISABLE_VIRTUAL_SCROLL_IDENTIFIER), + ts.factory.createTrue() + ) + ], + false + ) + ]); + + let identifier: ts.Identifier | undefined; + const expression = stmt.expression; + if ( + ts.isCallExpression(expression) && + ts.isPropertyAccessExpression(expression.expression) && + ts.isIdentifier(expression.expression.name) + ) { + identifier = expression.expression.name; + } + + const startPos = identifier ? identifier.getStart() : stmt.getStart(); + const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(startPos); + const indent = identifier ? lineAndCharacter.character - 1 : lineAndCharacter.character + INDENT_STEP; + const text = + this.getNewLine() + + ' '.repeat(indent) + + '.' + + this.printer.printNode(ts.EmitHint.Unspecified, newExpr, stmt.getSourceFile()); + return [{ start: stmt.getEnd(), end: stmt.getEnd(), replacementText: text }]; + } + + fixDeprecatedApiForCallExpression(callExpr: ts.CallExpression): Autofix[] | undefined { + const createUIContextAccess = (methodName: string): ts.Node => { + return ts.factory.createPropertyAccessExpression( + ts.factory.createCallExpression(ts.factory.createIdentifier('getUIContext'), undefined, []), + ts.factory.createIdentifier(methodName) + ); + }; + + if (ts.isPropertyAccessExpression(callExpr.expression)) { + const fullName = `${callExpr.expression.expression.getText()}.${callExpr.expression.name.getText()}`; + const methodName = propertyAccessReplacements.get(fullName); + if (methodName) { + const newExpression = createUIContextAccess(methodName); + const newText = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, callExpr.getSourceFile()); + return [ + { + start: callExpr.expression.getStart(), + end: callExpr.expression.getEnd(), + replacementText: newText + } + ]; + } + } + + if (ts.isIdentifier(callExpr.expression)) { + const identifierText = callExpr.expression.getText(); + const methodName = identifierReplacements.get(identifierText); + + if (methodName) { + const newExpression = createUIContextAccess(methodName); + const newText = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, callExpr.getSourceFile()); + return [ + { + start: callExpr.expression.getStart(), + end: callExpr.expression.getEnd(), + replacementText: newText + } + ]; + } + } + + return undefined; + } + + fixSpecialDeprecatedApiForCallExpression(callExpr: ts.CallExpression, name: ts.Identifier): Autofix[] | undefined { + if (name.getText() !== 'clip' || !ts.isNewExpression(callExpr.arguments[0])) { + return undefined; + } + + const shapeMap = { + Circle: 'CircleShape', + Path: 'PathShape', + Ellipse: 'EllipseShape', + Rect: 'RectShape' + } as const; + + const argsExpr = callExpr.arguments[0].arguments; + const constructorName = callExpr.arguments[0].expression.getText(); + + if ( + ts.isPropertyAccessExpression(callExpr.expression) && + callExpr.expression.name.text === 'clip' && + constructorName in shapeMap + ) { + const shapeType = shapeMap[constructorName as keyof typeof shapeMap]; + const newExpression = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + callExpr.expression.expression, + ts.factory.createIdentifier('clipShape') + ), + undefined, + [ts.factory.createNewExpression(ts.factory.createIdentifier(shapeType), undefined, argsExpr)] + ); + + const newText = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, callExpr.getSourceFile()); + return [ + { + start: callExpr.getStart(), + end: callExpr.getEnd(), + replacementText: newText + } + ]; + } + + return undefined; + } + + fixSideEffectImport(importDeclNode: ts.ImportDeclaration): Autofix[] { + const initModuleCall = ts.factory.createCallExpression(ts.factory.createIdentifier('initModule'), undefined, [ + importDeclNode.moduleSpecifier + ]); + const expressionStatement = ts.factory.createExpressionStatement(initModuleCall); + const replacedText = this.printer.printNode( + ts.EmitHint.Unspecified, + expressionStatement, + importDeclNode.getSourceFile() + ); + + return [ + { + start: importDeclNode.getStart(), + end: importDeclNode.getEnd(), + replacementText: replacedText + } + ]; + } + + fixNumericLiteralToFloat(node: ts.NumericLiteral): Autofix[] { + void this; + return [ + { + start: node.getStart(), + end: node.getEnd(), + replacementText: `${node.text}.0` + } + ]; + } } diff --git a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts index 1d05ac4792952a0f3d2ff1007df0a4150e21c3bc..7d8aad85134f7babf281474ea14ecd7f28229f2c 100644 --- a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts +++ b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts @@ -14,11 +14,13 @@ */ import * as fs from 'node:fs'; +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 { USE_STATIC } from '../utils/consts/InteropAPI'; import { AUTOFIX_HTML_TEMPLATE_TEXT, AutofixHtmlTemplate } from './AutofixReportHtmlHelper'; const BACKUP_AFFIX = '~'; @@ -29,7 +31,8 @@ export class QuasiEditor { readonly srcFileName: string, readonly sourceText: string, readonly linterOpts: LinterOptions, - readonly cancellationToken?: ts.CancellationToken + readonly cancellationToken?: ts.CancellationToken, + readonly reportPath?: string ) {} private static getBackupFileName(filePath: string): string { @@ -40,12 +43,6 @@ export class QuasiEditor { fs.copyFileSync(filePath, QuasiEditor.getBackupFileName(filePath)); } - static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { - return problemInfos.some((problemInfo) => { - return problemInfo.autofix !== undefined; - }); - } - private generateReport(acceptedPatches: Autofix[]): void { const report = { filePath: this.srcFileName, @@ -64,11 +61,14 @@ export class QuasiEditor { }) }; - const reportPath = './autofix-report.html'; - const getOldJsonArray = (reportPath: string): Set => { + let reportFilePath = './autofix-report.html'; + if (this.reportPath !== undefined) { + reportFilePath = path.join(path.normalize(this.reportPath), 'autofix-report.html'); + } + const getOldJsonArray = (reportFilePath: string): Set => { try { const RegexCaptureBraketFirst = 1; - const rawData = fs.readFileSync(reportPath, 'utf-8'); + const rawData = fs.readFileSync(reportFilePath, 'utf-8'); const rawContent = rawData.match(/`([\s\S]*?)`/)?.[RegexCaptureBraketFirst] ?? ''; return new Set(JSON.parse(rawContent) || []); } catch { @@ -77,24 +77,29 @@ export class QuasiEditor { }; try { - const existingReports = getOldJsonArray(reportPath); + const existingReports = getOldJsonArray(reportFilePath); existingReports.add(report); const str = JSON.stringify([...existingReports], null, 2); const HtmlContent = AutofixHtmlTemplate.replace(AUTOFIX_HTML_TEMPLATE_TEXT, str); - fs.writeFileSync(reportPath, HtmlContent, { encoding: 'utf-8' }); + 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}`); } } - fix(problemInfos: ProblemInfo[]): string { + fix(problemInfos: ProblemInfo[], needAddUseStatic: boolean | undefined): string { const acceptedPatches = QuasiEditor.sortAndRemoveIntersections(problemInfos); - const result = this.applyFixes(acceptedPatches); + let result = this.applyFixes(acceptedPatches); if (this.linterOpts.migrationReport) { this.generateReport(acceptedPatches); } - + if (needAddUseStatic) { + result = QuasiEditor.addUseStaticDirective(result); + } return result; } @@ -188,4 +193,18 @@ export class QuasiEditor { */ return !(lhs.end < rhs.start || rhs.end < lhs.start); } + + private static addUseStaticDirective(content: string): string { + const lines = content.split('\n'); + if (lines.length > 0 && lines[0].trim() === USE_STATIC) { + return content; + } + return USE_STATIC + '\n' + content; + } + + static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { + return problemInfos.some((problemInfo) => { + return problemInfo.autofix !== undefined; + }); + } } diff --git a/ets2panda/linter/src/lib/data/BuiltinList.json b/ets2panda/linter/src/lib/data/BuiltinList.json index 3ba53f2cbb312d567c6bdc3b9c58df079844fb3e..e2a086ed83b24b6265dcf2795b4f9a85f9c81c2d 100644 --- a/ets2panda/linter/src/lib/data/BuiltinList.json +++ b/ets2panda/linter/src/lib/data/BuiltinList.json @@ -4,13 +4,13 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 107, - "problem": "BuiltinAll", + "problem": "BuiltinNarrowTypes", "api_name": "PropertyKey", "api_type": "TypeAliasDeclaration", "api_func_args": [], "parent_api": [], "code_kind": 268, - "api_property_type": "string | number | symbol" + "method_return_type": "string | number | symbol" }, "import_path": [], "is_global": true @@ -148,7 +148,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 133, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "valueOf", "api_type": "MethodSignature", "api_optional": false, @@ -189,8 +189,8 @@ { "file_path": "lib.es5.d.ts", "api_info": { - "line": 156, - "problem": "BuiltinAll", + "line": 157, + "problem": "BuiltinDisableApi", "api_type": "CallSignature", "parent_api": [ { @@ -206,8 +206,8 @@ { "file_path": "lib.es5.d.ts", "api_info": { - "line": 157, - "problem": "BuiltinAll", + "line": 576, + "problem": "BuiltinNewCtor", "api_type": "CallSignature", "parent_api": [ { @@ -224,7 +224,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 392, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "length", "api_type": "PropertySignature", "api_optional": false, @@ -244,7 +244,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 393, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "callee", "api_type": "PropertySignature", "api_optional": false, @@ -277,6 +277,23 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 522, + "problem": "BuiltinNewCtor", + "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": { @@ -294,6 +311,23 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 539, + "problem": "BuiltinNewCtor", + "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": { @@ -311,11 +345,28 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 576, + "problem": "BuiltinNewCtor", + "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", + "problem": "BuiltinDisableApi", "api_name": "raw", "api_type": "PropertySignature", "api_optional": false, @@ -348,6 +399,23 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 916, + "problem": "BuiltinNewCtor", + "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": { @@ -399,6 +467,23 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1060, + "problem": "BuiltinNewCtor", + "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": { @@ -539,7 +624,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1188, - "problem": "BuiltinAll", + "problem": "BuiltinNarrowTypes", "api_name": "concat", "api_type": "MethodSignature", "api_optional": false, @@ -825,7 +910,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1334, - "problem": "BuiltinAll", + "problem": "BuiltinNarrowTypes", "api_name": "concat", "api_type": "MethodSignature", "api_optional": false, @@ -1070,6 +1155,23 @@ "import_path": [], "is_global": true }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1490, + "problem": "BuiltinNewCtor", + "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": { @@ -1194,7 +1296,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1506, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "ClassDecorator", "api_type": "TypeAliasDeclaration", "api_func_args": [ @@ -1215,7 +1317,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1507, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "PropertyDecorator", "api_type": "TypeAliasDeclaration", "api_func_args": [ @@ -1241,7 +1343,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1508, - "problem": "NoPropertyDescriptor", + "problem": "BuiltinDisableApi", "api_name": "MethodDecorator", "api_type": "TypeAliasDeclaration", "api_func_args": [ @@ -1272,7 +1374,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1509, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "ParameterDecorator", "api_type": "TypeAliasDeclaration", "api_func_args": [ @@ -1303,7 +1405,7 @@ "file_path": "lib.es5.d.ts", "api_info": { "line": 1681, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "ArrayBuffer", "api_type": "PropertySignature", "api_optional": false, @@ -3505,7 +3607,7 @@ "file_path": "lib.es2015.iterable.d.ts", "api_info": { "line": 46, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "return", "api_type": "MethodSignature", "api_optional": true, @@ -3533,7 +3635,7 @@ "file_path": "lib.es2015.iterable.d.ts", "api_info": { "line": 47, - "problem": "BuiltinAll", + "problem": "BuiltinDisableApi", "api_name": "throw", "api_type": "MethodSignature", "api_optional": true, @@ -4626,6 +4728,2710 @@ }, "import_path": [], "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "iterable", + "type": "Iterable | ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64ArrayConstructor", + "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": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigUint64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "Iterable", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arrayLike", + "type": "ArrayLike", + "is_optional": false, + "has_default": false + }, + { + "name": "mapfn", + "type": "(v: T, k: number) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(this: void, value: T, index: number, obj: 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": "S | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, obj: 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 | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "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": 1, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "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": "S[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(this: void, value: T, index: number, obj: 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 | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, obj: 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 | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, obj: 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": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.promise.d.ts", + "api_info": { + "line": 1, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "AggregateErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.promise.d.ts", + "api_info": { + "line": 1, + "problem": "BuiltinNewCtor", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "AggregateErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 43, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, obj: 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": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.promise.d.ts", + "api_info": { + "line": 110, + "problem": "NoPropertyDescriptor", + "api_name": "errors", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "AggregateError", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "any[]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2019.array.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinDisableApi", + "api_name": "flat", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "this", + "type": "A", + "is_optional": false, + "has_default": false + }, + { + "name": "depth", + "type": "D", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FlatArray[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "day", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "dayPeriod", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "era", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "hour", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "literal", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "minute", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "month", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "second", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "timeZoneName", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "weekday", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "year", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DateTimeFormatPartTypesRegistry", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "any", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DisplayNames", + "api_type": "VariableDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "DisplayNames", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.intl.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ListFormat", + "api_type": "VariableDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "ListFormat", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 114, + "problem": "BuiltinDisableApi", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "NumberFormat", + "api_type": "VariableDeclaration" + }, + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "NumberFormat", + "code_kind": 170 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2019.array.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinDisableApi", + "api_name": "flat", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "this", + "type": "A", + "is_optional": false, + "has_default": false + }, + { + "name": "depth", + "type": "D", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FlatArray[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2019.array.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinDisableApi", + "api_name": "flatMap", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "callback", + "type": "(this: This, value: T, index: number, array: T[]) => U | ReadonlyArray", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "This", + "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.es2018.regexp.d.ts", + "api_info": { + "line": 110, + "problem": "BuiltinDisableApi", + "api_name": "groups", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RegExpExecArray", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "{[key: string]: string}" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2018.regexp.d.ts", + "api_info": { + "line": 110, + "problem": "BuiltinDisableApi", + "api_name": "groups", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RegExpMatchArray", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "{[key: string]: string}" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2019.array.d.ts", + "api_info": { + "line": 110, + "problem": "BuiltinDisableApi", + "api_name": "FlatArray", + "api_type": "TypeAliasDeclaration", + "api_optional": true, + "parent_api": [], + "code_kind": 170, + "method_return_type": "{\"done\": Arr, \"recur\": Arr extends ReadonlyArray ? FlatArray : Arr}[Depth extends -1 ? \"done\" : \"recur\"]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "isFinite", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "number", + "type": "unknown", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "isInteger", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "number", + "type": "unknown", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "isNaN", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "number", + "type": "unknown", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "isSafeInteger", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "number", + "type": "unknown", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.reflect.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinAll", + "api_name": "get", + "api_type": "MethodDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "propertyKey", + "type": "P", + "is_optional": false, + "has_default": false + }, + { + "name": "receiver", + "type": "unknown", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Reflect", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "P extends keyof T ? T[P] : any", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.reflect.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "has", + "api_type": "MethodDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "object", + "is_optional": false, + "has_default": false + }, + { + "name": "propertyKey", + "type": "PropertyKey", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Reflect", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.reflect.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinNarrowTypes", + "api_name": "ownKeys", + "api_type": "MethodDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Reflect", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "(string | symbol)[]", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.reflect.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinAll", + "api_name": "set", + "api_type": "MethodDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "propertyKey", + "type": "P", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "P extends keyof T ? T[P] : any", + "is_optional": false, + "has_default": false + }, + { + "name": "receiver", + "type": "any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Reflect", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.core.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinDisableApi", + "api_name": "raw", + "api_type": "MethodSignature", + "api_func_args": [ + { + "name": "template", + "type": "{ raw: readonly string[] | ArrayLike}", + "is_optional": false, + "has_default": false + }, + { + "name": "substitutions", + "type": "any[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StringConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1, + "problem": "BuiltinDisableApi", + "api_name": "from", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "iterable", + "type": "Iterable | ArrayLike", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1, + "problem": "BuiltinNarrowTypes", + "api_name": "isArray", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "arg is any[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinIteratorResultValue", + "api_name": "IteratorResult", + "api_type": "TypeAliasDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "IteratorYieldResult | IteratorReturnResult", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinDisableApi", + "api_name": "done", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IteratorReturnResult", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "true" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinDisableApi", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IteratorReturnResult", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "TReturn" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinDisableApi", + "api_name": "done", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "IteratorYieldResult", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "false" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinDisableApi", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IteratorYieldResult", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "TYield" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1244, + "problem": "BuiltinNarrowTypes", + "api_name": "isView", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "arg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayBufferConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "arg is ArrayBufferView", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1244, + "problem": "BuiltinNarrowTypes", + "api_name": "toJSON", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Date", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2022.error.d.ts", + "api_info": { + "line": 110, + "problem": "NoPropertyDescriptor", + "api_name": "cause", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ErrorOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "unknown" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2022.error.d.ts", + "api_info": { + "line": 110, + "problem": "NoPropertyDescriptor", + "api_name": "cause", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "Error", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "unknown" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "stringify", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "any", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(this: any, key: string, value: any) => any", + "is_optional": true, + "has_default": false + }, + { + "name": "space", + "type": "string | number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "stringify", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "any", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(number | string)[] | null", + "is_optional": true, + "has_default": false + }, + { + "name": "space", + "type": "string | number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.object.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "entries", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "o", + "type": "{}", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "[string, any][]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2017.object.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "values", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "o", + "type": "{}", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "any[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2019.object.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "fromEntries", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "entries", + "type": "Iterable", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "{ [k: string]: T }", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "replace", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "searchValue", + "type": "string | RegExp", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(substring: string, ...args: any[]) => string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "String", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.string.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinNarrowTypes", + "api_name": "replaceAll", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "searchValue", + "type": "string | RegExp", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(substring: string, ...args: any[]) => string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "String", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 522, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "WeakMapConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 522, + "problem": "BuiltinNewCtor", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "WeakMapConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "BigInt", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "BigIntConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "DataView", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "DataViewConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Int8Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "Int8ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Int16Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "Int16ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Int32Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "Int32ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "BigInt64Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "BigInt64ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Float32Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "Float32ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Float64Array", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "Float64ArrayConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Boolean", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "BooleanConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "String", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "StringConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "WeakMap", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "WeakMapConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "WeakSet", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "WeakSetConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2021.weakref.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "FinalizationRegistry", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "FinalizationRegistryConstructor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinFinalClass", + "api_name": "Promise", + "api_type": "VariableDeclaration", + "api_optional": false, + "parent_api": [], + "code_kind": 260, + "api_property_type": "PromiseConstructor" + }, + "import_path": [], + "is_global": true } ] } \ No newline at end of file diff --git a/ets2panda/linter/src/lib/data/DeprecatedApiList.json b/ets2panda/linter/src/lib/data/DeprecatedApiList.json new file mode 100644 index 0000000000000000000000000000000000000000..2c05b55d141c4d13401df081b8b3b3d82312a892 --- /dev/null +++ b/ets2panda/linter/src/lib/data/DeprecatedApiList.json @@ -0,0 +1,10369 @@ +{ + "api_list": [ + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "clip", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean | CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "opacity", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "type", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "TransitionType" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.curves.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "cubicBezier", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "curves", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "x1", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "y1", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "x2", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "y2", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "string" + }, + "import_path": [ + "@ohos.curves", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "rotate", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "RotateOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "scale", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "ScaleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "translate", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "TranslateOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigation.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "toolBar", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigationAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "object | CustomBuilder", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigationAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigation.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "subTitle", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigationAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigationAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "px2lpx", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "lpx2px", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "px2fp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "fp2px", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "px2vp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "vp2px", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getContext", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "component", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "Context" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/xcomponent.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "setXComponentSurfaceSize", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentController", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n surfaceWidth: number;\n surfaceHeight: number;\n }", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/text_input.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onEditChanged", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "TextInputAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(isEditing: boolean) => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "TextInputAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenY", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TouchObject", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenX", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "TouchObject", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenY", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "MouseEvent", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenX", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "MouseEvent", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenY", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ClickEvent", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenX", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ClickEvent", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/image_animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "preDecode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ImageAnimatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ImageAnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/text_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "TextPickerDialog", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "TextPickerDialogOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/text_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onCancel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "TextPickerAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "() => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "TextPickerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/text_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onAccept", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "TextPickerAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(value: string, index: number) => void", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "TextPickerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/date_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DatePickerDialog", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "DatePickerDialogOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/date_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onChange", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DatePickerDialogOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "DatePickerResult", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(value: DatePickerResult) => void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/date_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onAccept", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DatePickerDialogOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "DatePickerResult", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(value: DatePickerResult) => void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/date_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onChange", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DatePickerAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(value: DatePickerResult)", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "DatePickerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/lazy_for_each.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDataChanged", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DataChangeListener", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/lazy_for_each.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDataDeleted", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DataChangeListener", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/lazy_for_each.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDataMoved", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DataChangeListener", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "from", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "to", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/lazy_for_each.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDataAdded", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DataChangeListener", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.arkui.UIContext.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showActionMenu", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PromptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "promptAction.ActionMenuOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "promptAction.ActionMenuSuccessResponse", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.UIContext", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/action_sheet.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ActionSheet", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "ActionSheetOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/alert_dialog.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AlertDialog", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "AlertDialogParamWithConfirm | AlertDialogParamWithButtons | AlertDialogParamWithOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/refresh.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "offset", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RefreshOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number | string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Center", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "Edge", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Middle", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "Edge", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "5" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.arkui.componentSnapshot.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createFromBuilder", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "componentSnapshot", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "builder", + "type": "CustomBuilder", + "is_optional": false, + "has_default": false + }, + { + "name": "delay", + "type": "number", + "is_optional": true, + "has_default": false + }, + { + "name": "checkImageStatus", + "type": "boolean", + "is_optional": true, + "has_default": false + }, + { + "name": "options", + "type": "SnapshotOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.arkui.componentSnapshot", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.componentSnapshot.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createFromBuilder", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "componentSnapshot", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "builder", + "type": "CustomBuilder", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + }, + { + "name": "delay", + "type": "number", + "is_optional": true, + "has_default": false + }, + { + "name": "checkImageStatus", + "type": "boolean", + "is_optional": true, + "has_default": false + }, + { + "name": "options", + "type": "SnapshotOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.componentSnapshot", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.componentSnapshot.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "get", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "componentSnapshot", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "id", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "SnapshotOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.arkui.componentSnapshot", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.componentSnapshot.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "get", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "componentSnapshot", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "id", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "SnapshotOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.componentSnapshot", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.measure.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "measureTextSize", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "MeasureText", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "MeasureOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SizeOptions" + }, + "import_path": [ + "@ohos.measure", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.measure.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "measureText", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "MeasureText", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "MeasureOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number" + }, + "import_path": [ + "@ohos.measure", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.dragController.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getDragPreview", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "dragController", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "DragPreview" + }, + "import_path": [ + "@ohos.arkui.dragController", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.dragController.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createDragAction", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "dragController", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "customArray", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "dragInfo", + "type": "DragInfo", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "DragAction" + }, + "import_path": [ + "@ohos.arkui.dragController", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.dragController.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "executeDrag", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "dragController", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "custom", + "type": "CustomBuilder | DragItemInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "dragInfo", + "type": "DragInfo", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.arkui.dragController", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.dragController.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "executeDrag", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "dragController", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "custom", + "type": "CustomBuilder | DragItemInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "dragInfo", + "type": "DragInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.dragController", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getShared", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "LocalStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "LocalStorage" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.arkui.inspector.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createComponentObserver", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "inspector", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "id", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ComponentObserver" + }, + "import_path": [ + "@ohos.arkui.inspector", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "create", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Animator", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "AnimatorOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorResult" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.mediaquery.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "matchMediaSync", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "mediaquery", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "condition", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "MediaQueryListener" + }, + "import_path": [ + "@ohos.mediaquery", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.font.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getFontByName", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "font", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "fontName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "FontInfo" + }, + "import_path": [ + "@ohos.font", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.font.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getSystemFontList", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "font", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Array" + }, + "import_path": [ + "@ohos.font", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.font.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "registerFont", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "font", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "FontOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.font", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushNamedRoute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "NamedRouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getParams", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Object" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "hideAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "EnableAlertOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getStateByUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "url", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Array" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getStateByIndex", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "RouterState | undefined" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getState", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "RouterState" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getLength", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "string" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "clear", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "back", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "params", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "back", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replaceUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "RouterMode", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "pushUrl", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/time_picker.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "TimePickerDialog", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "TimePickerDialogOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "animateTo", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "AnimateParam", + "is_optional": false, + "has_default": false + }, + { + "name": "event", + "type": "() => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showActionMenu", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ActionMenuOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showActionMenu", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ActionMenuOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "closeCustomDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "dialogId", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "openCustomDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "CustomDialogOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowDialogOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowDialogOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.promptAction.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showToast", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "promptAction", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowToastOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.promptAction", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.componentUtils.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getRectangleById", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "componentUtils", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "id", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ComponentInfo" + }, + "import_path": [ + "@ohos.arkui.componentUtils", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "layout", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "childLayoutInfo", + "type": "LayoutInfo", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "position", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "Position" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "borderInfo", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "LayoutBorderInfo" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "position", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "Position" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "measure", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "childConstraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "id", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constraint", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "ConstraintSizeOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "name", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constraint", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "ConstraintSizeOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "margin", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutBorderInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "Margin" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "useSizeType", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n xs?: number | { span: number; offset: number; };\n sm?: number | { span: number; offset: number; };\n md?: number | { span: number; offset: number; };\n lg?: number | { span: number; offset: number; };\n }", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "padding", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutBorderInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "Padding" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "borderWidth", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "LayoutBorderInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "EdgeWidths" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "mask", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "CircleAttribute | EllipseAttribute | PathAttribute | RectAttribute | ProgressMask", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onMeasure", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onLayout", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "placementOnTop", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "PopupOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onScroll", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ScrollableCommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(scrollOffset: number)", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "touchable", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "maskColor", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "CustomPopupOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Color | string | Resource | number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getX", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DragEvent", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getY", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DragEvent", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "LayoutChild", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "LayoutChild", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "LayoutInfo", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "LayoutInfo", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "LayoutBorderInfo", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "LayoutBorderInfo", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "TransitionOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "TransitionOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "gridOffset", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "gridSpan", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "CommonMethod", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "indicatorStyle", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "SwiperAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "IndicatorStyle", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "SwiperAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "IndicatorStyle", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "color", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "ResourceColor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "right", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Length" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "left", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Length" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AUTO_LINEAR", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SwiperDisplayMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AutoLinear", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SwiperDisplayMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "selectedColor", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "ResourceColor" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "mask", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "bottom", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Length" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "size", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Length" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Stretch", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SwiperDisplayMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/swiper.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "top", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "IndicatorStyle", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Length" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/scroll.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "scrollPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Scroller", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{ next: boolean; direction: Axis }", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/scroll.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Free", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "ScrollDirection", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/scroll.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onScrollEnd", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ScrollAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "() => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "ScrollAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/scroll.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onScroll", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ScrollAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(xOffset: number, yOffset: number) => void", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ScrollAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/ui_extension_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onResult", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "UIExtensionComponentAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "import('../api/@ohos.base').Callback<{\n\n code: number;\n\n want: import('../api/@ohos.app.ability.Want').default;\n\n }>", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "UIExtensionComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/ui_extension_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onRelease", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "UIExtensionComponentAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "import('../api/@ohos.base').Callback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "UIExtensionComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/slider.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "minLabel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "SliderAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SliderAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/slider.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "maxLabel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "SliderAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SliderAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list_item.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ListItemAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListItemInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "ListItemAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list_item.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "sticky", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListItemAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Sticky", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ListItemAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list_item.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "editable", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListItemAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean | EditMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ListItemAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list_item.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Sticky", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "Sticky", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list_item.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "EditMode", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "EditMode", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.arkui.advanced.ChipGroup.d.ets", + "api_info": { + "line": 1, + "problem": "", + "api_name": "suffixIcon", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ChipGroupItemOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "IconOptions" + }, + "import_path": [ + "@ohos.arkui.advanced.ChipGroup" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouterInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "NavRouterAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouter", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "NavRouterInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "mode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavRouterAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "mode", + "type": "NavRouteMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavRouterAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onStateChange", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavRouterAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(isActivated: boolean) => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "NavRouterAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouterAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "NavRouterAttribute", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "REPLACE", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavRouteMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PUSH", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavRouteMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PUSH_WITH_RECREATE", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavRouteMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouteMode", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "NavRouteMode", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouterAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavRouterInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "RouteInfo", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavRouterAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouterAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavRouterInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "NavRouterAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavRouterInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "NavRouterInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "param", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouteInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "unknown" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "name", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouteInfo", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/nav_router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "RouteInfo", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "RouteInfo", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigatorInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Navigator", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "NavigatorInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "params", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "object", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "target", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "type", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "NavigationType", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "active", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigatorAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "NavigatorAttribute", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigatorAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigatorAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "NavigatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{ target: string; type: NavigationType }", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "NavigatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigatorInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "NavigatorInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Replace", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavigationType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Back", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavigationType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Push", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "NavigationType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/navigator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NavigationType", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "NavigationType", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SizeType", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainer", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "GridContainerInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainerInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "GridContainerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainerInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "GridContainerInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainerOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "GridContainerOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainerAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "GridContainerAttribute", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "index", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "prompt.ShowDialogSuccessResponse", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ParamsInterface", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string]: Object;\n}" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/matrix2d.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "rotate", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Matrix2D", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "rx", + "type": "number", + "is_optional": true, + "has_default": false + }, + { + "name": "ry", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "Matrix2D" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/matrix2d.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "multiply", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Matrix2D", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "other", + "type": "Matrix2D", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "Matrix2D" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onScroll", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(scrollOffset: number)", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ListAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/xcomponent.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "XComponentAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{ id: string; type: string; libraryname: string; controller: XComponentController }", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "XComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "COMPONENT", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "XComponentType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/arkui/XComponentNode.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "changeRenderType", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentNode", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "type", + "type": "NodeRenderType", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [ + "@ohos.arkui.node", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/arkui/XComponentNode.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDestroy", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentNode", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.node", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/arkui/XComponentNode.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onCreate", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentNode", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.arkui.node", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/arkui/XComponentNode.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constructor", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "XComponentNode", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "uiContext", + "type": "UIContext", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "RenderOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "id", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "type", + "type": "XComponentType", + "is_optional": false, + "has_default": false + }, + { + "name": "libraryName", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "string)" + }, + "import_path": [ + "@ohos.arkui.node", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/arkui/XComponentNode.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "XComponentNode", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "XComponentNode", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.arkui.node", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GetShared", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "LocalStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "LocalStorage" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "CROSS_DEVICE", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "CopyOptions", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "BackRouterOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "BackRouterOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SetAndLink", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "defaultValue", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SubscribedAbstractProperty" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Link", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AbilityComponentInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "AbilityComponentInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AbilityComponent", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "AbilityComponentInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.app.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "requestFullWindow", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "App", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RequestFullWindowOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.app", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "enableAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "EnableAlertBeforeBackPageOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SM", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowDialogOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/list.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onItemDelete", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(index: number)", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "ListAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Baseline", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "Edge", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "sizeType", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "GridContainerOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "SizeType" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "DeleteProp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PersistentStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/menu.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "fontSize", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "MenuAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Length", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "MenuAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "invert", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Button", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "prompt.Button", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "shortName", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "buttons", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "prompt.ShowDialogOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "[Button, Button?, Button?]" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showActionMenu", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ActionMenuOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ActionMenuSuccessResponse", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "prompt.ActionMenuSuccessResponse", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showActionMenu", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ActionMenuOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Promise" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AbilityComponentAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AbilityComponentInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{want: import('../api/@ohos.app.ability.Want').default}", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AbilityComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getLength", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ActionMenuOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "prompt.ActionMenuOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getParams", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "ParamsInterface" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "RouterOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "RouterOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onConnect", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AbilityComponentAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "()", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AbilityComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "cancel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DisableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "errMsg", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(errMsg: string) => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "enableAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "EnableAlertOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Set", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "newValue", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "params", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "BackRouterOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Object" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.curves.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "steps", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "curves", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "count", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "end", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "string" + }, + "import_path": [ + "@ohos.curves", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/gridItem.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "forceRebuild", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "GridItemAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "GridItemAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Keys", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "IterableIterator" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "bottom", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string | number" + }, + "import_path": [ + "@system.prompt" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "staticClear", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "LG", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "4" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Has", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "scale", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ScaleOption", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showDialog", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowDialogOptions", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "duration", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number" + }, + "import_path": [ + "@system.prompt" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "transformPoint", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "[number, number]", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "[number, number]" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "message", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@system.prompt" + ], + "is_global": false + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "uri", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ShowDialogOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "ShowDialogOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "message", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createAnimator", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Animator", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "AnimatorOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorResult" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SetAndProp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "defaultValue", + "type": "S", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SubscribedAbstractProperty" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/progress.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "style", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ProgressOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "ProgressStyle" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "index", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ActionMenuSuccessResponse", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SetOrCreate", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "newValue", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getState", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "RouterState" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "columns", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "GridContainerOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number | \"auto\"" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "cancel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "errMsg", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(errMsg: string) => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "complete", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "() => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "buttons", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ActionMenuOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "[Button, Button?, Button?, Button?, Button?, Button?]" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "color", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "Button", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PersistProp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PersistentStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "defaultValue", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/list.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "editMode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ListAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "ListAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replace", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "path", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouterState", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.curves.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "spring", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "curves", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "velocity", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "mass", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "stiffness", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "damping", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "string" + }, + "import_path": [ + "@ohos.curves", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "RouterState", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "RouterState", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "MD", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "abilityName", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AbilityComponentAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "AbilityComponentAttribute", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "params", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouterOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "Object" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "name", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouterState", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "title", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowDialogOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "prompt", + "api_type": "NamespaceDeclaration", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "NamespaceDeclaration" + } + ], + "code_kind": 237, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "success", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "errMsg", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(errMsg: string) => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "DisableAlertBeforeBackPageOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "DisableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Auto", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ShowToastOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.prompt" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onDisconnect", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AbilityComponentAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "() => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AbilityComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "push", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ShowDialogSuccessResponse", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "ShowDialogSuccessResponse", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Prop", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "back", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "BackRouterOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "update", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorResult", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "AnimatorOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "combine", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "Matrix4Transit", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/alphabet_indexer.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onSelected", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AlphabetIndexerAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(index: number) => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AlphabetIndexerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showToast", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "prompt", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ShowToastOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "disableAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "disableAlertBeforeBackPage", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "DisableAlertBeforeBackPageOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "EnvProp", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Environment", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "S", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "IsMutable", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "XS", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "SizeType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "complete", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DisableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "() => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "duration", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Get", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "T | undefined" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Keys", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PersistentStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Array" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "index", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouterState", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "number" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "text", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "prompt.Button", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/ability_component.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AbilityComponentInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "AbilityComponentAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "rotate", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RotateOption", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "success", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "DisableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "errMsg", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(errMsg: string) => void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "margin", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "GridContainerOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number | string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "GridContainerAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "GridContainerInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "GridContainerOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "GridContainerAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PersistProps", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PersistentStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "properties", + "type": "{\n key: string;\n defaultValue: any;\n }[]", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "bottom", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string | number" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Keys", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Environment", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Array" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "copy", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "title", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "prompt.ActionMenuOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid_container.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "gutter", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "GridContainerOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number | string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "deviceId", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "EnvProps", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Environment", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "props", + "type": "{\n key: string;\n defaultValue: any;\n }[]", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Clear", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "replace", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "clear", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "Router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "void" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "uri", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "BackRouterOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/rect.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "RectInStance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "RectAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.curves.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "init", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "curves", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "curve", + "type": "Curve", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "string" + }, + "import_path": [ + "@ohos.curves", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.app.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "screenOnVisible", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "App", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "ScreenOnVisibleOptions", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.app", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Delete", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "propName", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/common_ts_ets_api.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Size", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AppStorage", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "bundleName", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "message", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "ShowDialogOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "string" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.matrix4.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "translate", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "matrix4", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "TranslateOption", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "Matrix4Transit" + }, + "import_path": [ + "@ohos.matrix4", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ShowToastOptions", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "prompt.ShowToastOptions", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@ohos.prompt", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "push", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "router", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "options", + "type": "RouterOptions", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@ohos.router", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Router", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "Router", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "uri", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RouterOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/@system.router.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "message", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "EnableAlertBeforeBackPageOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "string" + }, + "import_path": [ + "@system.router" + ], + "is_global": false + }, + { + "file_path": "api/bundle/elementName.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ElementName", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "ElementName", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "elementName" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Mini", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelMode", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "PanelMode", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Half", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Full", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelMode", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/inspector.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getInspectorNodes", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "object" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onrepeat", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorResult", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "() => void" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "oncancel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorResult", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "() => void" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onfinish", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorResult", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [], + "method_return_type": "() => void" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onframe", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorResult", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "progress", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "(progress: number) => void" + }, + "import_path": [ + "@ohos.animator", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/grid.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onScroll", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "GridAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(scrollOffset: number)", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "GridAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onChange", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(width: number)", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Panel", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "PanelInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onHeightChange", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "callback", + "type": "(value: number)", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showCloseIcon", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "backgroundMask", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "color", + "type": "ResourceColor", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "show", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "miniHeight", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number | string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "halfHeight", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number | string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "fullHeight", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number | string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "customHeight", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Dimension | PanelHeight", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "dragBar", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "type", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "PanelType", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "mode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "PanelMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "PanelAttribute", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "PanelInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "show", + "type": "boolean", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "PanelAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "PanelInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "WRAP_CONTENT", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelHeight", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelHeight", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "PanelHeight", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "CUSTOM", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Temporary", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "2" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Foldable", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "1" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Minibar", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "PanelType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "0" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/panel.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "PanelType", + "api_type": "EnumDeclaration", + "parent_api": [ + { + "api_name": "PanelType", + "api_type": "" + } + ], + "code_kind": 241, + "api_optional": false + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/refresh.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "friction", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "RefreshOptions", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": true, + "method_return_type": "number | string" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/common/full/global.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createLocalParticleAbility", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/common/lite/global.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "createLocalParticleAbility", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "method_return_type": "any" + }, + "import_path": [ + "global" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/inspector.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "getInspectorNodeById", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "id", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "object" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AnimatorAttribute", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AnimatorAttribute", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "playMode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "PlayMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AnimatorInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "duration", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "motion", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "SpringMotion | FrictionMotion | ScrollMotion", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "delay", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onRepeat", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "()", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "state", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "AnimationStatus", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "iterations", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onPause", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "()", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onStart\n\n", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "()", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "curve\n", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorInterface", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Curve", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "Animator", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "AnimatorInterface" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "AnimatorInstance", + "api_type": "PropertySignature", + "parent_api": [ + { + "api_name": "unnamed", + "api_type": "" + } + ], + "code_kind": 156, + "api_optional": false, + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onFinish", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "() => void", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onCancel", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "()", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "fillMode", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "FillMode", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "onFrame", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "AnimatorAttribute", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(value: number)", + "is_optional": false, + "has_default": true + } + ], + "method_return_type": "AnimatorAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constructor", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "ScrollMotion", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "position", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "velocity", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "min", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "max", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "prop", + "type": "SpringProp", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SpringProp)" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constructor", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "SpringMotion", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "start", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "end", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "velocity", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "prop", + "type": "SpringProp", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "SpringProp)" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SpringProp", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "SpringProp", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constructor", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "FrictionMotion", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "friction", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "position", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "velocity", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number)" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts\n", + "api_info": { + "line": 1, + "problem": "", + "api_name": "FrictionMotion", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "FrictionMotion", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "SpringMotion", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "ScrollMotion", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "ScrollMotion", + "api_type": "ClassDeclaration", + "parent_api": [ + { + "api_name": "ScrollMotion", + "api_type": "ClassDeclaration" + } + ], + "code_kind": 239, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@internal/component/ets/animator.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "constructor", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "SpringProp", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "mass", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "stiffness", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "damping", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "number)" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@system.prompt.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "showToast", + "api_type": "InterfaceDeclaration", + "parent_api": [ + { + "api_name": "Prompt", + "api_type": "" + } + ], + "code_kind": 240, + "api_optional": false, + "method_return_type": "" + }, + "import_path": [ + "@system.prompt" + ], + "is_global": false + }, + { + "file_path": "api/@system.app.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "setImageRawDataCacheSize", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "App", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.app", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.app.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "setImageCacheCount", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "App", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.app", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@system.app.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "setImageFileCacheSize", + "api_type": "MethodSignature", + "parent_api": [ + { + "api_name": "App", + "api_type": "" + } + ], + "code_kind": 173, + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "method_return_type": "void" + }, + "import_path": [ + "@system.app", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@internal/component/ets/enums.d.ts", + "api_info": { + "line": 1, + "problem": "", + "api_name": "NODE", + "api_type": "EnumMember", + "parent_api": [ + { + "api_name": "XComponentType", + "api_type": "" + } + ], + "code_kind": 242, + "api_optional": false, + "method_return_type": "3" + }, + "import_path": [], + "is_global": true + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/src/lib/data/SdkCommonList.json b/ets2panda/linter/src/lib/data/SdkCommonList.json new file mode 100644 index 0000000000000000000000000000000000000000..d13d239b9a745427697527448d2f3df29c07a081 --- /dev/null +++ b/ets2panda/linter/src/lib/data/SdkCommonList.json @@ -0,0 +1,6450 @@ +{ + "api_list": [ + { + "file_path": "api/@ohos.util.ArrayList.d.ts", + "api_info": { + "line": 858, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ArrayList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.ArrayList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.ArrayList.d.ts", + "api_info": { + "line": 858, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, arrlist?: ArrayList) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.ArrayList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.ArrayList.d.ts", + "api_info": { + "line": 858, + "problem": "WhiteList", + "api_name": "replaceAllElements", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, arrlist?: ArrayList) => T", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.ArrayList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.ArrayList.d.ts", + "api_info": { + "line": 858, + "problem": "BehaviorChange", + "api_name": "sort", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "comparator", + "type": "(firstValue: T, secondValue: T) => number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ArrayList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.ArrayList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@arkts.collections.d.ts", + "api_info": { + "line": 12151, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "BitVector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@arkts.collections", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Deque.d.ts", + "api_info": { + "line": 375, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Deque", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Deque", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Deque.d.ts", + "api_info": { + "line": 375, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, deque?: Deque) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Deque", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Deque", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.HashMap.d.ts", + "api_info": { + "line": 551, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "HashMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.HashMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.HashMap.d.ts", + "api_info": { + "line": 551, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: V, key?: K, map?: HashMap) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "HashMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.HashMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.HashSet.d.ts", + "api_info": { + "line": 551, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "HashSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.HashSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.HashSet.d.ts", + "api_info": { + "line": 551, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: T, key?: T, set?: HashSet) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "HashSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.HashSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LightWeightMap.d.ts", + "api_info": { + "line": 760, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LightWeightMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LightWeightMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LightWeightMap.d.ts", + "api_info": { + "line": 760, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: V, key?: K, map?: LightWeightMap) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LightWeightMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LightWeightMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LightWeightSet.d.ts", + "api_info": { + "line": 512, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LightWeightSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LightWeightSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LightWeightSet.d.ts", + "api_info": { + "line": 512, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: T, key?: T, set?: LightWeightSet) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LightWeightSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LightWeightSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LinkedList.d.ts", + "api_info": { + "line": 512, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LinkedList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LinkedList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LinkedList.d.ts", + "api_info": { + "line": 512, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, LinkedList?: LinkedList) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LinkedList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LinkedList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LinkedList.d.ts", + "api_info": { + "line": 512, + "problem": "BehaviorChange", + "api_name": "removeFirstFound", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LinkedList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LinkedList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.LinkedList.d.ts", + "api_info": { + "line": 512, + "problem": "BehaviorChange", + "api_name": "removeLastFound", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LinkedList", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.LinkedList", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.List.d.ts", + "api_info": { + "line": 848, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "List", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.List", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.List.d.ts", + "api_info": { + "line": 848, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, List?: List) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "List", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.List", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.List.d.ts", + "api_info": { + "line": 848, + "problem": "WhiteList", + "api_name": "replaceAllElements", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, list?: List) => T", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "List", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.List", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.PlainArray.d.ts", + "api_info": { + "line": 848, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "PlainArray", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator<[number, T]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.PlainArray", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.PlainArray.d.ts", + "api_info": { + "line": 848, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, PlainArray?: PlainArray) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PlainArray", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.PlainArray", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Queue.d.ts", + "api_info": { + "line": 266, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Queue", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Queue", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Queue.d.ts", + "api_info": { + "line": 266, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, Queue?: Queue) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Queue", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Queue", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Queue.d.ts", + "api_info": { + "line": 266, + "problem": "WhiteList", + "api_name": "add", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Queue", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Queue", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Stack.d.ts", + "api_info": { + "line": 266, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Stack", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Stack", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Stack.d.ts", + "api_info": { + "line": 266, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, stack?: Stack) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Stack", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Stack", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeMap.d.ts", + "api_info": { + "line": 760, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TreeMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.TreeMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeMap.d.ts", + "api_info": { + "line": 760, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: V, key?: K, map?: TreeMap) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TreeMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.TreeMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeMap.d.ts", + "api_info": { + "line": 760, + "problem": "BehaviorChange", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "comparator", + "type": "(firstValue: K, secondValue: K) => boolean", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TreeMap", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util.TreeMap", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeSet.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TreeSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.TreeSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeSet.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value?: T, key?: T, set?: TreeSet) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TreeSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.TreeSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.TreeSet.d.ts", + "api_info": { + "line": 89, + "problem": "BehaviorChange", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "comparator", + "type": "(firstValue: T, secondValue: T) => boolean", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TreeSet", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util.TreeSet", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[string, string]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getAll", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string[]", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "append", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "delete", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "entries", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[string, string]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: string, key: string, searchParams: URLSearchParams) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "get", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string | null", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "get", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string[]", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "has", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "set", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "name", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "keys", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "values", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "toString", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "sort", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "init", + "type": "string[][] | Record | string | URLSearchParams", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: string, key: string, searchParams: URLParams) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLSearchParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "put", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "V", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "capacity", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "updateCapacity", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "newCapacity", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getCapacity", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getCreateCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getMissCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getRemovalCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getMatchCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "getPutCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getPutCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "length", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "LRUCache", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "number", + "code_kind": 171 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.json.d.ts", + "api_info": { + "line": 59, + "problem": "WhiteList", + "api_name": "parse", + "api_type": "FunctionDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "text", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "reviver", + "type": "Transformer", + "is_optional": true, + "has_default": false + }, + { + "name": "options", + "type": "ParseOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "json", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object | null", + "code_kind": 263 + }, + "import_path": [ + "@ohos.util.json" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.json.d.ts", + "api_info": { + "line": 42, + "problem": "WhiteList", + "api_name": "Transformer", + "api_type": "TypeAliasDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "this", + "type": "Object", + "is_optional": false, + "has_default": false + }, + { + "name": "key", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "json", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object | undefined | null", + "code_kind": 268 + }, + "import_path": [ + "@ohos.util.json" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.json.d.ts", + "api_info": { + "line": 59, + "problem": "WhiteList", + "api_name": "remove", + "api_type": "FunctionDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "obj", + "type": "object", + "is_optional": false, + "has_default": false + }, + { + "name": "property", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "json", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 263 + }, + "import_path": [ + "@ohos.util.json" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isArgumentsObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isGeneratorFunction", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isGeneratorFunction", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isGeneratorObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isModuleNamespaceObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isProxy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 3585, + "problem": "WhiteList", + "api_name": "isSymbolObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "types", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 4701, + "problem": "WhiteList", + "api_name": "addAfter", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "targetClass", + "type": "Object", + "is_optional": false, + "has_default": false + }, + { + "name": "methodName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "isStatic", + "type": "boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "after", + "type": "Function", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Aspect", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 4667, + "problem": "WhiteList", + "api_name": "addBefore", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "targetClass", + "type": "Object", + "is_optional": false, + "has_default": false + }, + { + "name": "methodName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "isStatic", + "type": "boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "before", + "type": "Function", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Aspect", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 4773, + "problem": "WhiteList", + "api_name": "replace", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "targetClass", + "type": "Object", + "is_optional": false, + "has_default": false + }, + { + "name": "methodName", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "isStatic", + "type": "boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "instead", + "type": "Function", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Aspect", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 992, + "problem": "BehaviorChange", + "api_name": "href", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 992, + "problem": "BehaviorChange", + "api_name": "href", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 992, + "problem": "BehaviorChange", + "api_name": "origin", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 992, + "problem": "BehaviorChange", + "api_name": "pathname", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 1143, + "problem": "BehaviorChange", + "api_name": "search", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 1143, + "problem": "WhiteList", + "api_name": "searchParams", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "URL", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "URLSearchParams", + "code_kind": 171 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.url.d.ts", + "api_info": { + "line": 283, + "problem": "BehaviorChange", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "init", + "type": "string[][] | Record | string | URLParams", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "URLParams", + "api_type": "ClassDeclaration" + }, + { + "api_name": "url", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.url", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "WhiteList", + "api_name": "stringify", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "any", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(this: any, key: string, value: any) => any", + "is_optional": true, + "has_default": false + }, + { + "name": "space", + "type": "string | number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "WhiteList", + "api_name": "stringify", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "any", + "is_optional": false, + "has_default": false + }, + { + "name": "replacer", + "type": "(number | string)[] | null", + "is_optional": true, + "has_default": false + }, + { + "name": "space", + "type": "string | number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "slice", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "start", + "type": "number", + "is_optional": true, + "has_default": false + }, + { + "name": "end", + "type": "number", + "is_optional": true, + "has_default": false + }, + { + "name": "type", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Blob", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Blob", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readInt8", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readInt16BE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readInt16LE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readInt32BE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readInt32LE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readIntBE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "byteLength", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.buffer.d.ts", + "api_info": { + "line": 3388, + "problem": "BehaviorChange", + "api_name": "readIntLE", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "offset", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "byteLength", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Buffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "buffer", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.buffer", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getErrorString", + "api_type": "FunctionDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "errno", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "printf", + "api_type": "FunctionDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "format", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "...args", + "type": "Object[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "promiseWrapper", + "api_type": "FunctionDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "original", + "type": "(err: Object, value: Object) => void", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "decode", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array | string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "decodeSync", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array | string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encode", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encodeSync", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encodeToString", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encodeToStringSync", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "BehaviorChange", + "api_name": "encodeToStringSync", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "src", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "Type", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Base64Helper", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "stream", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "DecodeWithStreamOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "afterRemoval", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "isEvict", + "type": "boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "V", + "is_optional": false, + "has_default": false + }, + { + "name": "newValue", + "type": "V", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "clear", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "capacity", + "type": "number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "contains", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "createDefault", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "entries", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "get", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V | undefined", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getCapacity", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getCreateCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getMatchCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getMissCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getPutCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getPutCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getRemovalCount", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "isEmpty", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "keys", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "K[]", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "put", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + }, + { + "name": "value", + "type": "V", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "remove", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "key", + "type": "K", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V | undefined", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "toString", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "updateCapacity", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "newCapacity", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "values", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "V[]", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "length", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "LruBuffer", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "number", + "code_kind": 171 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "clamp", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "ScopeType", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "lowerObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + }, + { + "name": "upperObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "contains", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "range", + "type": "Scope", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "contains", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "range", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "expand", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "lowerObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + }, + { + "name": "upperObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Scope", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "expand", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Scope", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "expand", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "range", + "type": "Scope", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Scope", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getLower", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "ScopeType", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "getUpper", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "ScopeType", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "intersect", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "lowerObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + }, + { + "name": "upperObj", + "type": "ScopeType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Scope", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "intersect", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "range", + "type": "Scope", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Scope", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "toString", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Scope", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "encoding", + "type": "string", + "is_optional": true, + "has_default": false + }, + { + "name": "options", + "type": "{ fatal?: boolean; ignoreBOM?: boolean; }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextDecoder", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "decode", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "input", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "{ stream?: false; }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextDecoder", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "decodeWithStream", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "input", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "DecodeWithStreamOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextDecoder", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encode", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "input", + "type": "string", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextEncoder", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.d.ts", + "api_info": { + "line": 615, + "problem": "WhiteList", + "api_name": "encodeInto", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "input", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "dest", + "type": "Uint8Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextEncoder", + "api_type": "ClassDeclaration" + }, + { + "api_name": "util", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "{ read: number; written: number; }", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "[Symbol.iterator]", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "add", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "clear", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "clone", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "Vector", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "constructor", + "api_type": "ConstructorDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 176 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "convertToArray", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "Array", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "copyToArray", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "array", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "forEach", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, vector?: Vector) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "get", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getCapacity", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getFirstElement", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getIndexFrom", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getIndexOf", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getIndexOf", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getLastIndexFrom", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "getLastIndexOf", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "has", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "has", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "newCapacity", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "insert", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "isEmpty", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "remove", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "element", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "removeByIndex", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "removeByRange", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "fromIndex", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "toIndex", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "replaceAllElements", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackFn", + "type": "(value: T, index?: number, vector?: Vector) => T", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "Object", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "set", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "element", + "type": "T", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "setLength", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "newSize", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "sort", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "comparator", + "type": "(firstValue: T, secondValue: T) => number", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "subVector", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "fromIndex", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "toIndex", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "Vector", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "toString", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "trimToCurrentLength", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.util.Vector.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "length", + "api_type": "PropertyDeclaration", + "api_optional": false, + "parent_api": [ + { + "api_name": "Vector", + "api_type": "ClassDeclaration" + } + ], + "api_property_type": "number", + "code_kind": 171 + }, + "import_path": [ + "@ohos.util.Vector", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "convert", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "xml", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "ConvertOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ConvertXML", + "api_type": "ClassDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 174 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "fastConvertToJSObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "xml", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "ConvertOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ConvertXML", + "api_type": "ClassDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 174 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "convertToJSObject", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "xml", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "options", + "type": "ConvertOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ConvertXML", + "api_type": "ClassDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 174 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "trim", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreDeclaration", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreInstruction", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreAttributes", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreComment", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreCDATA", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreDoctype", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "ignoreText", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "boolean", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "declarationKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "instructionKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "attributesKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "textKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "cdataKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "doctypeKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "commentKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "parentKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "typeKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "nameKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.convertxml.d.ts", + "api_info": { + "line": 349, + "problem": "WhiteList", + "api_name": "elementsKey", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ConvertOptions", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "xml", + "api_type": "ModuleDeclaration" + } + ], + "api_property_type": "string", + "code_kind": 170 + }, + "import_path": [ + "@ohos.convertxml", + "@kit.ArkTS" + ], + "is_global": false + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts b/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..83518dc9571dafd6a6f6c849db7870fec9581068 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type * as ts from 'typescript'; +import type { LinterOptions } from '../LinterOptions'; +import type { FixedLineProgressBar } from './FixedLineProgressBar'; +import type { MigrationInfo } from './MigrationInfo'; + +export interface CmdProgressInfo { + cmdProgressBar: FixedLineProgressBar; + options: LinterOptions; + migrationInfo?: MigrationInfo; + srcFiles: ts.SourceFile[]; +} diff --git a/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts new file mode 100644 index 0000000000000000000000000000000000000000..4eb68d553bc9515852861a543cbf20299159ed04 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import chalk from 'chalk'; +import * as cliProgress from 'cli-progress'; +import type { CmdProgressInfo } from './CmdProgressInfo'; +import type { ProgressPayload } from './ProgressPayload'; + +export class FixedLineProgressBar { + private readonly bar: cliProgress.SingleBar; + private currentTask: string = ''; + private currentStatus: string = ''; + private isActive = false; + private lastOutput = ''; + private static fixedLinePosition = 0; + private readonly minBarWidth = 20; + private readonly fixedPartsWidth = 40; + private resizeListener: (() => void) | null = null; + private lastTerminalWidth: number = 0; + + constructor() { + this.bar = new cliProgress.SingleBar( + { + format: (options, params, payload): string => { + return this.generateBarString(params.progress, payload); + }, + barCompleteChar: '\u2588', + barIncompleteChar: '\u2591', + hideCursor: true, + clearOnComplete: false, + stopOnComplete: true, + linewrap: false, + forceRedraw: true, + autopadding: true, + noTTYOutput: true, + notTTYSchedule: 0 + }, + cliProgress.Presets.shades_grey + ); + + this.resizeListener = (): void => { + if (!this.isActive) { + return; + } + const currentWidth = process.stdout.columns || 80; + // Only redraw when width changes by more than 5 characters to avoid excessive refreshes + if (Math.abs(currentWidth - this.lastTerminalWidth) > 5) { + this.renderToFixedLine(); + this.lastTerminalWidth = currentWidth; + } + }; + process.stdout.on('resize', this.resizeListener); + this.lastTerminalWidth = process.stdout.columns || 80; + } + + private generateBarString(progress: number, payload: ProgressPayload): string { + const terminalWidth = process.stdout.columns || 80; + const availableWidth = terminalWidth - this.fixedPartsWidth; + const barWidth = Math.max(this.minBarWidth, availableWidth); + + const completedLength = Math.max(0, Math.min(barWidth, Math.floor(progress * barWidth))); + const remainingLength = Math.max(0, barWidth - completedLength); + + const completedBar = this.bar.options.barCompleteChar!.repeat(completedLength); + const remainingBar = this.bar.options.barIncompleteChar!.repeat(remainingLength); + const progressBar = `${completedBar}${remainingBar}`; + + const progressPercent = Math.round(progress * 100); + const statusColor = + payload.status === 'scanning' ? chalk.blue : payload.status === 'fixing' ? chalk.yellow : chalk.green; + + return `${chalk.bold(payload.task)} ${statusColor(payload.statusText)} [${progressBar}] ${progressPercent}%`; + } + + startBar(taskName: string, total: number, initialStatus: 'scanning' | 'fixing'): void { + this.isActive = true; + this.currentTask = taskName; + this.currentStatus = initialStatus; + this.lastTerminalWidth = process.stdout.columns || 80; + + this.bar.start(total, 0, { + task: `${taskName.padEnd(12)}`, + status: initialStatus, + statusText: FixedLineProgressBar.getStatusText(initialStatus) + }); + + this.renderToFixedLine(); + } + + updateBar(progress: number, status: 'scanning' | 'fixing'): void { + if (!this.isActive) { + return; + } + + if (status !== this.currentStatus) { + this.currentStatus = status; + this.bar.update(progress, { + status, + statusText: FixedLineProgressBar.getStatusText(status) + }); + } else { + this.bar.update(progress); + } + + this.renderToFixedLine(); + } + + completeBar(): void { + if (!this.isActive) { + return; + } + + this.bar.update(this.bar.getTotal(), { + status: 'completed', + statusText: 'Completed' + }); + + this.renderToFixedLine(); + this.isActive = false; + } + + skipBar(): void { + if (!this.isActive) { + return; + } + + this.bar.update(0, { + status: 'skipped', + statusText: 'No files need to be fixed --- skipped' + }); + + this.renderToFixedLine(); + this.isActive = false; + } + + private renderToFixedLine(): void { + const content = this.bar.lastDrawnString || ''; + + FixedLineProgressBar.moveToFixedLine(); + process.stderr.write('\x1B[2K'); + process.stderr.write(content); + FixedLineProgressBar.restoreCursor(); + + this.lastOutput = content; + FixedLineProgressBar.fixedLinePosition = 1; + } + + static getStatusText(status: string): string { + const statusMap: Record = { + scanning: chalk.blue('Scanning...'), + fixing: chalk.yellow('Fixing...'), + skipped: chalk.magenta('Skipped'), + completed: chalk.green('Completed') + }; + return statusMap[status] || ''; + } + + static moveToFixedLine(): void { + const linesToMove = FixedLineProgressBar.fixedLinePosition; + if (linesToMove > 0) { + process.stderr.write(`\x1B[${linesToMove}F`); + } + process.stderr.write('\x1B[0G'); + } + + static restoreCursor(): void { + const linesToMove = FixedLineProgressBar.fixedLinePosition; + if (linesToMove > 0) { + process.stderr.write(`\x1B[${linesToMove}E`); + } + } + + stop(): void { + if (this.isActive) { + this.isActive = false; + process.stderr.write('\x1B[1F\x1B[0G\x1B[2K'); + } + + if (this.resizeListener) { + process.stdout.off('resize', this.resizeListener); + this.resizeListener = null; + } + } +} + +export function preProcessCmdProgressBar(cmdProgressInfo: CmdProgressInfo): void { + const { options, cmdProgressBar, srcFiles } = cmdProgressInfo; + + const isMigrationStep = options.migratorMode && cmdProgressInfo.migrationInfo; + const migrationPhase = isMigrationStep ? + ` ${cmdProgressInfo.migrationInfo!.currentPass + 1} / ${cmdProgressInfo.migrationInfo!.maxPasses}` : + ''; + const phasePrefix = isMigrationStep ? 'Migration Phase' : 'Scan Phase'; + const displayContent = `${phasePrefix}${migrationPhase}`; + const totalFiles = srcFiles.length; + + if (isMigrationStep) { + cmdProgressBar.startBar(displayContent, totalFiles, 'fixing'); + if (!srcFiles || srcFiles.length === 0) { + cmdProgressBar.skipBar(); + } + } else { + cmdProgressBar.startBar(displayContent, totalFiles, 'scanning'); + } +} + +export function processCmdProgressBar(cmdProgressInfo: CmdProgressInfo, fileCount: number): void { + const progress = fileCount; + const status = cmdProgressInfo.options.migratorMode && cmdProgressInfo.migrationInfo ? 'fixing' : 'scanning'; + + cmdProgressInfo.cmdProgressBar.updateBar(progress, status); +} + +export function postProcessCmdProgressBar(cmdProgressInfo: CmdProgressInfo): void { + const { cmdProgressBar, srcFiles } = cmdProgressInfo; + + if (srcFiles.length > 0) { + cmdProgressBar.completeBar(); + + process.stderr.write('\n'); + } else { + cmdProgressBar.skipBar(); + process.stderr.write('\n'); + } +} diff --git a/ets2panda/linter/src/lib/progress/MigrationInfo.ts b/ets2panda/linter/src/lib/progress/MigrationInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..6bfafb5f08f656f7d2a259a2b9c6314bfd41f8f0 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/MigrationInfo.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 interface MigrationInfo { + currentPass: number; + maxPasses: number; +} diff --git a/ets2panda/linter/src/lib/progress/ProgressBarInfo.ts b/ets2panda/linter/src/lib/progress/ProgressBarInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..689e2215885383b1dae6a53063d99dad6ad63832 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/ProgressBarInfo.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 type * as ts from 'typescript'; +import type { LinterOptions } from '../LinterOptions'; +import type { MigrationInfo } from './MigrationInfo'; + +export interface ProgressBarInfo { + migrationInfo?: MigrationInfo; + currentSrcFile: ts.SourceFile; + srcFiles: ts.SourceFile[]; + options: LinterOptions; +} diff --git a/ets2panda/linter/src/lib/progress/ProgressPayload.ts b/ets2panda/linter/src/lib/progress/ProgressPayload.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae171ceba1a528ca28dc6b0f55082a87f6a67007 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/ProgressPayload.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 interface ProgressPayload { + task: string; + status: 'scanning' | 'fixing' | 'completed' | 'skipped'; + statusText: string; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/CountFile.ts b/ets2panda/linter/src/lib/statistics/scan/CountFile.ts new file mode 100644 index 0000000000000000000000000000000000000000..04f0166f357d2edf02567784d0c2662214963efb --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/CountFile.ts @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 { promisify } from 'util'; + +// Define file type extensions +const FILE_TYPES: { [key: string]: string[] } = { + 'C/C++': ['.c', '.h', '.cpp', '.hpp'], + JavaScript: ['.js'], + TypeScript: ['.ts'], + JSON: ['.json', '.json5'], + XML: ['.xml'], + ArkTS: ['.ets'], + 'ArkTS Test': ['.test.ets'] +}; + +// Comment regex patterns by file type +const COMMENT_REGEX1: { [key: string]: RegExp } = { + 'C/C++': /\/\/.*/g, + JavaScript: /\/\/.*/g, + TypeScript: /\/\/.*/g, + ArkTS: /\/\/.*/g, + 'ArkTS Test': /\/\/.*/g, + XML: //g +}; + +const COMMENT_REGEX2: { [key: string]: RegExp } = { + 'C/C++': /\/\*.*?\*\//gs, + JavaScript: /\/\*.*?\*\//gs, + TypeScript: /\/\*.*?\*\//gs, + ArkTS: /\/\*.*?\*\//gs, + 'ArkTS Test': /\/\*.*?\*\//gs +}; + +/** + * Remove comments from file content + */ +function removeComments(content: string, fileType: string): string { + if (COMMENT_REGEX1[fileType]) { + content = content.replace(COMMENT_REGEX1[fileType], ''); + } + if (COMMENT_REGEX2[fileType]) { + content = content.replace(COMMENT_REGEX2[fileType], ''); + } + return content; +} + +/** + * Count valid lines of code (excluding comments and empty lines) + */ +async function countLines(filePath: string, fileType: string): Promise { + try { + const content = await promisify(fs.readFile)(filePath, 'utf-8'); + const cleanedContent = removeComments(content, fileType); + const lines = cleanedContent.split('\n'); + + // Filter out empty lines + const validLines = lines.filter((line) => { + return line.trim(); + }); + return validLines.length; + } catch (error) { + console.error(`Error reading ${filePath}: ${error}`); + return 0; + } +} + +/** + * Merge multiple result objects + */ +function mergeAllResults(results: { [key: string]: { fileCount: number; lineCount: number } }[]): { + [key: string]: { fileCount: number; lineCount: number }; +} { + const combined: { [key: string]: { fileCount: number; lineCount: number } } = {}; + + for (const result of results) { + for (const [type, counts] of Object.entries(result)) { + if (!combined[type]) { + combined[type] = { fileCount: 0, lineCount: 0 }; + } + combined[type].fileCount += counts.fileCount; + combined[type].lineCount += counts.lineCount; + } + } + + return combined; +} + +/** + * Process directory entries recursively + */ +async function walkDir(dir: string): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + try { + const entries = await promisify(fs.readdir)(dir, { withFileTypes: true }); + const fileResults = await processFiles(dir, entries); + const dirResults = await processDirs(dir, entries); + return mergeAllResults([fileResults, dirResults]); + } catch (error) { + console.error(`Error reading ${dir}: ${error}`); + return {}; + } +} + +/** + * Process files in a directory + */ +async function processFiles( + dir: string, + entries: fs.Dirent[] +): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + const fileResults = await Promise.all( + entries. + filter((entry) => { + return entry.isFile(); + }). + map(async(entry) => { + return processFileEntry(dir, entry); + }) + ); + return mergeAllResults(fileResults); +} + +/** + * Process a single file entry + */ +async function processFileEntry( + dir: string, + entry: fs.Dirent +): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + const fullPath = path.join(dir, entry.name); + + for (const fileType in FILE_TYPES) { + const extensions = FILE_TYPES[fileType]; + const ext = path.extname(entry.name); + + if (extensions.includes(ext)) { + const lines = await countLines(fullPath, fileType); + return { + [fileType]: { + fileCount: 1, + lineCount: lines + } + }; + } + } + + return {}; +} + +/** + * Process subdirectories recursively + */ +async function processDirs( + dir: string, + entries: fs.Dirent[] +): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + const dirEntries = entries.filter((entry) => { + return entry.isDirectory(); + }); + const dirResults = await Promise.all( + dirEntries.map((entry) => { + return walkDir(path.join(dir, entry.name)); + }) + ); + return mergeAllResults(dirResults); +} + +/** + * Analyze directory and count files/lines by type + */ +async function analyzeDirectory( + directory: string +): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + // Initialize results + const results: { [key: string]: { fileCount: number; lineCount: number } } = {}; + for (const fileType in FILE_TYPES) { + results[fileType] = { fileCount: 0, lineCount: 0 }; + } + + const finalResults = await walkDir(directory); + Object.assign(results, finalResults); + return results; +} + +/** + * Main export function + */ +export async function countFiles( + directory: string +): Promise<{ [key: string]: { fileCount: number; lineCount: number } }> { + try { + const stats = await promisify(fs.stat)(directory); + if (stats.isDirectory()) { + return await analyzeDirectory(directory); + } + console.error('The directory is invalid!'); + return {}; + } catch (error) { + console.error('Read directory failed', error); + return {}; + } +} diff --git a/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts b/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0bfafbcd8629650b9efe04308054e79730ab785 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.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 * as fs from 'fs'; +import * as path from 'path'; +import { Logger } from '../../Logger'; +import type { NapiFileStatisticInfo } from './NapiFileStatisticInfo'; + +const EXTENSIONS = ['.c', '.cpp', '.cc', '.cxx', '.h', '.hpp', '.hh', '.hxx']; + +const SINGLE_LINE_COMMENT_REGEX = /\/\/.*/g; +const MULTI_LINE_COMMENT_REGEX = /\/\*[\s\S]*?\*\//g; + +const DEFAULT_STATISTICS: NapiFileStatisticInfo = { + totalFiles: 0, + totalLines: 0, + napiFiles: 0, + napiLines: 0, + napiFileLines: 0 +}; + +function removeComments(content: string): string { + return content.replace(MULTI_LINE_COMMENT_REGEX, '').replace(SINGLE_LINE_COMMENT_REGEX, ''); +} + +async function countLines(filePath: string): Promise { + try { + const content = await fs.promises.readFile(filePath, 'utf-8'); + const contentWithoutComments = removeComments(content); + const validLines = contentWithoutComments.split('\n').filter((line) => { + return line.trim(); + }); + return validLines.length; + } catch (e) { + Logger.error(`Error reading ${filePath}: ${e}`); + return 0; + } +} + +async function countNapiLines(filePath: string): Promise { + try { + const content = await fs.promises.readFile(filePath, 'utf-8'); + const lines = content.split('\n'); + const napiLines = new Set(); + + for (const line of lines) { + if (line.toLowerCase().includes('napi')) { + napiLines.add(line); + } + } + + return napiLines.size; + } catch (e) { + Logger.error(`Error reading ${filePath}: ${e}`); + return 0; + } +} + +async function analyzeDirectoryAsync(directory: string): Promise { + const dirQueue: string[] = [directory]; + const allResults: NapiFileStatisticInfo[] = []; + + while (dirQueue.length > 0) { + const currentDir = dirQueue.shift()!; + const entries = await fs.promises.readdir(currentDir, { withFileTypes: true }); + const fileResults = await Promise.all( + entries. + map((entry) => { + const fullPath = path.join(currentDir, entry.name); + if (entry.isDirectory()) { + dirQueue.push(fullPath); + return null; + } else if (isTargetFile(entry.name)) { + return processFile(fullPath); + } + return null; + }). + filter(Boolean) as Promise[] + ); + allResults.push(...fileResults); + } + + return allResults.reduce( + (acc, cur) => { + acc.totalFiles += cur.totalFiles; + acc.totalLines += cur.totalLines; + if (cur.napiFiles > 0) { + acc.napiFiles += cur.napiFiles; + acc.napiLines += cur.napiLines; + acc.napiFileLines += cur.napiFileLines; + } + return acc; + }, + { ...DEFAULT_STATISTICS } + ); +} + +async function processFile(filePath: string): Promise { + const result: NapiFileStatisticInfo = { + totalFiles: 1, + totalLines: 0, + napiFiles: 0, + napiLines: 0, + napiFileLines: 0 + }; + + try { + const [lines, napiCount] = await Promise.all([countLines(filePath), countNapiLines(filePath)]); + + result.totalLines = lines; + if (napiCount > 0) { + result.napiFiles = 1; + result.napiLines = napiCount; + result.napiFileLines = lines; + } + } catch (e) { + Logger.error(`Error processing ${filePath}: ${e}`); + } + return result; +} + +function isTargetFile(filename: string): boolean { + return EXTENSIONS.some((ext) => { + return filename.endsWith(ext); + }); +} + +export async function countNapiFiles(directory: string): Promise { + try { + const stat = await fs.promises.stat(directory); + if (!stat.isDirectory()) { + Logger.error('The provided path is not a directory!'); + return DEFAULT_STATISTICS; + } + return await analyzeDirectoryAsync(directory); + } catch (e) { + Logger.error(`Error accessing directory ${directory}: ${e}`); + return DEFAULT_STATISTICS; + } +} diff --git a/ets2panda/linter/src/lib/statistics/scan/FloderScanResultInfo.ts b/ets2panda/linter/src/lib/statistics/scan/FloderScanResultInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..447813a2d2df7baf6b55caf1056c8a5231f27a0e --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/FloderScanResultInfo.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. + */ + +export interface FloderScanResultInfo { + normalizedPath: string; + arkTSCodeLines: number; + cAndCPPCodeLines: number; + napiCodeLines: number; + jsCodeLines: number; + tsCodeLines: number; + jsonCodeLines: number; + xmlCodeLines: number; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/NapiFileStatisticInfo.ts b/ets2panda/linter/src/lib/statistics/scan/NapiFileStatisticInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..20b324380215c2eb4c542e833a8d7eb2f7a8bffd --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/NapiFileStatisticInfo.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. + */ + +export interface NapiFileStatisticInfo { + totalFiles: number; + totalLines: number; + napiFiles: number; + napiLines: number; + napiFileLines: number; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/ProblemNumbersInfo.ts b/ets2panda/linter/src/lib/statistics/scan/ProblemNumbersInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..d969313546fc3883371a58401a0c74a87cf1ad9d --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/ProblemNumbersInfo.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. + */ + +export interface ProblemNumbersInfo { + totalProblemNumbers: number; + arkOnePointOneProblemNumbers: number; + arkOnePointTWOProblemNumbers: number; + canBeAutoFixedproblemNumbers: number; + needToManualFixproblemNumbers: number; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsCommonFunction.ts b/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsCommonFunction.ts new file mode 100644 index 0000000000000000000000000000000000000000..e8e8f93510106e82eda0a9a245e7856ff5aa23a5 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsCommonFunction.ts @@ -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. + */ + +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { LintRunResult } from '../../LintRunResult'; +import { Logger } from '../../Logger'; +import type { ProblemInfo } from '../../ProblemInfo'; +import * as mk from '../../utils/consts/MapKeyConst'; +import { countFiles } from './CountFile'; +import { countNapiFiles } from './CountNapiFile'; +import type { ProblemNumbersInfo } from './ProblemNumbersInfo'; +import type { ProblemStatisticsInfo } from './ProblemStatisticsInfo'; +import type { RuleDetailedErrorInfo } from './RuleDetailedErrorInfo'; +import type { StatisticsReportInPutInfo } from './StatisticsReportInPutInfo'; +import type { TimeRecorder } from './TimeRecorder'; +import { WorkLoadInfo } from './WorkLoadInfo'; +import { getAllLinterRules } from '../../utils/functions/ConfiguredRulesProcess'; + +export function getProblemStatisticsInfo( + problemNumbers: ProblemNumbersInfo, + ruleToNumbersMap: Map, + ruleToAutoFixedNumbersMap: Map, + timeRecorder: TimeRecorder, + WorkLoadInfo?: WorkLoadInfo +): ProblemStatisticsInfo { + const problemNumberMap: Map = new Map(); + problemNumberMap.set(mk.TOTAL_PROBLEMS, problemNumbers.totalProblemNumbers); + problemNumberMap.set(mk.ONE_POINT_ONE_PROBLEMS, problemNumbers.arkOnePointOneProblemNumbers); + problemNumberMap.set(mk.ONE_POINT_TWO_PROBLEMS, problemNumbers.arkOnePointTWOProblemNumbers); + problemNumberMap.set(mk.CAN_BE_AUTO_FIXED_PROBLEMS_NUMBERS, problemNumbers.canBeAutoFixedproblemNumbers); + problemNumberMap.set(mk.NEED_TO_NAMUAL_FIX_PROBLEM_NUMBERS, problemNumbers.needToManualFixproblemNumbers); + + const scanTime = timeRecorder.getScanTime(); + const migrationTime = timeRecorder.getMigrationTime(); + const usedTimeMap: Map = new Map(); + usedTimeMap.set(mk.SCAN_TIME, scanTime); + usedTimeMap.set(mk.MIGRATION_TIME, migrationTime); + + const detailRuleProblemsMap: Map = new Map(); + ruleToNumbersMap.forEach((value, key) => { + const ruleDetailedErrorInfo: RuleDetailedErrorInfo = { + rule: key, + problemNumbers: value, + canBeAutoFixedMumbers: ruleToAutoFixedNumbersMap.get(key) ?? 0 + }; + detailRuleProblemsMap.set(key, ruleDetailedErrorInfo); + }); + + const problemStatisticsInfo: ProblemStatisticsInfo = { + problems: Object.fromEntries(problemNumberMap), + usedTime: Object.fromEntries(usedTimeMap), + WorkLoadInfo: WorkLoadInfo, + eachRuleProblemsDetail: Array.from(detailRuleProblemsMap.values()) + }; + return problemStatisticsInfo; +} + +export function getArktsOnePointOneProlemNumbers(problems: ProblemInfo[]): number { + let problemNumbersForATSOnePointOne: number = 0; + const signForOne: string = 's2d'; + problems.forEach((problem) => { + if (problem.rule !== undefined) { + if (problem.rule.includes(signForOne)) { + problemNumbersForATSOnePointOne = problemNumbersForATSOnePointOne + 1; + } + } + }); + return problemNumbersForATSOnePointOne; +} + +export function accumulateRuleNumbers( + problems: ProblemInfo[], + ruleToNumbersMap: Map, + ruleToAutoFixedNumbersMap: Map +): void { + const regex = /.*\(([^)]+)\)[^(]*$/; + problems.forEach((problem) => { + if (problem.rule !== undefined) { + const match = problem.rule.match(regex); + if (match?.[1]?.trim()) { + if (problem.autofix) { + const currentNumber = ruleToAutoFixedNumbersMap.get(match[1]) || 0; + ruleToAutoFixedNumbersMap.set(match[1], currentNumber + 1); + } + const currentNumber = ruleToNumbersMap.get(match[1]) || 0; + ruleToNumbersMap.set(match[1], currentNumber + 1); + } + } + }); +} + +export async function generateReportFile(reportName: string, reportData, reportPath?: string): Promise { + let reportFilePath = path.join(reportName); + if (reportPath !== undefined) { + reportFilePath = path.join(path.normalize(reportPath), reportName); + } + try { + await fs.promises.mkdir(path.dirname(reportFilePath), { recursive: true }); + await fs.promises.writeFile(reportFilePath, JSON.stringify(reportData, null, 2)); + } catch (error) { + Logger.error(`Error generating report file:${error}`); + } +} + +export function generateReportFileSync(reportName: string, reportData: any, reportPath?: string): void { + let reportFilePath = reportName; + if (reportPath !== undefined) { + reportFilePath = path.join(path.normalize(reportPath), reportName); + } + try { + fs.mkdirSync(path.dirname(reportFilePath), { recursive: true }); + fs.writeFileSync(reportFilePath, JSON.stringify(reportData, null, 2)); + } catch (error) { + Logger.error(`Error generating report file:${error}`); + } +} + +export function getMapValueSum(map: Map): number { + let result = 0; + for (const value of map.values()) { + result += value; + } + return result; +} + +export async function generateScanProbelemStatisticsReport( + statisticsReportInPutInfo: StatisticsReportInPutInfo +): Promise { + const canBeAutoFixedproblemNumbers = getMapValueSum(statisticsReportInPutInfo.ruleToAutoFixedNumbersMap); + const problemNumbers: ProblemNumbersInfo = { + totalProblemNumbers: statisticsReportInPutInfo.totalProblemNumbers, + arkOnePointOneProblemNumbers: statisticsReportInPutInfo.arkOnePointOneProblemNumbers, + arkOnePointTWOProblemNumbers: + statisticsReportInPutInfo.totalProblemNumbers - statisticsReportInPutInfo.arkOnePointOneProblemNumbers, + canBeAutoFixedproblemNumbers: canBeAutoFixedproblemNumbers, + needToManualFixproblemNumbers: statisticsReportInPutInfo.totalProblemNumbers - canBeAutoFixedproblemNumbers + }; + const projectFolderList = statisticsReportInPutInfo.cmdOptions.linterOptions.projectFolderList!; + const workLoadInfo = await getWorkLoadInfo(projectFolderList); + workLoadInfo.calculateFixRate(problemNumbers); + const statisticsReportData = getProblemStatisticsInfo( + problemNumbers, + getProcessedRuleToNumbersMap(statisticsReportInPutInfo.ruleToNumbersMap, statisticsReportInPutInfo.allLinterRules), + statisticsReportInPutInfo.ruleToAutoFixedNumbersMap, + statisticsReportInPutInfo.timeRecorder, + workLoadInfo + ); + await generateReportFile( + statisticsReportInPutInfo.statisticsReportName, + statisticsReportData, + statisticsReportInPutInfo.cmdOptions.outputFilePath + ); +} + +function getProcessedRuleToNumbersMap( + ruleToNumbersMap: Map, + allLinterRules: string[] +): Map { + const processedRuleToNumbersMap: Map = new Map(); + const homecheckRuleToNumbersMap: Map = ruleToNumbersMap; + allLinterRules.forEach((ruleName) => { + const ruleNumber = ruleToNumbersMap.get(ruleName) || 0; + homecheckRuleToNumbersMap.delete(ruleName); + processedRuleToNumbersMap.set(ruleName, ruleNumber); + }); + + homecheckRuleToNumbersMap.forEach((number, ruleName) => { + processedRuleToNumbersMap.set(ruleName, number); + }); + + return processedRuleToNumbersMap; +} + +export function generateMigrationStatisicsReport( + lintResult: LintRunResult, + timeRecorder: TimeRecorder, + outputFilePath?: string +): void { + const ruleToNumbersMap: Map = new Map(); + const ruleToAutoFixedNumbersMap: Map = new Map(); + let arkOnePointOneProblemNumbers: number = 0; + + const problemsInfoAfterAutofixed = lintResult.problemsInfos; + for (const problems of problemsInfoAfterAutofixed.values()) { + accumulateRuleNumbers(problems, ruleToNumbersMap, ruleToAutoFixedNumbersMap); + arkOnePointOneProblemNumbers = arkOnePointOneProblemNumbers + getArktsOnePointOneProlemNumbers(problems); + } + + let totalProblemNumbers: number = 0; + for (const problems of problemsInfoAfterAutofixed.values()) { + totalProblemNumbers += problems.length; + } + + const canBeAutoFixedproblemNumbers = getMapValueSum(ruleToAutoFixedNumbersMap); + + const problemNumbers: ProblemNumbersInfo = { + totalProblemNumbers: totalProblemNumbers, + arkOnePointOneProblemNumbers: arkOnePointOneProblemNumbers, + arkOnePointTWOProblemNumbers: totalProblemNumbers - arkOnePointOneProblemNumbers, + canBeAutoFixedproblemNumbers: canBeAutoFixedproblemNumbers, + needToManualFixproblemNumbers: totalProblemNumbers - canBeAutoFixedproblemNumbers + }; + + const statisticsReportData = getProblemStatisticsInfo( + problemNumbers, + getProcessedRuleToNumbersMap(ruleToNumbersMap, getAllLinterRules()), + ruleToAutoFixedNumbersMap, + timeRecorder + ); + const statisticsReportName: string = 'migration-results-statistics.json'; + generateReportFileSync(statisticsReportName, statisticsReportData, outputFilePath); +} + +export async function getWorkLoadInfo(projectPathList: string[]): Promise { + const workloadInfo = new WorkLoadInfo(); + const projectResults = await Promise.all( + projectPathList.map(async(projectPath) => { + const normalizedPath = path.normalize(projectPath); + const [countFilesResults, countNapiFileResults] = await Promise.all([ + countFiles(normalizedPath), + countNapiFiles(normalizedPath) + ]); + + const getLines = (lang: keyof typeof countFilesResults): number => { + return countFilesResults[lang]?.lineCount || 0; + }; + + return { + normalizedPath, + arkTSCodeLines: getLines('ArkTS') + getLines('ArkTS Test'), + cAndCPPCodeLines: getLines('C/C++'), + napiCodeLines: countNapiFileResults.napiLines, + jsCodeLines: getLines('JavaScript'), + tsCodeLines: getLines('TypeScript'), + jsonCodeLines: getLines('JSON'), + xmlCodeLines: getLines('XML') + }; + }) + ); + + projectResults.forEach((result) => { + workloadInfo.addFloderResult(result); + }); + return workloadInfo; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsInfo.ts b/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..8bbef29b1616af2b7c19476f7a227c429bf6145d --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsInfo.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. + */ + +import type { RuleDetailedErrorInfo } from './RuleDetailedErrorInfo'; +import type { WorkLoadInfo } from './WorkLoadInfo'; + +export interface ProblemStatisticsInfo { + problems: { [k: string]: number }; + usedTime: { [k: string]: string }; + eachRuleProblemsDetail: RuleDetailedErrorInfo[]; + WorkLoadInfo?: WorkLoadInfo; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/RuleDetailedErrorInfo.ts b/ets2panda/linter/src/lib/statistics/scan/RuleDetailedErrorInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..b4c56ee615babc9f984bdb45ab357179e661b1cd --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/RuleDetailedErrorInfo.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 interface RuleDetailedErrorInfo { + rule: string; + problemNumbers: number; + canBeAutoFixedMumbers: number; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/ScanTaskRelatedInfo.ts b/ets2panda/linter/src/lib/statistics/scan/ScanTaskRelatedInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..6cc3f6dafdb3dcb3baa4d063562040b653996486 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/ScanTaskRelatedInfo.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 type { CommandLineOptions } from '../../CommandLineOptions'; +import type { LinterConfig } from '../../LinterConfig'; +import type { ProblemInfo } from '../../ProblemInfo'; +import type { StatisticsReportInPutInfo } from './StatisticsReportInPutInfo'; +import type { TimeRecorder } from './TimeRecorder'; + +export interface ScanTaskRelatedInfo { + cmdOptions: CommandLineOptions; + timeRecorder: TimeRecorder; + statisticsReportInPutInfo: StatisticsReportInPutInfo; + mergedProblems: Map; + homeCheckResult: Map; + totalProblemNumbers: number; + statisticsReportName: number; + compileOptions: LinterConfig; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/StatisticsReportInPutInfo.ts b/ets2panda/linter/src/lib/statistics/scan/StatisticsReportInPutInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..a841890f976e085f546d76fb5f527ea40c92d083 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/StatisticsReportInPutInfo.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 type { CommandLineOptions } from '../../CommandLineOptions'; +import type { TimeRecorder } from './TimeRecorder'; + +export class StatisticsReportInPutInfo { + totalProblemNumbers: number = 0; + arkOnePointOneProblemNumbers: number = 0; + ruleToNumbersMap: Map = {} as Map; + allLinterRules: string[] = [] as string[]; + ruleToAutoFixedNumbersMap: Map = {} as Map; + cmdOptions: CommandLineOptions = {} as CommandLineOptions; + timeRecorder: TimeRecorder = {} as TimeRecorder; + statisticsReportName: string = ''; +} diff --git a/ets2panda/linter/src/lib/statistics/scan/TimeRecorder.ts b/ets2panda/linter/src/lib/statistics/scan/TimeRecorder.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f21944a8125872db5d872bbc43402fc91b7c47d --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/TimeRecorder.ts @@ -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. + */ + +export class TimeRecorder { + private lintStart = BigInt(0); + private lintEnd = BigInt(0); + private migrationStart = BigInt(0); + private migrationEnd = BigInt(0); + private isHomeCheckCount: boolean = false; + + setHomeCheckCountStatus(isHomeCheckCount: boolean): void { + this.isHomeCheckCount = isHomeCheckCount; + } + + getHomeCheckCountStatus(): boolean { + return this.isHomeCheckCount; + } + + startScan(): void { + this.lintStart = process.hrtime.bigint(); + } + + endScan(): void { + this.lintEnd = process.hrtime.bigint(); + } + + startMigration(): void { + this.migrationStart = process.hrtime.bigint(); + } + + endMigration(): void { + this.migrationEnd = process.hrtime.bigint(); + } + + getScanTime(): string { + return `${(Number(this.lintEnd - this.lintStart) / 1000000000).toFixed(2)} s`; + } + + getMigrationTime(): string { + return `${(Number(this.migrationEnd - this.migrationStart) / 1000000000).toFixed(2)} s`; + } +} diff --git a/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts b/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..9376d475091674828b5e231efa3d0d33456ae601 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/scan/WorkLoadInfo.ts @@ -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. + */ + +import { + AVERAGE_LINE_FOR_REPAIRE_RULE_COEFFICIENT, + NPAI_REPAIRE_WORKLOADA_COEFFICIEN, + TEST_DEBUG_WORKLOAD_COEFFICIENT +} from '../../utils/consts/WorkloadRelatedConst'; +import type { FloderScanResultInfo } from './FloderScanResultInfo'; +import type { ProblemNumbersInfo } from './ProblemNumbersInfo'; + +export class WorkLoadInfo { + scanFilePathList: string[] = []; + totalArkTSCodeLines = 0; + totalCAndCPPCodeLines = 0; + totalNapiCodeLines = 0; + totalJsCodeLines = 0; + totalTsCodeLines = 0; + totalJsonCodeLines = 0; + totalXmlCodeLines = 0; + manualFixRate: string | undefined; + + addFloderResult(result: FloderScanResultInfo): void { + this.scanFilePathList.push(result.normalizedPath); + this.totalArkTSCodeLines += result.arkTSCodeLines; + this.totalCAndCPPCodeLines += result.cAndCPPCodeLines; + this.totalNapiCodeLines += result.napiCodeLines; + this.totalJsCodeLines += result.jsCodeLines; + this.totalTsCodeLines += result.tsCodeLines; + this.totalJsonCodeLines += result.jsonCodeLines; + this.totalXmlCodeLines += result.xmlCodeLines; + } + + calculateFixRate(problemNumbers: ProblemNumbersInfo): void { + const totalLines = this.totalArkTSCodeLines + this.totalCAndCPPCodeLines; + if (totalLines <= 0) { + this.manualFixRate = '0.00%'; + } + + const problemCount = problemNumbers.needToManualFixproblemNumbers; + const ratio = + (problemCount * AVERAGE_LINE_FOR_REPAIRE_RULE_COEFFICIENT * TEST_DEBUG_WORKLOAD_COEFFICIENT + + this.totalNapiCodeLines * NPAI_REPAIRE_WORKLOADA_COEFFICIEN) / + totalLines; + + this.manualFixRate = `${(ratio * 100).toFixed(2)}%`; + } +} diff --git a/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts index 290326c0fc66a1584faac14d1b9e8376931ab237..7ca65eeb23af233bc2105512addd6edd1d8b4b5d 100644 --- a/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts +++ b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts @@ -35,6 +35,10 @@ export function readDeclareFiles(SdkPath: string): string[] { return []; } const declarationsFileNames: string[] = []; + const commonPath = path.resolve(SdkPath, './component/common.d.ts'); + if (fs.existsSync(commonPath)) { + declarationsFileNames.push(path.resolve(SdkPath, './component/common.d.ts')); + } const declarationsPath = path.resolve(SdkPath, './build-tools/ets-loader/declarations'); if (!fs.existsSync(declarationsPath)) { throw new Error('get wrong sdkDefaultApiPath, declarationsPath not found'); diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index 6365fab13f26e8068d81b96e4bc91f9016f2576a..3aa1893629cf4d0872461b648811448b079a9595 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -19,7 +19,7 @@ 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'; @@ -44,16 +44,20 @@ 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 { InteropType, USE_STATIC } from './consts/InteropAPI'; import { ETS_MODULE, PATH_SEPARATOR, VALID_OHM_COMPONENTS_MODULE_PATH } from './consts/OhmUrl'; -import { EXTNAME_D_TS, EXTNAME_ETS, EXTNAME_JS, EXTNAME_TS } from './consts/ExtensionName'; -import { STRING_ERROR_LITERAL } from './consts/Literals'; +import { EXTNAME_ETS, EXTNAME_JS, EXTNAME_D_ETS } from './consts/ExtensionName'; +import { CONCAT_ARRAY, STRING_ERROR_LITERAL } from './consts/Literals'; +import { INT_MIN, INT_MAX, LARGE_NUMBER_MIN, LARGE_NUMBER_MAX } from './consts/NumericalConstants'; +import { IGNORE_TYPE_LIST } from './consts/TypesToBeIgnored'; +export const PROMISE_METHODS = new Set(['all', 'race', 'any', 'resolve', 'allSettled']); +export const PROMISE_METHODS_WITH_NO_TUPLE_SUPPORT = new Set(['all', 'race', 'any', 'allSettled']); export const SYMBOL = 'Symbol'; export const SYMBOL_CONSTRUCTOR = 'SymbolConstructor'; const ITERATOR = 'iterator'; export type CheckType = (this: TsUtils, t: ts.Type) => boolean; + export class TsUtils { constructor( private readonly tsTypeChecker: ts.TypeChecker, @@ -115,12 +119,23 @@ export class TsUtils { return false; } - static isEnumType(tsType: ts.Type): boolean { + static isEnumType(tsType: ts.Type, checkUnion?: boolean): boolean { // when type equals `typeof `, only symbol contains information about it's type. const isEnumSymbol = tsType.symbol && this.isEnum(tsType.symbol); // otherwise, we should analyze flags of the type itself const isEnumType = !!(tsType.flags & ts.TypeFlags.Enum) || !!(tsType.flags & ts.TypeFlags.EnumLiteral); - return isEnumSymbol || isEnumType; + + if (isEnumSymbol || isEnumType) { + return true; + } + + if (checkUnion && tsType.isUnion()) { + return tsType.types.some((t) => { + return TsUtils.isEnumType(t); + }); + } + + return false; } static isEnum(tsSymbol: ts.Symbol): boolean { @@ -248,7 +263,11 @@ export class TsUtils { } const declaration = this.getDeclarationNode(ident); - if (!declaration) { + if (!declaration || ident.text.includes(STRING_ERROR_LITERAL)) { + return false; + } + + if (!declaration || !ident.text.includes(STRING_ERROR_LITERAL)) { return true; } @@ -330,7 +349,7 @@ export class TsUtils { TsUtils.isTypeReference(tsType) && tsType.typeArguments?.length === 1 && tsType.target.typeParameters?.length === 1 && - tsType.getSymbol()?.getName() === 'ConcatArray' + tsType.getSymbol()?.getName() === CONCAT_ARRAY ); } @@ -462,16 +481,26 @@ export class TsUtils { } static isNullableUnionType(type: ts.Type): boolean { - if (type.isUnion()) { - for (const t of type.types) { - if (!!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null)) { - return true; - } + if (!type.isUnion()) { + return false; + } + + for (const t of type.types) { + if (TsUtils.isNullishType(t)) { + return true; } } + return false; } + /** + * Returns true if the given type is `null` or `undefined`. + */ + static isNullishType(t: ts.Type): boolean { + return !!(t.flags & ts.TypeFlags.Undefined) || !!(t.flags & ts.TypeFlags.Null); + } + static isMethodAssignment(tsSymbol: ts.Symbol | undefined): boolean { return ( !!tsSymbol && (tsSymbol.flags & ts.SymbolFlags.Method) !== 0 && (tsSymbol.flags & ts.SymbolFlags.Assignment) !== 0 @@ -783,7 +812,10 @@ export class TsUtils { return false; } // #14569: Check for Function type. - if (this.areCompatibleFunctionals(lhsType, rhsType)) { + if (this.skipStructuralTypingCheckForFunctionals(lhsType, rhsType)) { + return false; + } + if (this.skipCheckForArrayBufferLike(lhsType, rhsType)) { return false; } if (rhsType.isUnion() || lhsType.isUnion()) { @@ -821,18 +853,22 @@ export class TsUtils { isStrict: boolean = false ): boolean { if ( - TsUtils.reduceReference(lhsType) === TsUtils.reduceReference(rhsType) && - TsUtils.isTypeReference(lhsType) && - TsUtils.isTypeReference(rhsType) + TsUtils.reduceReference(lhsType) !== TsUtils.reduceReference(rhsType) || + !TsUtils.isTypeReference(lhsType) || + !TsUtils.isTypeReference(rhsType) ) { - const lhsArgs = lhsType.typeArguments; - const rhsArgs = rhsType.typeArguments; - if (lhsArgs && lhsArgs.length > 0) { - if (rhsArgs && rhsArgs.length > 0) { - return this.needToDeduceStructuralIdentity(lhsArgs[0], rhsArgs[0], rhsExpr, isStrict); + return false; + } + const lhsArgs = lhsType.typeArguments; + const rhsArgs = rhsType.typeArguments; + if (lhsArgs && lhsArgs.length > 0) { + if (rhsArgs && rhsArgs.length > 0) { + if (rhsArgs[0] === lhsArgs[0]) { + return false; } - return this.needToDeduceStructuralIdentity(lhsArgs[0], rhsType, rhsExpr, isStrict); + return this.needToDeduceStructuralIdentity(lhsArgs[0], rhsArgs[0], rhsExpr, isStrict); } + return this.needToDeduceStructuralIdentity(lhsArgs[0], rhsType, rhsExpr, isStrict); } return false; } @@ -878,6 +914,16 @@ export class TsUtils { return isStrictLhs && this.typeContainsNonSendableClassOrInterface(rhsType); } + skipCheckForArrayBufferLike(lhsType: string | ts.Type, rhsType: string | ts.Type): boolean { + const lhsIsArrayBufferLike = TsUtils.isArrayBufferType( + typeof lhsType === 'string' ? lhsType : this.tsTypeChecker.typeToString(lhsType) + ); + const rhsIsArrayBufferLike = TsUtils.isArrayBufferType( + typeof rhsType === 'string' ? rhsType : this.tsTypeChecker.typeToString(rhsType) + ); + return !!this.options.arkts2 && lhsIsArrayBufferLike && rhsIsArrayBufferLike; + } + private processExtendedParentTypes(typeA: ts.Type, typeB: ts.Type): boolean { /* @@ -1353,13 +1399,18 @@ export class TsUtils { parentSymbolCache = new Map(); - getParentSymbolName(symbol: ts.Symbol): string | undefined { + getParentSymbolName(symbol: ts.Symbol | undefined): string | undefined { + if (!symbol) { + return undefined; + } const cached = this.parentSymbolCache.get(symbol); if (cached) { return cached; } - const name = this.tsTypeChecker.getFullyQualifiedName(symbol); + const fullName = this.tsTypeChecker.getFullyQualifiedName(symbol); + const match = fullName.match(/['"](.*)['"]\.(.*)/); + const name = match ? match[2] : fullName; const dotPosition = name.lastIndexOf('.'); const result = dotPosition === -1 ? undefined : name.substring(0, dotPosition); this.parentSymbolCache.set(symbol, result); @@ -1645,6 +1696,28 @@ export class TsUtils { return false; } + isStdLongType(type: ts.Type | undefined): boolean { + if (!type) { + return false; + } + const sym = type.aliasSymbol; + return !!sym && sym.getName() === 'long' && this.isGlobalSymbol(sym); + } + + static ifLargerThanInt(node: ts.NumericLiteral, isPrefix: boolean): boolean { + const raw = node.getText(); + const value = isPrefix ? Number(raw) * -1 : Number(raw); + + return value < INT_MIN || value > INT_MAX; + } + + static isLargeNumericLiteral(node: ts.NumericLiteral, isPrefix: boolean): boolean { + const raw = node.getText(); + const value = isPrefix ? Number(raw) * -1 : Number(raw); + + return value < LARGE_NUMBER_MIN || value > LARGE_NUMBER_MAX; + } + isStdErrorType(type: ts.Type): boolean { const symbol = type.symbol; if (!symbol) { @@ -1856,12 +1929,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 ); } @@ -1876,11 +1949,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; } @@ -1922,12 +1995,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.getVariableSymbolDeclarationTypeNode(sym); - return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); + return typeNode !== undefined && TsUtils.isEsValueType(typeNode); } static isEsObjectSymbol(sym: ts.Symbol): boolean { @@ -1935,7 +2008,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 ); } @@ -2027,113 +2100,70 @@ export class TsUtils { return type; } - private areCompatibleFunctionals(lhsType: ts.Type, rhsType: ts.Type): boolean { + private skipStructuralTypingCheckForFunctionals(lhsType: ts.Type, rhsType: ts.Type): boolean { return ( (this.isStdFunctionType(lhsType) || TsUtils.isFunctionalType(lhsType)) && (this.isStdFunctionType(rhsType) || TsUtils.isFunctionalType(rhsType)) ); } - isIncompatibleFunctionals(lhsTypeNode: ts.TypeNode, rhsExpr: ts.Expression): boolean { - if (ts.isUnionTypeNode(lhsTypeNode)) { - for (let i = 0; i < lhsTypeNode.types.length; i++) { - if (!this.isIncompatibleFunctional(lhsTypeNode.types[i], rhsExpr)) { - return false; + areCompatibleFunctionalTypes(lhsType: ts.Type, rhsType: ts.Type): boolean { + if (lhsType.isUnion()) { + for (let i = 0; i < lhsType.types.length; i++) { + if (this.areCompatibleFunctionalTypes(lhsType.types[i], rhsType)) { + return true; } } - return true; + return false; } - return this.isIncompatibleFunctional(lhsTypeNode, rhsExpr); - } - private isIncompatibleFunctional(lhsTypeNode: ts.TypeNode, rhsExpr: ts.Expression): boolean { - const lhsType = this.tsTypeChecker.getTypeAtLocation(lhsTypeNode); - const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); - const lhsParams = this.getLhsFunctionParameters(lhsTypeNode); - const rhsParams = this.getRhsFunctionParameters(rhsExpr); + const lhsSignature = TsUtils.getFunctionalTypeSignature(lhsType); + const rhsSignature = TsUtils.getFunctionalTypeSignature(rhsType); + if (!lhsSignature || !rhsSignature) { + return true; + } - if (lhsParams !== rhsParams) { + if (lhsSignature.parameters.length < rhsSignature.parameters.length) { return false; } - if (TsUtils.isFunctionalType(lhsType)) { - const lhsFunctionReturnType = this.getFunctionType(lhsTypeNode); - const rhsReturnType = this.getReturnTypeFromExpression(rhsType); - if (lhsFunctionReturnType && rhsReturnType) { - return TsUtils.isVoidType(lhsFunctionReturnType) && !TsUtils.isVoidType(rhsReturnType); - } + const lhsReturnType = lhsSignature.getReturnType(); + const rhsReturnType = rhsSignature.getReturnType(); + if (lhsReturnType && rhsReturnType) { + return !(TsUtils.isVoidType(lhsReturnType) && !TsUtils.isVoidType(rhsReturnType)); } - return false; + + return true; } static isVoidType(tsType: ts.Type): boolean { return (tsType.getFlags() & ts.TypeFlags.Void) !== 0; } - private getRhsFunctionParameters(expr: ts.Expression): number { - const type = this.tsTypeChecker.getTypeAtLocation(expr); - const signatures = this.tsTypeChecker.getSignaturesOfType(type, ts.SignatureKind.Call); - if (signatures.length > 0) { - const signature = signatures[0]; - return signature.parameters.length; - } - return 0; + static isFunctionalType(type: ts.Type): boolean { + const callSigns = type.getCallSignatures(); + return callSigns && callSigns.length > 0; } - private getLhsFunctionParameters(typeNode: ts.TypeNode): number { - let current: ts.TypeNode = typeNode; - while (ts.isTypeReferenceNode(current)) { - const symbol = this.tsTypeChecker.getSymbolAtLocation(current.typeName); - if (!symbol) { - break; - } - - const declaration = symbol.declarations?.[0]; - if (!declaration || !ts.isTypeAliasDeclaration(declaration)) { - break; - } - - current = declaration.type; - } - if (ts.isFunctionTypeNode(current)) { - return current.parameters.length; - } - return 0; + static isArrayBufferType(typeStr: string): boolean { + const arrayBufferLikeArr = ['ArrayBuffer', 'ArrayBufferLike']; + return arrayBufferLikeArr.includes(typeStr); } - private getFunctionType(typeNode: ts.TypeNode): ts.Type | undefined { - let current: ts.TypeNode = typeNode; - while (ts.isTypeReferenceNode(current)) { - const symbol = this.tsTypeChecker.getSymbolAtLocation(current.typeName); - if (!symbol) { - break; - } - - const declaration = symbol.declarations?.[0]; - if (!declaration || !ts.isTypeAliasDeclaration(declaration)) { - break; - } - - current = declaration.type; - } - if (ts.isFunctionTypeNode(current)) { - return this.tsTypeChecker.getTypeAtLocation(current.type); + static getFunctionalTypeSignature(type: ts.Type): ts.Signature | undefined { + const callSigns = type.getCallSignatures(); + if (callSigns.length > 0) { + return callSigns[0]; } return undefined; } - private getReturnTypeFromExpression(type: ts.Type): ts.Type | undefined { - const signatures = this.tsTypeChecker.getSignaturesOfType(type, ts.SignatureKind.Call); - if (signatures.length > 0) { - const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signatures[0]); - return returnType; + static getFunctionReturnType(type: ts.Type): ts.Type | null { + const signatures = type.getCallSignatures(); + if (signatures.length === 0) { + return null; } - return undefined; - } - - static isFunctionalType(type: ts.Type): boolean { - const callSigns = type.getCallSignatures(); - return callSigns && callSigns.length > 0; + return signatures[0].getReturnType(); } isStdFunctionType(type: ts.Type): boolean { @@ -2171,7 +2201,7 @@ export class TsUtils { return true; } } - // We allow computed property names if expression is string literal or string Enum member + // In ArkTS 1.0, the computed property names are allowed if expression is string literal or string Enum member. return ( !this.options.arkts2 && (ts.isStringLiteralLike(expr) || this.isEnumStringLiteral(computedProperty.expression)) ); @@ -3481,17 +3511,39 @@ export class TsUtils { } } - static isNumberLike(type: ts.Type, typeText: string, isEnum: boolean): boolean { + isNumberLike(type: ts.Type): boolean { const typeFlags = type.flags; + const typeText = this.tsTypeChecker.typeToString(type); const isNumberLike = typeText === STRINGLITERAL_NUMBER || typeText === STRINGLITERAL_NUMBER_ARRAY || (typeFlags & ts.TypeFlags.NumberLiteral) !== 0 || - isEnum; + this.isNumericEnumType(type); return isNumberLike; } + isNumericEnumType(type: ts.Type): boolean { + if (!TsUtils.isEnumType(type, true)) { + 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; + } + static getModuleName(node: ts.Node): string | undefined { const currentFilePath = node.getSourceFile().fileName; if (!currentFilePath.includes('src')) { @@ -3538,7 +3590,7 @@ export class TsUtils { return false; } - projectPath.concat(PATH_SEPARATOR + currentModule); + projectPath = projectPath.concat(PATH_SEPARATOR + currentModule); } const importedFile = path.resolve(projectPath, importFilePath + extension); @@ -3568,6 +3620,10 @@ export class TsUtils { return !!originalIdentifier && this.isImportedFromJS(originalIdentifier); } + static isClassOrInterfaceDeclaration(d: ts.Declaration): d is ts.ClassDeclaration | ts.InterfaceDeclaration { + return ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d); + } + /** * Extracts the Identifier from the given node. returns undefined if no Identifier is found. * @@ -3646,6 +3702,13 @@ export class TsUtils { 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; @@ -3683,51 +3746,14 @@ export class TsUtils { 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) { + isArkts12File(sourceFile: ts.SourceFile): boolean { + if (!sourceFile?.fileName) { return false; } - const statements = sourceFile.statements; - return ( - ts.isExpressionStatement(statements[0]) && - ts.isStringLiteral(statements[0].expression) && - statements[0].expression.getText() === USE_STATIC - ); + if (sourceFile.fileName.endsWith(EXTNAME_D_ETS)) { + return true; + } + return !!this.options.inputFiles?.includes(path.normalize(sourceFile.fileName)); } static removeOrReplaceQuotes(str: string, isReplace: boolean): string { @@ -3744,62 +3770,6 @@ export class TsUtils { return str; } - static getCurrentModule(currentFileName: string): string { - const parts = currentFileName.split(PATH_SEPARATOR); - parts.pop(); - const currentModule = parts.join(PATH_SEPARATOR); - return currentModule; - } - - static resolveModuleAndCheckInterop(wholeProjectPath: string, callExpr: ts.CallExpression): InteropType | undefined { - const moduleName = callExpr.arguments[0]; - if (!ts.isStringLiteral(moduleName)) { - return undefined; - } - - const importedModule = path.resolve(wholeProjectPath, moduleName.text); - - const importedFile = TsUtils.resolveImportModule(importedModule); - if (!importedFile) { - return undefined; - } - - const importSource = ts.sys.readFile(importedFile); - if (!importSource) { - return undefined; - } - - return TsUtils.checkFileForInterop(importedFile, importSource); - } - - static resolveImportModule(importedModule: string): string | undefined { - const extensions = ['.ts', '.js', '.ets']; - for (const ext of extensions) { - const tryPath = path.resolve(importedModule + ext); - if (fs.existsSync(tryPath)) { - return tryPath; - } - } - - return undefined; - } - - static checkFileForInterop(fileName: string, importSource: string): InteropType { - if (fileName.endsWith(EXTNAME_JS)) { - return InteropType.JS; - } - - if (fileName.endsWith(EXTNAME_TS) && !fileName.endsWith(EXTNAME_D_TS)) { - return InteropType.TS; - } - - if (fileName.endsWith(EXTNAME_ETS) && !importSource.includes('\'use static\'')) { - return InteropType.LEGACY; - } - - return InteropType.NONE; - } - isJsImport(node: ts.Node): boolean { const symbol = this.trueSymbolAtLocation(node); if (symbol) { @@ -3855,4 +3825,130 @@ export class TsUtils { forEachNodeInSubtree(targetNode, callback, stopCondition); return found; } + + static typeContainsVoid(typeNode: ts.TypeNode): boolean { + if (ts.isUnionTypeNode(typeNode)) { + return typeNode.types.some((t) => { + return t.kind === ts.SyntaxKind.VoidKeyword; + }); + } + return typeNode.kind === ts.SyntaxKind.VoidKeyword; + } + + static isStdPromiseType(type: ts.Type): boolean { + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'Promise' && isStdLibrarySymbol(sym); + } + + static isStdPromiseLikeType(type: ts.Type): boolean { + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'PromiseLike' && isStdLibrarySymbol(sym); + } + + static checkStmtHasTargetIdentifier(stmt: ts.ExpressionStatement, target: string): boolean { + let current: ts.Node | undefined = stmt.expression; + + while (current) { + if (ts.isCallExpression(current)) { + current = current.expression; + continue; + } + + if (ts.isPropertyAccessExpression(current)) { + if (current.name.getText() === target) { + return true; + } + current = current.expression; + continue; + } + + break; + } + + return false; + } + + collectPropertiesFromClass( + classDecl: ts.ClassDeclaration, + result: { + staticProps: Map; + instanceProps: Map; + }, + isBase: boolean = false + ): void { + classDecl.members.forEach((member) => { + if (!ts.isPropertyDeclaration(member) || !member.name || !ts.isIdentifier(member.name)) { + return; + } + + const propName = member.name.text; + + const isPrivate = member.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.PrivateKeyword; + }); + if (isBase && isPrivate) { + return; + } + + const propType = this.tsTypeChecker.getTypeAtLocation(member); + const isStatic = member.modifiers?.some((m) => { + return m.kind === ts.SyntaxKind.StaticKeyword; + }); + + if (isStatic) { + result.staticProps.set(propName, propType); + } else { + result.instanceProps.set(propName, propType); + } + }); + + const heritage = classDecl.heritageClauses?.find((h) => { + return h.token === ts.SyntaxKind.ExtendsKeyword; + }); + if (heritage) { + const baseTypeNode = heritage?.types[0]; + if (baseTypeNode) { + const baseType = this.tsTypeChecker.getTypeAtLocation(baseTypeNode); + const baseSymbol = baseType.getSymbol(); + const declarations = baseSymbol?.getDeclarations(); + const baseClassDecl = declarations?.find(ts.isClassDeclaration); + if (baseClassDecl) { + this.collectPropertiesFromClass(baseClassDecl, result, true); + } + } + } + } + + static isNegativeNumericLiteral(expr: ts.Expression): boolean { + return ( + ts.isPrefixUnaryExpression(expr) && + expr.operator === ts.SyntaxKind.MinusToken && + ts.isNumericLiteral(expr.operand) + ); + } + + isNumberArrayType(type: ts.Type): boolean { + if (!type.symbol || !this.isGenericArrayType(type)) { + return false; + } + + const typeArguments = this.tsTypeChecker.getTypeArguments(type); + if (!typeArguments || typeArguments.length === 0) { + return false; + } + + return (typeArguments[0].flags & ts.TypeFlags.Number) !== 0; + } + + static isIgnoredTypeForParameterType(typeString: string, type: ts.Type): boolean { + if (TsUtils.isAnyType(type)) { + return true; + } + + return ( + IGNORE_TYPE_LIST.findIndex((ignored_type) => { + return typeString.includes(ignored_type); + }) !== -1 + ); + } } diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts index dcddab08b580a515ee4cbb998d5b2bff7a1025a9..bae5dc65cc4e7b65fd607f7142fcd376411b217d 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts @@ -16,3 +16,6 @@ export const ASON_TEXT = 'ASON'; export const ASON_MODULES = ['@arkts.utils', '@kit.ArkTS']; export const JSON_TEXT = 'JSON'; +export const ARKTS_UTILS_TEXT = 'ArkTSUtils'; + +export const ASON_WHITE_SET: Set = new Set(['stringify']); diff --git a/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts b/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts index bd6d904c9391bd94907a86c1fd70364e0f28c294..c945fcd33c43ea75cf3dc6385861979004e8f531 100755 --- a/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts @@ -14,3 +14,4 @@ */ export const ARKTS_WHITE_API_PATH_TEXTSTYLE = 'component/styled_string.d.ts'; +export const COMMON_UNION_MEMBER_ACCESS_WHITELIST = new Set(['ArrayBufferLike', 'IteratorResult']); diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts index ec5b3df5042e3b9698048a81018a3bd24e9f1025..5b17c7dad52474dde94fcbec64d87153541edd6d 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts @@ -13,6 +13,8 @@ * limitations under the License. */ +import * as ts from 'typescript'; + export const DOUBLE_DOLLAR_IDENTIFIER = '$$'; export const THIS_IDENTIFIER = 'this'; export const ATTRIBUTE_SUFFIX = 'Attribute'; @@ -20,25 +22,47 @@ 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 = '@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 const NEW_PROP_DECORATOR_SUFFIX = 'Ref'; -export enum CustomDecoratorName { +export enum CustomInterfaceName { Extend = 'Extend', LocalBuilder = 'LocalBuilder', Styles = 'Styles', AnimatableExtend = 'AnimatableExtend', Memo = 'Memo', Observed = 'Observed', - Layoutable = 'Layoutable' + CustomLayout = 'CustomLayout', + CustomStyles = 'CustomStyles', + Repeat = 'Repeat', + WrappedBuilder = 'WrappedBuilder', + wrapBuilder = 'wrapBuilder', + BuilderNode = 'BuilderNode' } export enum StorageTypeName { LocalStorage = 'LocalStorage', - AppStorage = 'AppStorage' + AppStorage = 'AppStorage', + PersistentStorage = 'PersistentStorage', + PersistenceV2 = 'PersistenceV2' +} + +export enum PropDecoratorName { + Prop = 'Prop', + StorageProp = 'StorageProp', + LocalStorageProp = 'LocalStorageProp' +} + +export enum PropFunctionName { + Prop = 'prop', + SetAndProp = 'setAndProp' +} + +export enum BuilderNodeFunctionName { + Build = 'build', + Update = 'update' } export const observedDecoratorName: Set = new Set([ @@ -59,12 +83,79 @@ export const skipImportDecoratorName: Set = new Set([ 'Styles', 'Sendable', 'Concurrent', - 'LocalBuilder' + 'LocalBuilder', + 'Prop', + 'StorageProp', + 'LocalStorageProp' ]); -export const deepCopyDecoratorName: Set = new Set(['Prop', 'StorageProp', 'LocalStorageProp']); +export const serializationTypeFlags: Set = new Set([ + ts.TypeFlags.String, + ts.TypeFlags.Number, + ts.TypeFlags.Boolean, + ts.TypeFlags.StringLiteral, + ts.TypeFlags.NumberLiteral, + ts.TypeFlags.BooleanLiteral, + ts.TypeFlags.Undefined, + ts.TypeFlags.Null +]); -export const deepCopyFunctionName: Set = new Set(['prop', 'setAndProp']); +export const serializationTypeName: Set = new Set([ + 'Date', + 'number', + 'boolean', + 'string', + 'undefined', + 'null', + 'Date[]', + 'number[]', + 'boolean[]', + 'string[]', + 'undefined[]', + 'null[]', + 'Set', + 'Set', + 'Set', + 'Set', + 'Set', + 'Set', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map' +]); export const customLayoutFunctionName: Set = new Set(['onMeasureSize', 'onPlaceChildren']); @@ -76,3 +167,21 @@ export const GET_LOCAL_STORAGE_FUNC_NAME = '__get_local_storage__'; export const PROVIDE_DECORATOR_NAME = 'Provide'; export const PROVIDE_ALIAS_PROPERTY_NAME = 'alias'; export const PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME = 'allowOverride'; + +export const VIRTUAL_SCROLL_IDENTIFIER = 'virtualScroll'; +export const DISABLE_VIRTUAL_SCROLL_IDENTIFIER = 'disableVirtualScroll'; + +export const ARKUI_MODULE = '@kit.ArkUI'; +export const STATE_MANAGEMENT_MODULE = '@ohos.arkui.StateManagement'; + +export const BUILDERNODE_D_TS = 'BuilderNode.d.ts'; +export const NESTING_BUILDER_SUPPORTED = 'nestingBuilderSupported'; + +export const COMMON_TS_ETS_API_D_TS = 'common_ts_ets_api.d.ts'; +export const UI_STATE_MANAGEMENT_D_TS = '@ohos.arkui.StateManagement.d.ts'; +export const PERSIST_PROP_FUNC_NAME = 'persistProp'; +export const PERSIST_PROPS_FUNC_NAME = 'persistProps'; +export const GLOBAL_CONNECT_FUNC_NAME = 'globalConnect'; +export const CONNECT_FUNC_NAME = 'connect'; + +export const USE_STATIC_STATEMENT = 'use static'; diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts index 2a9e201f68677de4bd209cb995da5008d0fd849d..d4b3959341982d60c6aa5132d6a326adefb2495c 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiImportList.ts @@ -57,6 +57,7 @@ export const arkuiImportList: Set = new Set([ 'Animator', 'AnimatorAttribute', 'AnimatorInterface', + 'applyStyles', 'AppRotation', 'AppStorage', 'AppearSymbolEffect', @@ -262,6 +263,7 @@ export const arkuiImportList: Set = new Set([ 'CrownSensitivity', 'CurrentDayStyle', 'Curve', + 'CustomLayout', 'CustomBuilder', 'CustomComponent', 'CustomComponentV2', @@ -274,6 +276,7 @@ export const arkuiImportList: Set = new Set([ 'CustomSpanDrawInfo', 'CustomSpanMeasureInfo', 'CustomSpanMetrics', + 'CustomStyles', 'CustomTheme', 'CutEvent', 'DataAddOperation', @@ -494,6 +497,8 @@ export const arkuiImportList: Set = new Set([ 'GestureRecognizerState', 'GestureStyle', 'GestureType', + 'getInspectorByKey', + 'getInspectorTree', 'GetItemMainSizeByIndex', 'GradientDirection', 'Grid', @@ -687,6 +692,7 @@ export const arkuiImportList: Set = new Set([ 'LocalStorage', 'LocalStorageLink', 'LocalStorageProp', + 'LocalStoragePropRef', 'LocalizedAlignRuleOptions', 'LocalizedAlignment', 'LocalizedBarrierDirection', @@ -1054,6 +1060,7 @@ export const arkuiImportList: Set = new Set([ 'ProgressStyleOptions', 'ProgressType', 'Prop', + 'PropRef', 'ProtectedResourceType', 'Provide', 'ProvideOptions', @@ -1100,6 +1107,7 @@ export const arkuiImportList: Set = new Set([ 'RenderProcessNotRespondingData', 'RenderProcessNotRespondingReason', 'RenderingContextSettings', + 'Repeat', 'RepeatAttribute', 'RepeatItem', 'RepeatMode', @@ -1250,6 +1258,9 @@ export const arkuiImportList: Set = new Set([ 'SelectionMenuOptionsExt', 'SelectionOptions', 'Sendable', + 'sendKeyEvent', + 'sendMouseEvent', + 'sendTouchEvent', 'Serializer', 'ShadowOptions', 'ShadowStyle', @@ -1321,6 +1332,7 @@ export const arkuiImportList: Set = new Set([ 'Storage', 'StorageLink', 'StorageProp', + 'StoragePropRef', 'StyleOptions', 'StyledString', 'StyledStringChangeValue', @@ -1584,6 +1596,7 @@ export const arkuiImportList: Set = new Set([ 'WithThemeOptions', 'WordBreak', 'WorkStateStyle', + 'wrapBuilder', 'WrappedBuilder', 'XComponent', 'XComponentAttribute', @@ -1605,5 +1618,58 @@ export const arkuiImportList: Set = new Set([ 'px2vp', 'setAppBgColor', 'sharedTransitionOptions', - 'vp2px' + 'vp2px', + '$r', + '$rawfile' +]); + +export const arkTsBuiltInTypeName: Set = new Set([ + 'Object', + 'Function', + 'Boolean', + 'Symbol', + 'Number', + 'BigInt', + 'Math', + 'Date', + 'String', + 'RegExp', + 'Array', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array', + 'BigInt64Array', + 'BigUint64Array', + 'Map', + 'Set', + 'WeakMap', + 'WeakSet', + 'ArrayBuffer', + 'SharedArrayBuffer', + 'DataView', + 'JSON', + 'Promise', + 'Generator', + 'GeneratorFunction', + 'AsyncFunction', + 'AsyncGenerator', + 'AsyncGeneratorFunction', + 'Reflect', + 'Proxy', + 'Error', + 'EvalError', + 'RangeError', + 'ReferenceError', + 'SyntaxError', + 'TypeError', + 'URIError', + 'AggregateError', + 'Intl', + 'WebAssembly' ]); diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts b/ets2panda/linter/src/lib/utils/consts/ArraysAPI.ts old mode 100644 new mode 100755 similarity index 58% rename from ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts rename to ets2panda/linter/src/lib/utils/consts/ArraysAPI.ts index f1a9c97b6bc0ac2e7ac082b7b38bb215ecd2b5b3..4076fa0f93eda6dcd88b276bd66ccbd122e3d704 --- a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArraysAPI.ts @@ -13,56 +13,37 @@ * limitations under the License. */ -export const arkts2Rules: number[] = [ - 1, - 25, - 30, - 34, - 37, - 29, - 111, - 137, - 139, - 140, - 144, - 149, - 183, - 184, - 189, - 190, - 192, - 193, - 198, - 202, - 203, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 222, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 251, - 252, - 253, - 254, - 255, - 256, - 257, - 258, - 259, - 260, - 263, - 300, - 301, - 304, +export const ARRAY_API_LIST = [ + 'length', + 'concat', + 'copyWithin', + 'entries', + 'every', + 'fill', + 'filter', + 'find', + 'findIndex', + 'flat', + 'flatMap', + 'forEach', + 'includes', + 'indexOf', + 'join', + 'keys', + 'lastIndexOf', + 'map', + 'pop', + 'push', + 'reduce', + 'reduceRight', + 'reverse', + 'shift', + 'slice', + 'some', + 'sort', + 'splice', + 'toLocaleString', + 'toString', + 'unshift', + 'values' ]; diff --git a/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts b/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c3409d7ce7b8ac80d9a3931cb5019bc7e44d6dd --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/AssociatedInfo.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 { FaultID } from '../../Problems'; +import { SdkProblem } from './SdkWhitelist'; + +export const globalApiAssociatedInfo: Map = new Map([ + [SdkProblem.DeclWithDuplicateName, FaultID.DuplicateDeclNameFromSdk], + [SdkProblem.LimitedVoidType, FaultID.LimitedVoidTypeFromSdk] +]); diff --git a/ets2panda/linter/src/lib/utils/consts/AsyncLifecycleSDK.ts b/ets2panda/linter/src/lib/utils/consts/AsyncLifecycleSDK.ts new file mode 100644 index 0000000000000000000000000000000000000000..64ef7604190a31f48916e6272ee8a9778a70fbcb --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/AsyncLifecycleSDK.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. + */ + +export const VOID = 'Void'; +export const PROMISE = 'Promise'; + +export const ON_DESTROY = 'onDestroy'; +export const ON_DISCONNECT = 'onDisconnect'; + +export const SERVICE_EXTENSION_ABILITY = 'ServiceExtensionAbility'; + +export const ABILITY_KIT = '@kit.AbilityKit'; + +export const ASYNC_LIFECYCLE_SDK_LIST = new Set([ + 'UIAbility', + 'UIExtensionAbility', + 'AutoFillExtensionAbility', + 'ServiceExtensionAbility' +]); + +export const ABILITY_LIFECYCLE_SDK = 'ApplicationContext'; diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts index d4e4898557e485d0cb4c9c83c21c143be6314e61..3a2fb5e275855c9de6f40e439fc81dad240f31be 100644 --- a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts @@ -13,12 +13,19 @@ * limitations under the License. */ +import { FaultID } from '../../Problems'; + export enum BuiltinProblem { LimitedThisArg = 'ThisArg', SymbolIterator = 'SymbolIterator', BuiltinNoCtorFunc = 'BuiltinNoCtorFunc', BuiltinNoPropertyDescriptor = 'NoPropertyDescriptor', - MissingAttributes = 'MissingAttributes' + MissingAttributes = 'MissingAttributes', + BuiltinNewCtor = 'BuiltinNewCtor', + BuiltinFinalClass = 'BuiltinFinalClass', + BuiltinNarrowTypes = 'BuiltinNarrowTypes', + BuiltinDisableApi = 'BuiltinDisableApi', + BuiltinIteratorResultValue = 'BuiltinIteratorResultValue' } export const SYMBOL_ITERATOR: string = 'Symbol.iterator'; @@ -45,3 +52,31 @@ export const BUILTIN_DISABLE_CALLSIGNATURE = [ 'TypeError', 'URIError' ]; + +export const BUILTIN_CONSTRUCTORS = ['Boolean', 'Number', 'Object', 'String']; + +export const COLLECTION_TYPES = new Set(['Map', 'Set', 'WeakMap', 'WeakSet']); + +export const COLLECTION_METHODS = new Set(['add', 'delete', 'get', 'has', 'set']); + +export const BUILTIN_TYPE = 'BuiltinApi'; +export const BuiltinProblemInfos = new Map([ + [BuiltinProblem.BuiltinNoCtorFunc, FaultID.BuiltinNoCtorFunc], + [BuiltinProblem.BuiltinNoPropertyDescriptor, FaultID.NoPropertyDescriptor], + [BuiltinProblem.BuiltinNarrowTypes, FaultID.BuiltinNarrowTypes], + [BuiltinProblem.BuiltinDisableApi, FaultID.BuiltinDisableApi], + [BuiltinProblem.BuiltinIteratorResultValue, FaultID.BuiltinIteratorResultValue] +]); +export const BUILTIN_CONSTRUCTOR_API_NAME: string = 'builtin_constructor'; +export const BUILTIN_CONSTRUCTOR_API_TYPE = ['CallSignature']; +export const BUILTIN_CALLSIGNATURE_NEWCTOR = [ + 'AggregateError', + 'Array', + 'Boolean', + 'Date', + 'Error', + 'Number', + 'String', + 'WeakMap', + 'Object' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts index a7c1698e3ba00a285e16df6ee6b1c418f3832d4b..447620d50e90fa86cd474f73c9baa192cf6db826 100644 --- a/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts @@ -14,4 +14,8 @@ */ export const COLLECTIONS_TEXT = 'collections'; +export const ARKTS_COLLECTIONS_MODULE = '@arkts.collections'; +export const BIT_VECTOR = 'BitVector'; export const COLLECTIONS_MODULES = ['@arkts.collections', '@kit.ArkTS']; + +export type BitVectorUsage = undefined | { ns: string; used: boolean }; diff --git a/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts index 5fc45d2e960b875ace2b3e42b94de233b7d33b66..8b638213a54d01f440af36e62df30374e2df103d 100644 --- a/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts @@ -18,3 +18,4 @@ 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']; +export const SYSTEM_MODULES = ['@kit.ArkTS', '@ohos.']; diff --git a/ets2panda/linter/src/lib/utils/consts/DeprecateWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/DeprecateWhiteList.ts new file mode 100644 index 0000000000000000000000000000000000000000..e89e671d0d7878de8495f6474f3a6427e8efb6e8 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/DeprecateWhiteList.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. + */ + +export const DEPRECATE_TYPE = 'DeprecatedApi'; +export enum DeprecateProblem { + NoDeprecatedApi = 'NoDeprecatedApi' +} + +export enum DEPRECATE_CHECK_KEY { + PARENT_NAME = 'parentName', + PARAM_SET = 'parameters', + RETURN_TYPE = 'returnType', + FILE_NAME = 'fileName' +} + +export const DEPRECATE_UNNAMED = 'unnamed'; diff --git a/ets2panda/linter/src/lib/utils/consts/DeprecatedApi.ts b/ets2panda/linter/src/lib/utils/consts/DeprecatedApi.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc29b7df097199267fe022f3c6eff8ce51b8c7ff --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/DeprecatedApi.ts @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const propertyAccessReplacements = new Map([ + ['TextPickerDialog.show', 'showTextPickerDialog'], + ['DatePickerDialog.show', 'showDatePickerDialog'], + ['ActionSheet.show', 'showActionSheet'], + ['AlertDialog.show', 'showAlertDialog'], + ['componentSnapshot.createFromBuilder', 'getComponentSnapshot().createFromBuilder'], + ['componentSnapshot.get', 'getComponentSnapshot().get'], + ['MeasureText.measureTextSize', 'createMeasureText.measureTextSize'], + ['MeasureText.measureText', 'createMeasureText.measureText'], + ['dragController.getDragPreview', 'createDragController.getDragPreview'], + ['dragController.createDragAction', 'createDragController.createDragAction'], + ['dragController.executeDrag', 'createDragController.executeDrag'], + ['LocalStorage.getShared', 'getSharedLocalStorage'], + ['inspector.createComponentObserver', 'createInspector.createComponentObserver'], + ['Animator.create', 'createAnimator'], + ['mediaquery.matchMediaSync', 'createMediaQuery.matchMediaSync'], + ['componentUtils.getRectangleById', 'getComponentUtils().getRectangleById'], + ['promptAction.showToast', 'getPromptAction.showToast'], + ['promptAction.showDialog', 'getPromptAction.showDialog'], + ['promptAction.openCustomDialog', 'getPromptAction.openCustomDialog'], + ['promptAction.closeCustomDialog', 'getPromptAction.closeCustomDialog'], + ['promptAction.showActionMenu', 'getPromptAction.showActionMenu'], + ['TimePickerDialog.show', 'showTimePickerDialog'], + ['router.pushUrl', 'getRouter.pushUrl'], + ['router.replaceUrl', 'getRouter.replaceUrl'], + ['router.back', 'getRouter.back'], + ['router.clear', 'getRouter.clear'], + ['router.getLength', 'getRouter.getLength'], + ['router.getState', 'getRouter.getState'], + ['router.getStateByIndex', 'getRouter.getStateByIndex'], + ['router.getStateByUrl', 'getRouter.getStateByUrl'], + ['router.showAlertBeforeBackPage', 'getRouter.showAlertBeforeBackPage'], + ['router.hideAlertBeforeBackPage', 'getRouter.hideAlertBeforeBackPage'], + ['router.getParams', 'getRouter.getParams'], + ['router.pushNamedRoute', 'getRouter.pushNamedRoute'], + ['router.replaceNamedRoute', 'getRouter.replaceNamedRoute'], + ['font.registerFont', 'createFont.registerFont'], + ['font.getSystemFontList', 'createFont.getSystemFontList'], + ['font.getFontByName', 'createFont.getFontByName'] +]); + +export const identifierReplacements = new Map([ + ['px2lpx', 'px2lpx'], + ['lpx2px', 'lpx2px'], + ['px2fp', 'px2fp'], + ['fp2px', 'fp2px'], + ['px2vp', 'px2vp'], + ['vp2px', 'vp2px'], + ['getContext', 'getHostContext'], + ['animateTo', 'animateTo'] +]); diff --git a/ets2panda/linter/src/lib/utils/consts/ESObject.ts b/ets2panda/linter/src/lib/utils/consts/ESObject.ts index 9394367c4b8e88826862eaea625d04a0b93dcdc7..ca9f988679dbf9a63ecae9df6ef15f4a6f074ec2 100644 --- a/ets2panda/linter/src/lib/utils/consts/ESObject.ts +++ b/ets2panda/linter/src/lib/utils/consts/ESObject.ts @@ -13,4 +13,5 @@ * limitations under the License. */ +export const ES_VALUE = 'ESValue'; export const ES_OBJECT = 'ESObject'; diff --git a/ets2panda/linter/src/lib/utils/consts/ErrorProp.ts b/ets2panda/linter/src/lib/utils/consts/ErrorProp.ts new file mode 100644 index 0000000000000000000000000000000000000000..a215397dc8bcadeb7f1285aa7973deff73d88ce7 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/ErrorProp.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. + */ + +export const ERROR_PROP_LIST: Set = new Set([ + 'name', + 'message', + 'stack', + 'code', + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable' +]); + +export const ERROR_TASKPOOL_PROP_LIST: { [key: string]: Set } = { + 'taskpool.TaskInfo': new Set(['duration']), + 'taskpool.ThreadInfo': new Set(['taskIds', 'priority']), + 'StdProcess.ConditionType': new Set(['timeout', 'killSignal', 'maxBuffer']) +}; diff --git a/ets2panda/linter/src/lib/utils/consts/ExtendedBaseTypes.ts b/ets2panda/linter/src/lib/utils/consts/ExtendedBaseTypes.ts index 198e45afb177dd2cd24d452d985aed11f79571af..de0c40e18679dc734fa930fe89e9eab30f724314 100644 --- a/ets2panda/linter/src/lib/utils/consts/ExtendedBaseTypes.ts +++ b/ets2panda/linter/src/lib/utils/consts/ExtendedBaseTypes.ts @@ -33,5 +33,6 @@ export const EXTENDED_BASE_TYPES = new Map([ ['ReadonlyArray', ['ConcatArray']], ['Array', ['ReadonlyArray']], ['Map', ['ReadonlyMap']], - ['Set', ['ReadonlySet']] + ['Set', ['ReadonlySet']], + ['Promise', ['PromiseLike']] ]); diff --git a/ets2panda/linter/src/lib/utils/consts/ExtensionName.ts b/ets2panda/linter/src/lib/utils/consts/ExtensionName.ts index 23a5b243cecb14e9f4a26b13f65dd0d435a8f926..efd5c03d9ad6dfa139e965704378a1a34b395c3d 100644 --- a/ets2panda/linter/src/lib/utils/consts/ExtensionName.ts +++ b/ets2panda/linter/src/lib/utils/consts/ExtensionName.ts @@ -22,3 +22,4 @@ export const EXTNAME_MJS: string = '.mjs'; export const EXTNAME_CJS: string = '.cjs'; export const EXTNAME_D_TS: string = '.d.ts'; export const EXTNAME_D_ETS: string = '.d.ets'; +export const EXTNAME_JSON: string = '.json'; diff --git a/ets2panda/linter/src/lib/utils/consts/InValidIndentifierKeywords.ts b/ets2panda/linter/src/lib/utils/consts/InValidIndentifierKeywords.ts index 072f4a88c43c803c3239755d85191010bbf795b3..cb69af6fad8d5f2092c234d4107a498fb6b00116 100755 --- a/ets2panda/linter/src/lib/utils/consts/InValidIndentifierKeywords.ts +++ b/ets2panda/linter/src/lib/utils/consts/InValidIndentifierKeywords.ts @@ -120,5 +120,97 @@ export const INVALID_IDENTIFIER_KEYWORDS = [ 'AsyncIterator', 'NewableFunction', 'CallableFunction', - 'PropertyDescriptor' + 'PropertyDescriptor', + 'AbcFile', + 'AbcRuntimeLinker', + 'BaseEnum', + 'BootRuntimeLinker', + 'Box', + 'BuiltinArrayAlgorithms', + 'BuiltinArray', + 'BuiltinArraySort', + 'Class', + 'Collator', + 'Comparable', + 'Console', + 'ConsoleHelper', + 'Coroutine', + 'DateTimeFormat', + 'DateTimeFormatTypes', + 'DisplayNames', + 'EAWorker', + 'EnumConstant', + 'Exception', + 'Exceptions', + 'Field', + 'FinalizableWeakRef', + 'FinalizationRegistry', + 'GC', + '_initializerBlock_', + 'Intl', + 'Job', + 'Json', + 'ListFormat', + 'Locale', + 'LocaleMatch', + 'MemoryRuntimeLinker', + 'Method', + 'Never', + 'NullValue', + 'NumberFormat', + 'Numeric', + 'Parameter', + 'PluralRules', + 'Promise', + 'PromiseRef', + 'RelativeTimeFormat', + 'Runtime', + 'RuntimeLinkerErrors', + 'RuntimeLinker', + 'Segmenter', + 'StackTrace', + 'StringBuilder', + 'SyncPrimitives', + 'System', + 'Tuple', + 'TypeCreator', + 'Type', + 'UnionCase', + 'Unsafe', + 'Value', + 'Void', + 'WeakRef', + 'consts/consts', + 'ArrayBuffer', + 'Array', + 'ArrayLike', + 'Atomics', + 'BigInt', + 'ConcatArray', + 'ConcurrencyHelpers', + 'DataView', + 'Date', + 'deepcopy', + 'Error', + 'Errors', + 'escompat', + 'Functions', + 'Global', + 'Iterator', + 'json', + 'Map', + 'Math', + 'Process', + 'ReadonlyArray', + 'ReadonlyArrayProxy', + 'Reflect', + 'RegExp', + 'Set', + 'taskpool', + 'TypedArrays', + 'TypedUArrays', + 'WeakMap', + 'WeakSet', + 'arguments', + 'eval' ]; 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 1d7f1f674578282bdb1b625dc42c5df4cad00463..6d4e230d392679d3c8957979217b92d8b85130ea 100644 --- a/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts @@ -12,12 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import type * as ts from 'typescript'; -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 LENGTH = 'length'; +export const INVOKE = 'invoke'; +export const INVOKE_METHOD = 'invokeMethod'; +export const TO_PROMISE = 'toPromise'; +export const IS_INSTANCE_OF = 'isInstanceOf'; export const REFLECT_PROPERTIES = [ 'get', @@ -34,11 +39,35 @@ export const REFLECT_PROPERTIES = [ 'isExtensible', 'preventExtensions' ]; -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 OBJECT_PROPERTIES = [ + 'get', + 'set', + 'has', + 'hasOwn', + 'ownKeys', + 'keys', + 'getOwnPropertyDescriptor', + 'getOwnPropertyDescriptors', + 'getOwnPropertyName', + 'defineProperty', + 'deleteProperty', + 'apply', + 'construct', + 'getPrototypeOf', + 'setPrototypeOf', + 'isExtensible', + 'isFrozen', + 'isSealed' +]; + +export const USE_STATIC = '\'use static\''; +export const OBJECT_LITERAL = 'Object'; +export const REFLECT_LITERAL = 'Reflect'; +export const NONE = 'none'; +export type ForbidenAPICheckResult = 'Object' | 'Reflect' | 'none'; +export const GET_PROPERTY = 'getProperty'; +export const SET_PROPERTY = 'setProperty'; export const TO_NUMBER = 'toNumber'; export enum InteropType { @@ -47,3 +76,13 @@ export enum InteropType { LEGACY = '1.0', NONE = 'none' } + +export type IdentifierAndArguments = { + ident: undefined | ts.Identifier; + args: ts.NodeArray | undefined; +}; + +export type IncrementDecrementNodeInfo = { + varAssignText: string; + addOrDecrOperation: ts.BinaryExpression; +}; diff --git a/ets2panda/linter/src/lib/utils/consts/LikeFunction.ts b/ets2panda/linter/src/lib/utils/consts/LikeFunction.ts index 669b24fd7b6c0af4fcac10613a84daf547c58aa8..1367fd24f22ecab951f3b1b37807b5cdc45644a0 100755 --- a/ets2panda/linter/src/lib/utils/consts/LikeFunction.ts +++ b/ets2panda/linter/src/lib/utils/consts/LikeFunction.ts @@ -14,3 +14,7 @@ */ export const LIKE_FUNCTION = 'Function'; + +export const LIKE_FUNCTION_CONSTRUCTOR = 'FunctionConstructor'; + +export const FORBIDDEN_FUNCTION_BODY = 'return this'; diff --git a/ets2panda/linter/src/lib/utils/consts/LimitedStandardUtilityTypes.ts b/ets2panda/linter/src/lib/utils/consts/LimitedStandardUtilityTypes.ts index 04f651d08023de840edbffdca60cdda456b7a534..fe772501207fdd19343441d3dd08b248eb152a5f 100644 --- a/ets2panda/linter/src/lib/utils/consts/LimitedStandardUtilityTypes.ts +++ b/ets2panda/linter/src/lib/utils/consts/LimitedStandardUtilityTypes.ts @@ -32,3 +32,24 @@ export const LIMITED_STANDARD_UTILITY_TYPES = [ 'Pick', 'Awaited' ]; + +export const LIMITED_STANDARD_UTILITY_TYPES2 = [ + 'Uncapitalize', + 'Capitalize', + 'Lowercase', + 'Uppercase', + 'ThisType', + 'OmitThisParameter', + 'ThisParameterType', + 'InstanceType', + 'ReturnType', + 'ConstructorParameters', + 'Parameters', + 'NonNullable', + 'Extract', + 'Exclude', + 'Omit', + 'Pick', + 'Awaited', + 'NoInfer' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts index ca9bdcd8431c31b723b45d592176955b315df23d..5865c5a450ca91113cc75b3e6fe788d81d12e808 100644 --- a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts @@ -153,7 +153,32 @@ export const LIMITED_STD_API = new Map = { - '@kit.ArkTS': ['taskpool', 'ArkTSUtils', 'process'], + '@kit.ArkTS': ['taskpool', 'ArkTSUtils', 'process', 'collections'], '@ohos.process': ['process'], - '@ohos.taskpool': ['taskpool'] + '@ohos.taskpool': ['taskpool'], + '@arkts.utils': ['ArkTSUtils'], + '@arkts.collections': ['collections'] }; + +export const ARKTSUTILS_MODULES = ['@arkts.utils', '@ohos.process', '@kit.ArkTS']; +export const ARKTSUTILS_LOCKS_MEMBER = 'locks'; + +export const OBJECT_PUBLIC_API_METHOD_SIGNATURES = new Map([ + ['toString', '(): string'], + ['toLocaleString', '(): string'], + ['valueOf', '(): Object'], + ['hasOwnProperty', '(v: PropertyKey): boolean'], + ['isPrototypeOf', '(v: Object): boolean'], + ['propertyIsEnumerable', '(v: PropertyKey): boolean'] +]); +export const ARKTSUTILS_PROCESS_MEMBER = 'process'; + +export const PROCESS_DEPRECATED_INTERFACES = [ + 'isAppUid', + 'getUidForName', + 'getThreadPriority', + 'getSystemConfig', + 'getEnvironmentVar', + 'exit', + 'kill' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/Literals.ts b/ets2panda/linter/src/lib/utils/consts/Literals.ts index 3ca262e108fa4358f39d2498be4cc3a9e1d0d6a7..56d16c0fe22541a7c36601aee8e82bb8b8298277 100644 --- a/ets2panda/linter/src/lib/utils/consts/Literals.ts +++ b/ets2panda/linter/src/lib/utils/consts/Literals.ts @@ -13,4 +13,8 @@ * limitations under the License. */ -export const STRING_ERROR_LITERAL = 'ERROR'; +export const STRING_ERROR_LITERAL = 'Error'; +export const CONCAT_ARRAY = 'ConcatArray'; +export const SELECT_IDENTIFIER = 'Select'; +export const SELECT_OPTIONS = ['Array', 'SelectOption[]']; +export const COMPONENT_DECORATOR = '@Component'; diff --git a/ets2panda/linter/src/lib/utils/consts/MapKeyConst.ts b/ets2panda/linter/src/lib/utils/consts/MapKeyConst.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5689d3f2a3f30ba320d6d5b5b6351c6bae229f1 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/MapKeyConst.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. + */ + +export const TOTAL_PROBLEMS = 'totalProblems'; + +export const ONE_POINT_ONE_PROBLEMS = 'arts1.1_Problems'; + +export const ONE_POINT_TWO_PROBLEMS = 'arts1.2_Problems'; + +export const CAN_BE_AUTO_FIXED_PROBLEMS_NUMBERS = 'canBeAutoFixedproblemNumbers'; + +export const NEED_TO_NAMUAL_FIX_PROBLEM_NUMBERS = 'needToManualFixproblemNumbers'; + +export const SCAN_TIME = 'scanTime'; + +export const MIGRATION_TIME = 'migrationTime'; diff --git a/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts index 7705ae690e06280b6bf50db10a3d4116267b6b1b..73ef2d0743a7fb9dc8cecec551eee9ba82eae738 100644 --- a/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts +++ b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts @@ -1,16 +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'; +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 index d1a2ad228ec1dfe1eb64abb457565d7f1174a103..d3f3faf510e07f15707c2e0293054f6e12230184 100644 --- a/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts +++ b/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts @@ -1,16 +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'; \ No newline at end of file +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/NumericalConstants.ts b/ets2panda/linter/src/lib/utils/consts/NumericalConstants.ts new file mode 100644 index 0000000000000000000000000000000000000000..2bf076304c3d5bd3cf3e614a207d37d68f49269d --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/NumericalConstants.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. + */ + +export const INT_MIN = -2147483648; +export const INT_MAX = 2147483647; + +// Large number literal constants (2^63 - 1 to -2^63) +export const LARGE_NUMBER_MAX = Number('9223372036854775807'); +export const LARGE_NUMBER_MIN = Number('-9223372036854775808'); diff --git a/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts index a262a88b17d85c6dd1b6c3de028a21f8d71efd3d..336a74350cdd26e730ebbf2709fe0734ced88ec9 100644 --- a/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts +++ b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts @@ -1,16 +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'; \ No newline at end of file +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 index 48678d03cca2429037046383f7094456b3b0262b..1bec2217b68943d6caf9189e3425b0c1a1fe4e30 100644 --- a/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts @@ -17,7 +17,7 @@ import type ts from 'typescript'; export type ArrayAccess = { pos: number; - accessingIdentifier: 'number' | ts.Identifier; + accessingIdentifier: 'number' | ts.Identifier | ts.Expression; arrayIdent: ts.Identifier; }; @@ -25,7 +25,7 @@ export type UncheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL | undefi export type CheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL; export const NUMBER_LITERAL = 'number'; - +export const LENGTH_IDENTIFIER = 'length'; export enum LoopConditionChecked { LEFT, RIGHT, @@ -34,5 +34,6 @@ export enum LoopConditionChecked { export enum CheckResult { SKIP, + HAS_ARRAY_ACCES, CHECKED } diff --git a/ets2panda/linter/src/lib/utils/consts/SdkCommonDeprecateWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/SdkCommonDeprecateWhiteList.ts new file mode 100644 index 0000000000000000000000000000000000000000..7a6c52b469ebac9347791a88c82fedc9070439f2 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/SdkCommonDeprecateWhiteList.ts @@ -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 { FaultID } from '../../Problems'; + +export const SDK_COMMON_TYPE = 'SdkCommonApi'; +export const SdkCommonApiProblemInfos = new Map([ + ['WhiteList', FaultID.SdkCommonApiWhiteList], + ['BehaviorChange', FaultID.SdkCommonApiBehaviorChange], + ['allDeprecated', FaultID.SdkCommonApiDeprecated] +]); +export const SDK_COMMON_INDEX_CLASS: Set = new Set(['Stack', 'Queue', 'LinkedList', 'PlainArray', 'Buffer']); +export enum SDK_COMMON_BUFFER_API { + apiName = 'Buffer', + full_api = 'buffer.Buffer', + indexof = 'indexOf' +} +export const SDK_COMMON_FUNCTIONLIKE = ['MethodSignature', 'MethodDeclaration', 'FunctionDeclaration']; +export const SDK_COMMON_PROPERTYLIKE = ['PropertyDeclaration', 'PropertySignature']; +export const SDK_COMMON_CONSTRUCTORLIKE = ['ConstructorDeclaration']; +export const SDK_COMMON_TYPEKEY = ['funlike', 'propertyLike']; + +export const SDK_COMMON_SYMBOL_ITERATOR: string = 'Symbol.iterator'; +export const SDK_COMMON_SYMBOL_ITERATOR_APINAME: string = '[Symbol.iterator]'; +export const SDK_COMMON_TRANSFORMER: string = 'Transformer'; +export const SDK_COMMON_CONSTRUCTOR: string = 'constructor'; +export const SDK_COMMON_VOID: string = 'void'; + +export const sdkCommonAllDeprecatedTypeName: Set = new Set([ + 'Base64', + 'LruBuffer', + 'Scope', + 'Vector', + 'ConvertXML', + 'ConvertOptions', + 'URLSearchParams' +]); +export const sdkCommonAllDeprecatedFullTypeName: Set = new Set([ + 'Base64', + 'LruBuffer', + 'Scope', + 'Vector', + 'ConvertXML', + 'ConvertOptions', + 'URLSearchParams', + 'util.Base64', + 'util.LruBuffer', + 'util.Scope', + 'Vector', + 'xml.ConvertXML', + 'xml.ConvertOptions', + 'url.URLSearchParams' +]); diff --git a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts index a525f8d321ec233034d4c21c2f9e36d4defdac3f..a694f58fa004ea8041e4da278f499dab8c55142c 100644 --- a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts +++ b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts @@ -24,4 +24,5 @@ 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'; \ No newline at end of file +export const STRINGLITERAL_ARRAY = 'Array'; +export const STRINGLITERAL_INFINITY = 'Infinity'; diff --git a/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts b/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts index b2d07bfe3906938c12121c337daf762d9d971344..5ae541d9ca3498008e312172ee3d68588ef8c076 100644 --- a/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts +++ b/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts @@ -14,15 +14,15 @@ */ export const TYPED_ARRAYS = [ + 'BigInt64Array', + 'BigUint64Array', + 'Float32Array', + 'Float64Array', 'Int8Array', - 'Uint8ClampedArray', - 'Uint8Array', - 'Uint16Array', 'Int16Array', - 'Uint32Array', 'Int32Array', - 'Float64Array', - 'Float32Array', - 'BigUint64Array', - 'BigInt64Array' + 'Uint8Array', + 'Uint8ClampedArray', + 'Uint16Array', + 'Uint32Array' ]; diff --git a/ets2panda/linter/src/lib/utils/consts/Types.ts b/ets2panda/linter/src/lib/utils/consts/Types.ts new file mode 100644 index 0000000000000000000000000000000000000000..86abf3d58c423b9fc86627e59255ae2f830f5e3e --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/Types.ts @@ -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 type { ClassDeclaration } from 'typescript'; + +export enum ExtendedIdentifierType { + UNKNOWN, + CLASS, + ERROR +} + +export type ExtendedIdentifierInfo = + | { + type: ExtendedIdentifierType.UNKNOWN | ExtendedIdentifierType.ERROR; + } + | { type: ExtendedIdentifierType.CLASS; decl: ClassDeclaration }; + +export type ConstructorParameter = { + name: string; + isOptional: boolean; + type: string; +}; + +export type ParameterName = string; + +export type BaseClassConstructorInfo = Set | undefined; diff --git a/ets2panda/linter/src/lib/utils/consts/TypesToBeIgnored.ts b/ets2panda/linter/src/lib/utils/consts/TypesToBeIgnored.ts new file mode 100644 index 0000000000000000000000000000000000000000..06b56ad53c8ca0351745034ce98cf18c73b1e32d --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/TypesToBeIgnored.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 IGNORE_TYPE_LIST: string[] = ['any[]', 'Promise', 'never', 'never[]', '{}', 'undefined[]']; diff --git a/ets2panda/linter/src/lib/utils/consts/WorkloadRelatedConst.ts b/ets2panda/linter/src/lib/utils/consts/WorkloadRelatedConst.ts new file mode 100644 index 0000000000000000000000000000000000000000..676b1fb1e73e634c72dae268c284e2e1569806e0 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/WorkloadRelatedConst.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 AVERAGE_LINE_FOR_REPAIRE_RULE_COEFFICIENT = 3; + +export const TEST_DEBUG_WORKLOAD_COEFFICIENT = 1.2; + +export const NPAI_REPAIRE_WORKLOADA_COEFFICIEN = 0.2; diff --git a/ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts b/ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts new file mode 100755 index 0000000000000000000000000000000000000000..cd7ad4f322b146094e6d60609ef2402b6d547fad --- /dev/null +++ b/ets2panda/linter/src/lib/utils/functions/CommonApiInfo.ts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-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 path from 'node:path'; +import * as ts from 'typescript'; +import { forEachNodeInSubtree } from './ForEachNodeInSubtree'; + +export const COMMON_FILE_NAME = 'common.d.ts'; +const commonApiInfoMap = new Set(); +function visitSourceFile(sf: ts.SourceFile | undefined): void { + if (!sf) { + return; + } + const callback = (node: ts.Node): void => { + const isSave = ts.isMethodDeclaration(node) && ts.isClassDeclaration(node.parent); + if (isSave) { + commonApiInfoMap.add(node); + } + }; + forEachNodeInSubtree(sf, callback); +} +export function collectCommonApiInfo(tsProgram: ts.Program): void { + const rootNames = tsProgram.getRootFileNames(); + rootNames.some((file) => { + if (path.basename(file) === COMMON_FILE_NAME) { + const commonSrcFile = tsProgram.getSourceFile(file); + visitSourceFile(commonSrcFile); + return true; + } + return false; + }); +} +export function getCommonApiInfoMap(): Set | undefined { + return commonApiInfoMap.size > 0 ? commonApiInfoMap : undefined; +} diff --git a/ets2panda/linter/src/lib/utils/functions/ConfiguredRulesProcess.ts b/ets2panda/linter/src/lib/utils/functions/ConfiguredRulesProcess.ts new file mode 100644 index 0000000000000000000000000000000000000000..27bf5988bdf90f09b96cc29e3546d7c95d570935 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/functions/ConfiguredRulesProcess.ts @@ -0,0 +1,104 @@ +/* + * 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. + */ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { OptionValues } from 'commander'; +import { Logger } from '../../../lib/Logger'; + +export function getConfiguredRuleTags( + arkTSRulesMap: Map, + configuredRulesMap: Map +): Set { + const mergedRulesMap: string[] = Array.from(configuredRulesMap.values()).flat(); + const configuredRuleTags = new Set(); + const mergedRulesSet = new Set(mergedRulesMap); + arkTSRulesMap.forEach((key, value) => { + if (mergedRulesSet.has(key)) { + configuredRuleTags.add(value); + } + }); + return configuredRuleTags; +} + +export function getRulesFromConfig(configRulePath: string): Map { + try { + const normalizedPath = path.normalize(configRulePath); + const data = fs.readFileSync(normalizedPath, 'utf-8'); + const jsonData = JSON.parse(data); + const dataMap = new Map(); + for (const [key, value] of Object.entries(jsonData)) { + dataMap.set(key, value); + } + return convertToStringArrayMap(dataMap); + } catch (error) { + if (error instanceof SyntaxError) { + throw new Error(`JSON parsing failed: ${error.message}`); + } + return new Map(); + } +} + +export function getConfigureRulePath(options: OptionValues): string { + if (!options.ruleConfig) { + return getDefaultConfigurePath(); + } + const stats = fs.statSync(path.normalize(options.ruleConfig)); + if (!stats.isFile()) { + Logger.error(`The file at ${options.ruleConfigPath} path does not exist! + And will use the default configure rule`); + return getDefaultConfigurePath(); + } + return options.ruleConfig; +} + +export function getDefaultConfigurePath(): string { + const defaultConfigPath = path.join(process.cwd(), 'rule-config.json'); + try { + fs.accessSync(defaultConfigPath, fs.constants.F_OK); + } catch (error: any) { + if (error.code === 'ENOENT') { + Logger.error( + 'The default rule configuration file does not exist, please add the file named rule-config.json in the migration-helper folder!' + ); + process.exit(1); + } + } + return defaultConfigPath; +} + +function convertToStringArrayMap(inputMap: Map): Map { + const resultMap: Map = new Map(); + for (const [key, value] of inputMap) { + if (isStringArray(value)) { + resultMap.set(key, value); + } + } + return resultMap; +} + +function isStringArray(value: any): value is string[] { + return ( + Array.isArray(value) && + value.every((item) => { + return typeof item === 'string'; + }) + ); +} + +export function getAllLinterRules(): string[] { + const configureRulePath = getDefaultConfigurePath(); + const configuredRulesMap = getRulesFromConfig(configureRulePath); + return Array.from(configuredRulesMap.values()).flat(); +} diff --git a/ets2panda/linter/src/lib/utils/functions/CookBookUtils.ts b/ets2panda/linter/src/lib/utils/functions/CookBookUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..d9cd3ace16f3259009759855f861148698dcbca5 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/functions/CookBookUtils.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. + */ + +export function extractRuleTags(tags: string[]): Map { + const resultMap = new Map(); + + for (let i = 0; i < tags.length; i++) { + const tag = tags[i]; + + if (!tag?.trim()) { + continue; + } + + // Match content of the last () + const regex = /.*\(([^)]+)\)[^(]*$/; + const match = tag.match(regex); + + if (match?.[1]?.trim()) { + resultMap.set(i, match[1]); + } + } + + return resultMap; +} diff --git a/ets2panda/test/compiler/ets/rethrowingCheck1.ets b/ets2panda/linter/src/lib/utils/functions/ProcessWrite.ts similarity index 56% rename from ets2panda/test/compiler/ets/rethrowingCheck1.ets rename to ets2panda/linter/src/lib/utils/functions/ProcessWrite.ts index b2a3ba24b39cedf894af44f65eaf54b99f6dd172..ef8e100ae8b34ba1feb582b9901d2a95fd55cf71 100644 --- a/ets2panda/test/compiler/ets/rethrowingCheck1.ets +++ b/ets2panda/linter/src/lib/utils/functions/ProcessWrite.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,14 +13,18 @@ * limitations under the License. */ -function foo() throws { - throw new Exception("I am an exception"); +export async function processSyncOut(message: string): Promise { + await new Promise((resolve) => { + process.stdout.write(message, () => { + resolve('success'); + }); + }); } -function bar(a: () => void throws) rethrows { - try { - foo(); - } catch (e) { - // error handling - } +export async function processSyncErr(message: string): Promise { + await new Promise((resolve) => { + process.stderr.write(message, () => { + resolve('success'); + }); + }); } diff --git a/ets2panda/linter/src/testRunner/LintTest.ts b/ets2panda/linter/src/testRunner/LintTest.ts index 02db53dd4993067c10a6897c7fc08d5b0563dc62..a1095833f1cb375a290149dd0c6cc7946bb07dbc 100644 --- a/ets2panda/linter/src/testRunner/LintTest.ts +++ b/ets2panda/linter/src/testRunner/LintTest.ts @@ -15,20 +15,21 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; +import type { Autofix } from '../lib/autofixes/Autofixer'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; import type { LinterConfig } from '../lib/LinterConfig'; import { lint } from '../lib/LinterRunner'; +import type { LintRunResult } from '../lib/LintRunResult'; import { Logger } from '../lib/Logger'; +import { TimeRecorder } from '../lib/statistics/scan/TimeRecorder'; import { compileLintOptions } from '../lib/ts-compiler/Compiler'; +import { DIFF_EXT, RESULTS_DIR, TAB } from './Consts'; +import type { CreateLintTestOptions } from './TestFactory'; 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'; +import { transformProblemInfos } from './TestUtil'; export class LintTest { readonly testDir: string; @@ -47,7 +48,8 @@ export class LintTest { Logger.info(`Running test ${this.testFile} (${TestMode[this.testModeProps.mode]} mode)`); const linterConfig = this.compile(); - const linterResult = lint(linterConfig); + const timeRecorder = new TimeRecorder(); + const linterResult = lint(linterConfig, timeRecorder); return this.validate(linterResult); } @@ -59,7 +61,7 @@ export class LintTest { // Get actual test results. const fileProblems = actualLinterResult.problemsInfos.get(path.normalize(this.cmdOptions.inputFiles[0])); if (fileProblems === undefined) { - return true; + return false; } const actualResult = transformProblemInfos(fileProblems, this.testModeProps.mode); diff --git a/ets2panda/linter/src/testRunner/TestRunner.ts b/ets2panda/linter/src/testRunner/TestRunner.ts index 4d3639fb3225a8fe9765d4f8207e96fd82ed8667..1f068e2f516cec4e38f3660baa7afd4c61d41f55 100755 --- a/ets2panda/linter/src/testRunner/TestRunner.ts +++ b/ets2panda/linter/src/testRunner/TestRunner.ts @@ -143,6 +143,21 @@ function runTests(): boolean { const { passed, failed } = testStats; Logger.info(`\nSUMMARY: ${passed + failed} total, ${passed} passed, ${failed} failed.`); Logger.info(failed > 0 ? '\nTEST FAILED' : '\nTEST SUCCESSFUL'); + + const saveCoverageData = (): void => { + const coverageData = globalThis.__coverage__; + if (coverageData) { + const projectRoot = path.resolve(__dirname, '../../..'); + const coverageDir = path.join(projectRoot, 'coverage'); + fs.mkdirSync(coverageDir, { recursive: true }); + + const coverageFile = path.join(coverageDir, 'coverage.json'); + fs.writeFileSync(coverageFile, JSON.stringify(coverageData, null, 4)); + } else { + console.log('no coverage data found'); + } + }; + saveCoverageData(); process.exit(failed > 0 ? -1 : 0); } diff --git a/ets2panda/linter/test/builtin/builtin_array_negative.ets b/ets2panda/linter/test/builtin/builtin_array_negative.ets new file mode 100755 index 0000000000000000000000000000000000000000..dbf1092470fb76fae8a74dda764bf6d3fd9b5351 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_negative.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. + */ +import { collections } from '@kit.ArkTS'; + +let arr1 = new Array(); //BuiltinNewCtor +let arr2 = new Array(); //BuiltinNewCtor +arr1.concat(1, arr2); //BuiltinAll +Array.length; +let arr11: ReadonlyArray = new Array(); //BuiltinNewCtor +let arr22: ReadonlyArray = new Array(); //BuiltinNewCtor +arr11.concat(1, arr22); //BuiltinAll + +const isArr = Array.isArray([1]); //BuiltinAll +let arr = new Array(); //BuiltinNewCtor + +const date = new Date("August 19,1975 23:00:00 UTC");//lib.es2015.core.d.ts +const jsonDate = date.toJSON(); //BuiltinAll +new Date().toJSON(); //BuiltinAll+BuiltinNewCtor +function getDate(){ + return date; +} +getDate().toJSON(); //BuiltinAll +console.log(new Demo().localDate?.toJSON()) //BuiltinAll +const demo = new Demo(); +demo.get()?.toJSON(); //BuiltinAll +Date.toString(); +//Reflect +let a1 = new Array(1,2,3) //BuiltinNewCtor +Reflect.ownKeys(a1) //BuiltinAll + +//ArrayBufferConstructor +ArrayBuffer.isView(1); //BuiltinAll +ArrayBuffer.isView(100n); //BuiltinAll +interface ArrayBufferConstructor{} +class Demo implements ArrayBufferConstructor,Date{ + localDate:Date|undefined = undefined; + set(localDate:Date|undefined){ + localDate = new Date(); //BuiltinNewCtor + return localDate + } + get():Date|undefined{ + return this.set(this.localDate); + } + isView(arg: string): arg is ArrayBufferView { + this.localDate?.toJSON(); //BuiltinAll + } + toJSON(key?: number): string { //BuiltinAll + return ''; + } +} + +let array = new collections.Array(1, 2, 3); +let array1 = new collections.Array(4, 5, 6); +let array2 = new collections.Array(7, 8, 9); +let concatArray = array.concat(array1, array2); +let arr3: collections.Array = new collections.Array('a', 'b', 'c', 'd'); +let result: boolean = collections.Array.isArray(arr3); +console.info(result + ''); + +const uint8 = new Uint8Array([1, 2, 3]); +ArrayBuffer.isView(uint8) //BuiltinAll +const buffer = new ArrayBuffer(16); +const dataView = new DataView(buffer); +ArrayBuffer.isView(dataView) //BuiltinAll + +//sum:24 \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_array_negative.ets.args.json b/ets2panda/linter/test/builtin/builtin_array_negative.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_negative.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_array_negative.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_array_negative.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7a708cf5aa78607c14fe9a1dd1ada1e31c6c507c --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_negative.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": 15, + "column": 10, + "endLine": 15, + "endColumn": 21, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 16, + "endLine": 18, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 6, + "endLine": 19, + "endColumn": 12, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 40, + "endLine": 21, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 40, + "endLine": 22, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 13, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 21, + "endLine": 25, + "endColumn": 28, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 15, + "endLine": 26, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 29, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 12, + "endLine": 30, + "endColumn": 18, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 17, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 35, + "endLine": 35, + "endColumn": 41, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 14, + "endLine": 40, + "endColumn": 19, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 20, + "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": 41, + "column": 9, + "endLine": 41, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 13, + "endLine": 45, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 46, + "endLine": 47, + "endColumn": 50, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 61, + "endColumn": 4, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 25, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 24, + "endLine": 56, + "endColumn": 46, + "problem": "IsOperator", + "suggest": "", + "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 21, + "endLine": 57, + "endColumn": 27, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 10, + "endLine": 59, + "endColumn": 22, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 17, + "endLine": 64, + "endColumn": 34, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 18, + "endLine": 66, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 43, + "endLine": 68, + "endColumn": 60, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 13, + "endLine": 73, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_array_negative.ets.json b/ets2panda/linter/test/builtin/builtin_array_negative.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..f96a03d6a073f3f669c25fcfa60bcd6c7e65b5c7 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_negative.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": 41, + "column": 1, + "endLine": 41, + "endColumn": 20, + "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": 56, + "column": 24, + "endLine": 56, + "endColumn": 46, + "problem": "IsOperator", + "suggest": "", + "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 47, + "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/builtin/builtin_array_positive.ets b/ets2panda/linter/test/builtin/builtin_array_positive.ets new file mode 100755 index 0000000000000000000000000000000000000000..73b998f4589d060c3a51e4409ae2d036cc9443db --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_positive.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 { collections } from '@kit.ArkTS'; +Array.length; +const date = new Date("August 19,1975 23:00:00 UTC");//lib.es2015.core.d.ts + +let array = new collections.Array(1, 2, 3); +let array1 = new collections.Array(4, 5, 6); +let array2 = new collections.Array(7, 8, 9); +let concatArray = array.concat(array1, array2); +let arr3: collections.Array = new collections.Array('a', 'b', 'c', 'd'); +let result: boolean = collections.Array.isArray(arr3); +console.info(result + ''); diff --git a/ets2panda/linter/test/builtin/builtin_array_positive.ets.args.json b/ets2panda/linter/test/builtin/builtin_array_positive.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_positive.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_array_positive.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_array_positive.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..2352209dcdc16cdebbd7ddde545ba65d43dbf1ad --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_positive.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": 15, + "column": 10, + "endLine": 15, + "endColumn": 21, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 34, + "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": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 43, + "endLine": 23, + "endColumn": 60, + "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/builtin/builtin_array_positive.ets.json b/ets2panda/linter/test/builtin/builtin_array_positive.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..e44cb0bda37d0d05d17c210929930e004c297a67 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_array_positive.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": 19, + "column": 5, + "endLine": 19, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 47, + "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/builtin/builtin_callsignature.ets b/ets2panda/linter/test/builtin/builtin_callsignature.ets index ccb7f4de952f3bc32e079f785565ea9e8f313d9f..c728c8dc6c64ef0caae8fe6678ac2f0251caeef3 100644 --- a/ets2panda/linter/test/builtin/builtin_callsignature.ets +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets @@ -34,4 +34,10 @@ function anotherName(ctorName0: BigIntConstructor) { // ERROR type BigIntConstructor1 = BigIntConstructor; // ERROR let ctorName2:BigIntConstructor1 = ctorName1 // ERROR const rs2 = ctorName2(1); // ERROR +} + +class A extends Error { + constructor(str: string) { + super(str); + } } \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json index 82638906838c1734e3d4c539b65ac8ad583f7425..6cdfec1941d1a2cbd4a14245402b9310ac583aa9 100644 --- a/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json @@ -34,6 +34,16 @@ "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", "severity": "ERROR" }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 15, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 23, "column": 29, diff --git a/ets2panda/linter/test/builtin/builtin_class.ets b/ets2panda/linter/test/builtin/builtin_class.ets new file mode 100755 index 0000000000000000000000000000000000000000..49d613c0963e2054b38be468839a27c85496b270 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_class.ets @@ -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. + */ + +class MyIntArray extends Int8Array implements Int8Array{} //BuiltinFinalClass*2 +interface MyIntArray2 extends Int8Array {} //BuiltinFinalClass + +class MyBigInt1 extends BigInt implements BigInt { //BuiltinFinalClass*2 + constructor(value: bigint | string | number) { + super(value); + } + [Symbol.iterator](): IterableIterator{ //BuiltinSymbolIterator + return this; + } +} + +class MyDataView1 extends DataView implements DataView{} //BuiltinFinalClass*2 +interface MyDataView3 extends DataView {} //BuiltinFinalClass + +class MyInt16Array1 extends Int16Array implements Int16Array { //BuiltinFinalClass*2 + filter(predicate: (value: number, index: number, array: Int16Array) => number, thisArg?: number): Int16Array {//BuiltinAll + return new Int16Array; + } +} +interface MyInt16Array2 extends Int16Array{ //BuiltinFinalClass + every(predicate: (value: number, index: number, array: Int16Array) => void, thisArg?: string): void; +} +class MyInt32Array1 extends Int32Array{}//BuiltinFinalClass +class MyInt32Array2 implements Int32Array{} //BuiltinFinalClass +interface MyInt32Array3 extends Int32Array{}; //BuiltinFinalClass + +class MyBigInt64Array1 extends BigInt64Array implements BigInt64Array{}//BuiltinFinalClass*2 +interface MyBigInt64Array2 extends BigInt64Array{}//BuiltinFinalClass + +class EmptyIterator implements IterableIterator{// + next(): IteratorResult {//BuiltinAll + return { done: true, value: undefined as void as T }; + } + + [Symbol.iterator](): IterableIterator {//BuiltinSymbolIterator*2 + return this; + }} +interface EmptyIterator2 extends IterableIterator{} + +class MyFloatArray1 extends Float32Array implements Float32Array,Float64Array {} //BuiltinFinalClass*3 +interface MyFloat32Array3 extends Float32Array{} //BuiltinFinalClass +interface MyFloat64Array3 extends Float64Array{} //BuiltinFinalClass + +class MyWeak extends WeakMapimplements WeakMap,WeakSet{} //BuiltinFinalClass*3 +interface MyWeakMap3 extends WeakMap{} //BuiltinFinalClass +class MyWeakSet1 extends WeakSet{} //BuiltinFinalClass +interface MyWeakSet3 extends WeakSet{} //BuiltinFinalClass + +class MyObject extends Boolean implements Boolean,String{} //BuiltinFinalClass*3 +interface MyBoolean3 extends Boolean {} //BuiltinFinalClass +interface MyString3 extends String{} //BuiltinFinalClass +class MyFinalizationRegistry1 extends FinalizationRegistry{} //BuiltinFinalClass +class MyFinalizationRegistry2 implements FinalizationRegistry { //BuiltinFinalClass + [Symbol.toStringTag]: "FinalizationRegistry"|undefined=undefined; + register(target: object, heldValue: T, unregisterToken?: object): void {} + unregister(unregisterToken: object): void {} +} +interface MyFinalizationRegistry3 extends FinalizationRegistry{} //BuiltinFinalClass +class MyPromise1 extends Promise { + constructor(executor: (resolve: (value: T | PromiseLike) => void, reject: (reason?: number) => void) => void) { + super(executor); + } +} + +class MyPromise2 implements Promise { + then( + onfulfilled?: ((value: string) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: string) => TResult2 | PromiseLike) | null + ): Promise { + return Promise.resolve() as Promise; + } + + catch( + onrejected?: ((reason: string) => TResult | PromiseLike) | null + ): Promise { + return Promise.resolve() as Promise; + } + + finally(onfinally?: (() => void) | null): Promise { + return Promise.resolve() as Promise; + } + + [Symbol.toStringTag]: string = "Promise"; +} + +interface MyPromise3 extends Promise {} diff --git a/ets2panda/linter/test/builtin/builtin_class.ets.args.json b/ets2panda/linter/test/builtin/builtin_class.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_class.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_class.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_class.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..d4f92e186a552f92744e71c8977aeb014209ae57 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_class.ets.arkts2.json @@ -0,0 +1,578 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 26, + "endLine": 16, + "endColumn": 35, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 47, + "endLine": 16, + "endColumn": 56, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 31, + "endLine": 17, + "endColumn": 40, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 25, + "endLine": 19, + "endColumn": 31, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 43, + "endLine": 19, + "endColumn": 49, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 4, + "endLine": 23, + "endColumn": 19, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 27, + "endLine": 28, + "endColumn": 35, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 48, + "endLine": 28, + "endColumn": 56, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 31, + "endLine": 29, + "endColumn": 39, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 29, + "endLine": 31, + "endColumn": 39, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 51, + "endLine": 31, + "endColumn": 61, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 10, + "endLine": 32, + "endColumn": 80, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 82, + "endLine": 32, + "endColumn": 98, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 33, + "endLine": 36, + "endColumn": 43, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 29, + "endLine": 39, + "endColumn": 39, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 32, + "endLine": 40, + "endColumn": 42, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 33, + "endLine": 41, + "endColumn": 43, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 32, + "endLine": 43, + "endColumn": 45, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 57, + "endLine": 43, + "endColumn": 70, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 37, + "endLine": 44, + "endColumn": 50, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 7, + "endLine": 46, + "endColumn": 20, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 25, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 18, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 31, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 46, + "endLine": 48, + "endColumn": 50, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 4, + "endLine": 51, + "endColumn": 19, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 29, + "endLine": 56, + "endColumn": 41, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 53, + "endLine": 56, + "endColumn": 65, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 66, + "endLine": 56, + "endColumn": 78, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 35, + "endLine": 57, + "endColumn": 47, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 35, + "endLine": 58, + "endColumn": 47, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 43, + "endLine": 60, + "endColumn": 50, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 67, + "endLine": 60, + "endColumn": 74, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 81, + "endLine": 60, + "endColumn": 88, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 51, + "endLine": 61, + "endColumn": 58, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 44, + "endLine": 62, + "endColumn": 51, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 48, + "endLine": 63, + "endColumn": 55, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 24, + "endLine": 65, + "endColumn": 31, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 43, + "endLine": 65, + "endColumn": 50, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 51, + "endLine": 65, + "endColumn": 57, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 30, + "endLine": 66, + "endColumn": 37, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 29, + "endLine": 67, + "endColumn": 35, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 42, + "endLine": 68, + "endColumn": 62, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 45, + "endLine": 69, + "endColumn": 65, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 23, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 11, + "endLine": 70, + "endColumn": 22, + "problem": "SymbolType", + "suggest": "", + "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 46, + "endLine": 74, + "endColumn": 66, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 29, + "endLine": 75, + "endColumn": 36, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 32, + "endLine": 81, + "endColumn": 39, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 79, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 79, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 77, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 23, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 11, + "endLine": 99, + "endColumn": 22, + "problem": "SymbolType", + "suggest": "", + "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 33, + "endLine": 102, + "endColumn": 40, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 23, + "problem": "StrictDiagnostic", + "suggest": "Property '[Symbol.toStringTag]' in type 'MyFinalizationRegistry2' is not assignable to the same property in base type 'FinalizationRegistry'.\n Type '\"FinalizationRegistry\" | undefined' is not assignable to type '\"FinalizationRegistry\"'.\n Type 'undefined' is not assignable to type '\"FinalizationRegistry\"'.", + "rule": "Property '[Symbol.toStringTag]' in type 'MyFinalizationRegistry2' is not assignable to the same property in base type 'FinalizationRegistry'.\n Type '\"FinalizationRegistry\" | undefined' is not assignable to type '\"FinalizationRegistry\"'.\n Type 'undefined' is not assignable to type '\"FinalizationRegistry\"'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_class.ets.json b/ets2panda/linter/test/builtin/builtin_class.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..93d76b46940663af5381df85cf13cfb8f4f2f164 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_class.ets.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": 70, + "column": 3, + "endLine": 70, + "endColumn": 23, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 4, + "endLine": 70, + "endColumn": 22, + "problem": "SymbolType", + "suggest": "", + "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 23, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 4, + "endLine": 99, + "endColumn": 22, + "problem": "SymbolType", + "suggest": "", + "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 23, + "problem": "StrictDiagnostic", + "suggest": "Property '[Symbol.toStringTag]' in type 'MyFinalizationRegistry2' is not assignable to the same property in base type 'FinalizationRegistry'.\n Type '\"FinalizationRegistry\" | undefined' is not assignable to type '\"FinalizationRegistry\"'.\n Type 'undefined' is not assignable to type '\"FinalizationRegistry\"'.", + "rule": "Property '[Symbol.toStringTag]' in type 'MyFinalizationRegistry2' is not assignable to the same property in base type 'FinalizationRegistry'.\n Type '\"FinalizationRegistry\" | undefined' is not assignable to type '\"FinalizationRegistry\"'.\n Type 'undefined' is not assignable to type '\"FinalizationRegistry\"'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_decorator.ets b/ets2panda/linter/test/builtin/builtin_decorator.ets new file mode 100644 index 0000000000000000000000000000000000000000..68c12e679052217a3bbbe6d2fc6cd74708936c2a --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_decorator.ets @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 propertyDecorator: PropertyDecorator = (ttt, yyy) => { + console.log(yyy as string); +} + +class A { + @propertyDecorator + prop = 1 +} + +let classDecorator: ClassDecorator = (target) => { return target } + +@classDecorator +class B {} + +let methodDecorator: MethodDecorator = (target, propertyKey, descriptor) => { +console.log(JSON.stringify(descriptor)); +} + +class C { + @methodDecorator + method(): void {} +} + +let paramDecorator: ParameterDecorator = (target, methodName, paramIdx) => { + console.log(methodName as string); +} + +class D { + method(@paramDecorator param: string): void {} +} + +class C implements Iterator { + a: number = 0; + b: number; + constructor (b:number) { + this.b = b; + } + next(): IteratorResult { + if (this.a >= this.b) { + return {value:undefined, done:true} + } + this.a++; + return {value:this.a, done:false} + } + return(): IteratorResult { //error + console.log("call return") + this.a = 0; + return {value:undefined, done:true} + } + throw(e:Error): IteratorResult { //error + console.error("Error: " + e); + return { value: undefined, done: true }; + } +} +let a = new C(5) +a.next() +a.return() +a.throw(new Error("test")) + + +let b = String.raw`a\nb\nc` //error + + +function f(c:TemplateStringsArray, ...values: Object[]) { + c.raw; //error +} +const c: string = "123" +f`Hello, ${c}!` + + +type T1 = number | T1[]; +let arr1: ReadonlyArray = [1, [1]]; +arr1.flat(2); //error + + +type T = number | T[]; +let arr: ReadonlyArray = [1, [1]]; +arr.flatMap((value, index, array) => { //error + return value; +}); + + +let num = new Object(); +num.valueOf(); //error + + +type T2 = number | T2[]; +let arr2: Array = [1, [1]]; +arr2.flat(2); //error + + +const str = ''; +const arr3 = Array.from(str); //error + + +let buff: ArrayBufferTypes = { + ArrayBuffer: new ArrayBuffer(10), + SharedArrayBuffer: new SharedArrayBuffer(10) +} +buff.ArrayBuffer; //error +buff.SharedArrayBuffer; + + +function fn1(iArguments: IArguments) { + Reflect.get(iArguments, Symbol.iterator); //error +} + + +function fn2(iArguments: IArguments) { + iArguments.callee; //error +} + + +function fn3(iArguments: IArguments) { + iArguments.length; //error +} + + +let o: Intl.DateTimeFormatPartTypesRegistry = { + day: undefined, //error + dayPeriod: undefined, //error + era: undefined, //error + hour: undefined, //error + literal: undefined, //error + minute: undefined, //error + month: undefined, //error + second: undefined, //error + timeZoneName: undefined, //error + weekday: undefined, //error + year: undefined, //error + unknown: undefined, + fractionalSecond: undefined +} + + +Intl.DisplayNames.prototype; //error + + +Intl.ListFormat.prototype; //error + + +Intl.NumberFormat.prototype; //error + + +const arr4 = [0, 1, 2, [3, 4]]; +let arr5: FlatArray = arr4.flat(); //error + + +let d: Object = Object(); //error + + +let d1: Object = Object({}); //error + + +const text = '2025-01-01'; +const regex = /(?\d{4})-(?\d{2})-(?\d{2})/; +const match = regex.exec(text); +console.log(match!.groups!.year); //error + + +const text1 = '2025-01-01'; +const regex1 = /(?\d{4})-(?\d{2})-(?\d{2})/; +const match1 = text1.match(regex1); +console.log(match1!.groups!.year); //error + + +class FileReader { + private lines: string[] = ["Line 1", "Line 2", "Line 3"]; + + [Symbol.iterator](): Iterator { + let index = 0; + const self = this; + + return { + next(): IteratorResult { + if (index < self.lines.length) { + return { value: self.lines[index++], done: false }; + } else { + return { value: undefined, done: true }; + } + }, + + return(): IteratorReturnResult { //error + return { done: true, value: index }; + }, + }; + } +} + + +class Counter { + private count: number = 0; + private max: number; + + constructor(max: number) { + this.max = max; + } + + [Symbol.iterator](): Iterator { + const self = this; + + return { + next(): IteratorYieldResult { //error + if (self.count < self.max) { + return { + value: self.count++, + }; + } + + return { done: false, value: -1 }; + }, + }; + } +} diff --git a/ets2panda/linter/test/builtin/builtin_decorator.ets.args.json b/ets2panda/linter/test/builtin/builtin_decorator.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_decorator.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/builtin/builtin_decorator.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_decorator.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f064799fd9eb474c043f862cd11bc78c6efc8255 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_decorator.ets.arkts2.json @@ -0,0 +1,878 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 3, + "endLine": 21, + "endColumn": 21, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 16, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 16, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 62, + "endLine": 30, + "endColumn": 72, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 27, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 27, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 19, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 19, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 25, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 25, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 64, + "endColumn": 4, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 3, + "endLine": 68, + "endColumn": 4, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 25, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 15, + "endLine": 55, + "endColumn": 20, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 32, + "endLine": 55, + "endColumn": 36, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 13, + "endLine": 58, + "endColumn": 18, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 27, + "endLine": 58, + "endColumn": 31, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 13, + "endLine": 60, + "endColumn": 27, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 13, + "endLine": 63, + "endColumn": 18, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 30, + "endLine": 63, + "endColumn": 34, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 3, + "endLine": 65, + "endColumn": 8, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 19, + "endLine": 65, + "endColumn": 33, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 14, + "endLine": 67, + "endColumn": 19, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 32, + "endLine": 67, + "endColumn": 36, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 16, + "endLine": 76, + "endColumn": 19, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 9, + "endLine": 76, + "endColumn": 28, + "problem": "TaggedTemplates", + "suggest": "", + "rule": "Tagged templates are not supported (arkts-no-tagged-templates)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 8, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 16, + "problem": "TaggedTemplates", + "suggest": "", + "rule": "Tagged templates are not supported (arkts-no-tagged-templates)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 6, + "endLine": 88, + "endColumn": 10, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 12, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 15, + "endLine": 98, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 5, + "endLine": 99, + "endColumn": 12, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 6, + "endLine": 104, + "endColumn": 10, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 20, + "endLine": 108, + "endColumn": 24, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 3, + "endLine": 112, + "endColumn": 14, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 26, + "endLine": 113, + "endColumn": 43, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 6, + "endLine": 115, + "endColumn": 17, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 3, + "endLine": 120, + "endColumn": 44, + "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": 120, + "column": 27, + "endLine": 120, + "endColumn": 42, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 14, + "endLine": 125, + "endColumn": 20, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 14, + "endLine": 130, + "endColumn": 20, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 6, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 3, + "endLine": 136, + "endColumn": 12, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 6, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 3, + "endLine": 138, + "endColumn": 7, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 10, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 9, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 8, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 9, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 3, + "endLine": 143, + "endColumn": 15, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 3, + "endLine": 144, + "endColumn": 10, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 3, + "endLine": 145, + "endColumn": 7, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 19, + "endLine": 151, + "endColumn": 28, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 19, + "endLine": 151, + "endColumn": 28, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 17, + "endLine": 154, + "endColumn": 26, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 17, + "endLine": 154, + "endColumn": 26, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 19, + "endLine": 157, + "endColumn": 28, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 19, + "endLine": 157, + "endColumn": 28, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 1, + "endLine": 157, + "endColumn": 18, + "problem": "PropertyDeclOnFunction", + "suggest": "", + "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 11, + "endLine": 161, + "endColumn": 20, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 31, + "endLine": 161, + "endColumn": 33, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 42, + "endLine": 161, + "endColumn": 46, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 17, + "endLine": 164, + "endColumn": 23, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 18, + "endLine": 167, + "endColumn": 24, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 15, + "endLine": 171, + "endColumn": 61, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 20, + "endLine": 173, + "endColumn": 26, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 16, + "endLine": 177, + "endColumn": 62, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 21, + "endLine": 179, + "endColumn": 27, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 4, + "endLine": 185, + "endColumn": 19, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 12, + "endLine": 189, + "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": 190, + "column": 15, + "endLine": 190, + "endColumn": 29, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 20, + "endLine": 192, + "endColumn": 25, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 38, + "endLine": 192, + "endColumn": 45, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 48, + "endLine": 192, + "endColumn": 52, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 20, + "endLine": 194, + "endColumn": 25, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 38, + "endLine": 194, + "endColumn": 42, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 7, + "endLine": 198, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 18, + "endLine": 199, + "endColumn": 22, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 30, + "endLine": 199, + "endColumn": 35, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 4, + "endLine": 214, + "endColumn": 19, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 12, + "endLine": 217, + "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": 221, + "column": 13, + "endLine": 221, + "endColumn": 18, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 18, + "endLine": 225, + "endColumn": 22, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 31, + "endLine": 225, + "endColumn": 36, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_decorator.ets.json b/ets2panda/linter/test/builtin/builtin_decorator.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..653a0772bb0cbe71df761c056e3b94562ecb1921 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_decorator.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": 120, + "column": 3, + "endLine": 120, + "endColumn": 44, + "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": 151, + "column": 19, + "endLine": 151, + "endColumn": 28, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 17, + "endLine": 154, + "endColumn": 26, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 19, + "endLine": 157, + "endColumn": 28, + "problem": "Prototype", + "suggest": "", + "rule": "Prototype assignment is not supported (arkts-no-prototype-assignment)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 12, + "endLine": 189, + "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": 217, + "column": 12, + "endLine": 217, + "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/builtin/builtin_error_negative.ets b/ets2panda/linter/test/builtin/builtin_error_negative.ets new file mode 100755 index 0000000000000000000000000000000000000000..36716c22fd73e9dfe075179dde8342964166cd14 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_negative.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. + */ + +let err1: AggregateError = new AggregateError([1]); //NoPropertyDescriptor +let err2: AggregateError = new AggregateError([1]); //NoPropertyDescriptor +let errors: Object[] = err2.errors; // NoPropertyDescriptor +try { + throw new Error(); //lib.es2022.error.d.ts +} catch (e) { + new Error("Connecting to database failed.", {cause: e}); +} +function get(err: AggregateError):Error { //NoPropertyDescriptor + const a = AggregateError.name; + const errr = Error() //BuiltinNoCtorFunc + return new Error; //lib.es2022.error.d.ts +} +const err3 = new AggregateError([1, "two", new Error("fail")]); //NoPropertyDescriptor +console.log(err3.errors.toString()); // NoPropertyDescriptor +console.log(err3.message); // NoPropertyDescriptor? + +const err4 = new AggregateError( //NoPropertyDescriptor + [new TypeError("invalid type"), new RangeError("out of bounds")], + "Multiple errors occurred" +); +console.log(err4.errors.length.toString()); // NoPropertyDescriptor + BuiltinAll + +function fetchData() { + try { + throw new Error("Network timeout"); //BuiltinNoCtorFunc lib.es2022.error.d.ts + } catch (e) { + return new Error("Fetch failed", { cause: e }); + } +} + +const result = fetchData(); +if (result.cause) {//NoPropertyDescriptor + console.log("Root cause:", result.cause.message); // NoPropertyDescriptor +} +console.log(err4.errors.toString()); // NoPropertyDescriptor + +//sum:18-1 \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_error_negative.ets.args.json b/ets2panda/linter/test/builtin/builtin_error_negative.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_negative.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_error_negative.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_error_negative.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..4b1ce86a71b4df73dff0f89817f6ac45d86a4a36 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_negative.ets.arkts2.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": 16, + "column": 5, + "endLine": 16, + "endColumn": 9, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 9, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 35, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 24, + "endLine": 18, + "endColumn": 28, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 29, + "endLine": 18, + "endColumn": 35, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 48, + "endLine": 22, + "endColumn": 53, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 14, + "endLine": 24, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 21, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 18, + "endLine": 30, + "endColumn": 24, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 11, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 8, + "endLine": 34, + "endColumn": 17, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 39, + "endLine": 34, + "endColumn": 49, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 40, + "endLine": 43, + "endColumn": 45, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 37, + "endLine": 49, + "endColumn": 42, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 13, + "endLine": 51, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 18, + "endLine": 51, + "endColumn": 24, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_error_negative.ets.json b/ets2panda/linter/test/builtin/builtin_error_negative.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_negative.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_error_positive.ets b/ets2panda/linter/test/builtin/builtin_error_positive.ets new file mode 100755 index 0000000000000000000000000000000000000000..80579bdae4ad51ed621a07a3dacf9ca06367d20d --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_positive.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. + */ + +try { + throw new Error(); //lib.es2022.error.d.ts +} catch (e) { + new Error("Connecting to database failed."); +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_error_positive.ets.args.json b/ets2panda/linter/test/builtin/builtin_error_positive.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_positive.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/debugger_statememt.ets.migrate.json b/ets2panda/linter/test/builtin/builtin_error_positive.ets.arkts2.json old mode 100644 new mode 100755 similarity index 100% rename from ets2panda/linter/test/main/debugger_statememt.ets.migrate.json rename to ets2panda/linter/test/builtin/builtin_error_positive.ets.arkts2.json diff --git a/ets2panda/linter/test/builtin/builtin_error_positive.ets.json b/ets2panda/linter/test/builtin/builtin_error_positive.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_error_positive.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_iterator_result.ets b/ets2panda/linter/test/builtin/builtin_iterator_result.ets new file mode 100644 index 0000000000000000000000000000000000000000..cbe6df9118a642183a709ba14cde9f02b56c7a34 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_iterator_result.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 arr = new Array('a'); +let iterator = arr.entries(); +let result = iterator.next(); +result.value[0]; + +arr.entries().next().value; \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_iterator_result.ets.args.json b/ets2panda/linter/test/builtin/builtin_iterator_result.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_iterator_result.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/builtin/builtin_iterator_result.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_iterator_result.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..424cd6f851e3cfbe47fcada0b4e4e52faee17c2f --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_iterator_result.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": 15, + "endLine": 16, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 13, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 27, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "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/builtin/builtin_iterator_result.ets.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json rename to ets2panda/linter/test/builtin/builtin_iterator_result.ets.json 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 index 1903c3e2db6fab4db83853f6b6de1ccf22dac0ae..f0f3bcf5e33f33376d4504915fa317fb121feb20 100644 --- 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 @@ -54,6 +54,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 17, + "column": 4, + "endLine": 17, + "endColumn": 16, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 18, "column": 2, @@ -64,6 +74,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 18, + "column": 4, + "endLine": 18, + "endColumn": 14, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 19, "column": 2, @@ -74,6 +94,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 20, "column": 2, @@ -84,6 +114,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 12, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 21, "column": 2, @@ -125,23 +165,53 @@ "severity": "ERROR" }, { - "line": 27, + "line": 26, "column": 3, - "endLine": 27, - "endColumn": 35, - "problem": "ObjectLiteralProperty", + "endLine": 26, + "endColumn": 8, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { "line": 28, - "column": 3, + "column": 7, "endLine": 28, - "endColumn": 32, - "problem": "ObjectLiteralProperty", + "endColumn": 8, + "problem": "ParameterType", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 13, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 3, + "endLine": 30, + "endColumn": 15, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 11, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { @@ -174,6 +244,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 19, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 39, "column": 5, @@ -184,6 +264,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 40, "column": 5, @@ -194,6 +284,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 12, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 41, "column": 5, @@ -204,6 +304,16 @@ "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, + { + "line": 41, + "column": 7, + "endLine": 41, + "endColumn": 15, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, { "line": 42, "column": 5, @@ -235,23 +345,53 @@ "severity": "ERROR" }, { - "line": 48, + "line": 47, "column": 5, - "endLine": 48, - "endColumn": 41, - "problem": "ObjectLiteralProperty", + "endLine": 47, + "endColumn": 10, + "problem": "NoPropertyDescriptor", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { "line": 49, - "column": 5, + "column": 9, "endLine": 49, - "endColumn": 34, - "problem": "ObjectLiteralProperty", + "endColumn": 10, + "problem": "ParameterType", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 15, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 17, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 13, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/builtin/builtin_object_negative.ets b/ets2panda/linter/test/builtin/builtin_object_negative.ets new file mode 100755 index 0000000000000000000000000000000000000000..cc99adc965614c99767d18b946aa08ddf23b829f --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_negative.ets @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//NumberConstructor +const num1 = new Number('123');//BuiltinNewCtor 1 +Number('123');//BuiltinNoCtorFunc 1 +console.log(Number(undefined).toString());//BuiltinNoCtorFunc 1 +Number.isFinite(1) //BuiltinAll 1 +Number.isInteger(true) //BuiltinAll 1 +Number.isNaN(true) //BuiltinAll 1 +Number.isSafeInteger(true) //BuiltinAll 1 +isFinite(11); +//ObjectConstructor +interface Person { + name: string; + age: number; +} +const obj: Person = { + name: '', + age: 42 +}; +const a: [string, number][] = Object.entries(obj);//BuiltinAll 1 +Object.values(obj);//BuiltinAll 1 + +const entries: Map = new Map([ + ['1', '2'] +]); +const obj1 = Object.fromEntries(entries);//BuiltinAll 1 +typeof new Object();//BuiltinAll 1 + +//String +new String(undefined);//BuiltinNewCtor 1 +String('');//BuiltinNoCtorFunc 1 +const str: string = 'abc'; +str.replace('a', 'b'); +str.replaceAll('a', 'b'); +class Demo implements String{ + replaceAll1(searchValue: string | RegExp, replacer: string): string { + + } + replaceAll(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string{//BuiltinAll 1 + + } +} +//replace(searchValue: string | RegExp, replaceValue: string): string; +const text = "Hello World, World!"; +const result1 = text.replace("World", "TypeScript"); +const result2 = text.replace(/World/g, "TypeScript"); + +//replace(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string; +function toUpperCaseReplacer(match: string): string { + return match.toUpperCase(); +} +text.replace('',toUpperCaseReplacer)//BuiltinAll 1 +const result4 = text.replace("world", (match) => match.toUpperCase());//BuiltinAll 1 +const result5 = text.replace("/(\w+) (\w+)/", (first, last:number) => `${last}, ${first}`);//BuiltinAll 1 +//replace(searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string; +//lib.es2015.symbol.wellknown.d.ts +const result6 = text.replace(/-/g, (match, offset:string) => `-${offset}-`);//BuiltinAll!! +const camelCase = text.replace(/_(\w)/g, (_, char:string) => char.toUpperCase());//BuiltinAll!! +console.log(camelCase); +const prices = { apple: 5, banana: 3 }; +function pricesChange(count:string, fruit:string){ + const price = prices[fruit as keyof typeof prices] || 0; + return `${count} ${fruit} ($${price * parseInt(count)})`; +} +const result7 = text.replaceAll(/(\d+)\s+(\w+)/g, pricesChange);//BuiltinAll 1 + +//WeakMapConstructor +interface Person1 { + age: number; +} +const key1: Person1 = {age: 12}; +const key2: Person1 = {age: 123}; +const weakMap = new WeakMap([ // 0 lib.es2015.iterable.d.ts + [key1, 'value1'], + [key2, 'value2'] +]); +//JSON +const a = JSON.stringify({x: 5, y: 6});//BuiltinAll 1 +class Test implements JSON{ + stringify(value: string, replacer?: (number | string)[] | null, space?: string | number): string{//BuiltinAll 1 + return ''; + } + str: String = ''; + get() { + return this.str; + } +} +const d = new Test(); +d.get().replaceAll('a', pricesChange);//BuiltinAll 1 + +const boolObj1 = new Boolean(true); //BuiltinNewCtor +console.log(boolObj1.valueOf()); +console.log(new Test().valueOf()); //BuiltinAll +console.log(typeof boolObj1); +const tt = new Test(); +typeof tt.valueOf; //BuiltinAll?? +const boolObj2 = new Boolean(""); //BuiltinNewCtor +const boolObj3 = new Boolean(null); //BuiltinNewCtor +const boolObj4 = new Boolean(0); //BuiltinNewCtor + +//sum:27 diff --git a/ets2panda/linter/test/builtin/builtin_object_negative.ets.args.json b/ets2panda/linter/test/builtin/builtin_object_negative.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_negative.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_object_negative.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_object_negative.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..29902703e0120f3d0107057e2d0e9716281a789d --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_negative.ets.arkts2.json @@ -0,0 +1,508 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 18, + "endLine": 16, + "endColumn": 24, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 7, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 13, + "endLine": 18, + "endColumn": 19, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 8, + "endLine": 19, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 17, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 13, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 8, + "endLine": 22, + "endColumn": 21, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 50, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 38, + "endLine": 33, + "endColumn": 45, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 8, + "endLine": 34, + "endColumn": 14, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 38, + "endLine": 38, + "endColumn": 3, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 21, + "endLine": 39, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 21, + "endLine": 39, + "endColumn": 32, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 12, + "endLine": 40, + "endColumn": 18, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 22, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 11, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 7, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 23, + "endLine": 48, + "endColumn": 29, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 3, + "endLine": 54, + "endColumn": 4, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 44, + "endLine": 52, + "endColumn": 99, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 83, + "endLine": 52, + "endColumn": 86, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 30, + "endLine": 59, + "endColumn": 38, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 6, + "endLine": 65, + "endColumn": 13, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 29, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 22, + "endLine": 67, + "endColumn": 29, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 30, + "endLine": 70, + "endColumn": 34, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 32, + "endLine": 71, + "endColumn": 40, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 16, + "endLine": 73, + "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": 75, + "column": 17, + "endLine": 75, + "endColumn": 53, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 39, + "endLine": 75, + "endColumn": 45, + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 22, + "endLine": 78, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 33, + "endLine": 78, + "endColumn": 49, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 16, + "endLine": 91, + "endColumn": 25, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 16, + "endLine": 91, + "endColumn": 25, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 95, + "endColumn": 4, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"JSON\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 95, + "endColumn": 4, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 13, + "endLine": 93, + "endColumn": 26, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 28, + "endLine": 93, + "endColumn": 65, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 9, + "endLine": 102, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 18, + "endLine": 104, + "endColumn": 35, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 22, + "endLine": 104, + "endColumn": 29, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 24, + "endLine": 106, + "endColumn": 31, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 18, + "endLine": 110, + "endColumn": 33, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 22, + "endLine": 110, + "endColumn": 29, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 18, + "endLine": 111, + "endColumn": 35, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 22, + "endLine": 111, + "endColumn": 29, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 18, + "endLine": 112, + "endColumn": 32, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 22, + "endLine": 112, + "endColumn": 29, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/builtin/builtin_object_negative.ets.json b/ets2panda/linter/test/builtin/builtin_object_negative.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..3ca8258156305d1d082ccd73ce6c961baaa5dd1e --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_negative.ets.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": 39, + "column": 14, + "endLine": 39, + "endColumn": 41, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 83, + "endLine": 52, + "endColumn": 86, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 16, + "endLine": 73, + "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": 75, + "column": 17, + "endLine": 75, + "endColumn": 53, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 39, + "endLine": 75, + "endColumn": 45, + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_positive.ets b/ets2panda/linter/test/builtin/builtin_object_positive.ets new file mode 100755 index 0000000000000000000000000000000000000000..876d5d13ce25b5f3e472ae79609f2d1e25077944 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_positive.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. + */ +const str: string = 'abc'; +str.replace('a', 'b'); +str.replaceAll('a', 'b'); +class Demo implements String{ //BuiltinFinalClass + replaceAll1(searchValue: string | RegExp, replacer: string): string { + + } +} +//replace(searchValue: string | RegExp, replaceValue: string): string; +const text = "Hello World, World!"; +const result1 = text.replace("World", "TypeScript"); +const result2 = text.replace(/World/g, "TypeScript"); + +//lib.es2015.symbol.wellknown.d.ts +const result6 = text.replace(/-/g, (match, offset:string) => `-${offset}-`); +const camelCase = text.replace(/_(\w)/g, (_, char:string) => char.toUpperCase()); \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_positive.ets.args.json b/ets2panda/linter/test/builtin/builtin_object_positive.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_positive.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_object_positive.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_object_positive.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7e7f373314ddd372af50cd4c50f48ba36d49e769 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_positive.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": 18, + "column": 23, + "endLine": 18, + "endColumn": 29, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 30, + "endLine": 26, + "endColumn": 38, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 30, + "endLine": 29, + "endColumn": 34, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 32, + "endLine": 30, + "endColumn": 40, + "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/builtin/builtin_object_positive.ets.json b/ets2panda/linter/test/builtin/builtin_object_positive.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_positive.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_symbol_iterator.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json index 36254158540286646fc21063b6b306396f132eb7..2a6b56517a1405887a664ab9dc3192310aed2963 100755 --- a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "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": 17, "column": 40, diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json index 8af4f78669b31c787e4cd40ae005aff560769df3..28c397d84b60c01802aa10c57ae051b20a183e7c 100755 --- a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json @@ -13,5 +13,16 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "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" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets b/ets2panda/linter/test/builtin/builtin_thisArgs.ets index 2a73669055134cc6b5b85d4c122a6da9a8e27bfb..912735bad56789edf367eca985b674b4c760f8f1 100755 --- a/ets2panda/linter/test/builtin/builtin_thisArgs.ets +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets @@ -23,9 +23,17 @@ Class MyClass { } } -let arr: Array = new Array(1, 2, 3); +let arr: Array = new Array(1, 2, 3); //BuiltinNewCtor 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 +arr.filter(a.compare, b); + +type T = number | T[]; +let arr: ReadonlyArray = [[1.0, 2.0], 3.0, [4.0, 5.0]]; +arr.flatMap( + (value, index, array) => { + return value; + } +); \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json index 937b8aef5ee8b2d2f9113c13c5d489145ea28cd6..738f2b023c0a649d79bb854723ea81c0a506e9b5 100755 --- a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json @@ -24,6 +24,16 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, + { + "line": 26, + "column": 30, + "endLine": 26, + "endColumn": 35, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, { "line": 27, "column": 5, @@ -74,26 +84,6 @@ "rule": "Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)", "severity": "ERROR" }, - { - "line": 29, - "column": 1, - "endLine": 29, - "endColumn": 25, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 22, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 31, "column": 1, @@ -103,16 +93,6 @@ "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": "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/builtin/builtin_uninitialized_element.ets b/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets new file mode 100644 index 0000000000000000000000000000000000000000..50efe4e895bbc05a7fdf02535d697bc173ab054e --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_uninitialized_element.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. + */ + +let arr = new Array(10); +let arr1 = new Array(10); +let arr2 = new Array(); +new Array(100); +new Array(100); +new Array([1, 2]); +new Array([1, 2]); +new Array(['1', '2']); + +function test(): number { + return 1; +} + +new Array(test()); \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.args.json b/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/prop_name_from_value.ets.args.json rename to ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.args.json diff --git a/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5642d5965993081bfeb2a76568c65caa6863daa3 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_uninitialized_element.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": 15, + "endLine": 16, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 11, + "endLine": 16, + "endColumn": 32, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 12, + "endLine": 17, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 12, + "endLine": 17, + "endColumn": 25, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 16, + "endLine": 18, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 12, + "endLine": 18, + "endColumn": 23, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 23, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 15, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 15, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 10, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 18, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.json b/ets2panda/linter/test/builtin/builtin_uninitialized_element.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..1de3f8f971ad906f61ac5459f333fb1993853bda --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_uninitialized_element.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": 5, + "endLine": 17, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "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/concurrent/@ohos.taskpool.ets b/ets2panda/linter/test/concurrent/@ohos.taskpool.ets new file mode 100755 index 0000000000000000000000000000000000000000..52a0d01da6b39a975c7146f9c643c5191fb19105 --- /dev/null +++ b/ets2panda/linter/test/concurrent/@ohos.taskpool.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 func = ()=>void +export namespace taskpool{ + export function isConcurrent(param:func):boolean { + return true + } +} +export namespace otherTaskPool{ + export function isConcurrent(param:func):boolean { + return true + } +} diff --git a/ets2panda/linter/test/concurrent/@ohos.taskpool.ets.args.json b/ets2panda/linter/test/concurrent/@ohos.taskpool.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..0adede204e309a92c8aac08d89f6af16d9c93f78 --- /dev/null +++ b/ets2panda/linter/test/concurrent/@ohos.taskpool.ets.args.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." + ], + "mode": { + } +} diff --git a/ets2panda/linter/test/concurrent/@ohos.taskpool.ets.json b/ets2panda/linter/test/concurrent/@ohos.taskpool.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/concurrent/@ohos.taskpool.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.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json index a392b58e6916b7f1c713e54314a1f43d02d4763e..f7eb69088ba1b002091c726d8cc2e87c1604abfb 100644 --- a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json @@ -65,4 +65,4 @@ "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 index 3a526714e45c4e0615ea0d437830a3d900eac89e..23a255e1ae4204fa975bba5d03088b8477a4fb64 100644 --- a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 618, "end": 629, - "replacementText": "" + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 12 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 659, "end": 670, - "replacementText": "" + "replacementText": "", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12 } ], "suggest": "", @@ -58,7 +66,11 @@ { "start": 707, "end": 718, - "replacementText": "" + "replacementText": "", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 12 } ], "suggest": "", @@ -75,7 +87,11 @@ { "start": 748, "end": 759, - "replacementText": "" + "replacementText": "", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12 } ], "suggest": "", @@ -93,4 +109,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets new file mode 100644 index 0000000000000000000000000000000000000000..c743b39bc25352fb3802ffe6937c8dd7898f9aa9 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.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 { process } from '../main/oh_modules/@kit.ArkTS'; + +// Deprecated APIs +process.isAppUid(12.0); // error +process.getUidForName('root'); // error +process.getThreadPriority(1.0); // error +process.getSystemConfig(1.0); // error +process.getEnvironmentVar('PATH'); // error +process.exit(0.0); // error +process.kill(6.0, 1.0); // error + +process.anyOtherMethod() // ok diff --git a/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.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/concurrent/concurrent_process_deprecated_apis.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2001c8e9d60d0a365c70a8eb617338690b767121 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.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": 16, + "column": 10, + "endLine": 16, + "endColumn": 17, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 8, + "problem": "DeprecatedProcessApi", + "suggest": "", + "rule": "This API of process is obsolete in ArkTS 1.1. It's no longer supported in ArkTS 1.2 (arkts-concurrent-deprecated-apis)", + "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/concurrent/concurrent_process_deprecated_apis.ets.json similarity index 100% rename from ets2panda/linter/test/main/prop_name_from_value.ets.json rename to ets2panda/linter/test/concurrent/concurrent_process_deprecated_apis.ets.json diff --git a/ets2panda/test/parser/ets/local-interface.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets old mode 100644 new mode 100755 similarity index 55% rename from ets2panda/test/parser/ets/local-interface.ets rename to ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets index 9aeed4261a9a51f7be4b28e97614845772b40842..a0e9c55367f1546d3e120937ca8372b2473fef37 --- a/ets2panda/test/parser/ets/local-interface.ets +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets @@ -1,20 +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. - */ - -function main() : int -{ - interface LocalInterface { } - return 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. + */ +import { SharedArrayBuffer } from './oh_modules/sharedArrayBuffer' + +let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts +s1.slice(0) +type sharedArray = SharedArrayBuffer +let s2: sharedArray; +type mapShare = Map +{ + let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts + let s2:sharedArray; +} +function fun6(pa:sharedArray) { + let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts + let s2:sharedArray; } \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3318ebbbcfd0ce90dc5f69df69452a3201e4204d --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_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_sharedarraybuffer1_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.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/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.autofix.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.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/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..fae7c2a3fe332707886d01e70ea981341f927c59 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_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_sharedarraybuffer1_arkts2.ets.migrate.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0e9c55367f1546d3e120937ca8372b2473fef37 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.ets @@ -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. + */ +import { SharedArrayBuffer } from './oh_modules/sharedArrayBuffer' + +let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts +s1.slice(0) +type sharedArray = SharedArrayBuffer +let s2: sharedArray; +type mapShare = Map +{ + let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts + let s2:sharedArray; +} +function fun6(pa:sharedArray) { + let s1 = new SharedArrayBuffer(1) //lib.es2017.sharedmemory.d.ts + let s2:sharedArray; +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_arkts2.ets.migrate.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer1_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/concurrent/concurrent_sharedarraybuffer_arkts2.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets index d3e0b2ca58ad6fde6ac4d5ba2e1d5e38bafd84a0..b6c511a7ad6194f0e29ea43ba3fa1b6843bcd5ca 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets @@ -21,4 +21,10 @@ 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 +function foo(atmo: Atomics) {} // NOT ERROR + +class A extends SharedArrayBuffer { + constructor() { + supper(1) + } +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json index 4914a0e04a5e8b68080870d071e75a4b4e158639..afa0bcaf5dcf732ce78a8ef1918853c6df697cf4 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json @@ -63,6 +63,16 @@ "suggest": "", "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", "severity": "ERROR" + }, + { + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 34, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "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 index da0b259374868118fedbdc520d2e21a9ac29ba80..5665081830ea79823ca1c1d8541da0634a98a623 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json @@ -1,103 +1,144 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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": [ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ { - "replacementText": "ArrayBuffer", - "start": 624, - "end": 641 - } - ], - "suggest": "", - "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 10, - "endLine": 17, - "endColumn": 27, - "problem": "SharedArrayBufferDeprecated", - "autofix": [ + "line": 16, + "column": 15, + "endLine": 16, + "endColumn": 32, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "start": 624, + "end": 641, + "replacementText": "ArrayBuffer", + "line": 16, + "column": 15, + "endLine": 16, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, { - "replacementText": "ArrayBuffer", - "start": 661, - "end": 678 - } - ], - "suggest": "", - "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 34, - "endLine": 17, - "endColumn": 51, - "problem": "SharedArrayBufferDeprecated", - "autofix": [ + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "start": 661, + "end": 678, + "replacementText": "ArrayBuffer", + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, { - "replacementText": "ArrayBuffer", - "start": 685, - "end": 702 - } - ], - "suggest": "", - "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 20, - "endLine": 19, - "endColumn": 37, - "problem": "SharedArrayBufferDeprecated", - "autofix": [ + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "start": 685, + "end": 702, + "replacementText": "ArrayBuffer", + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, { - "replacementText": "ArrayBuffer", - "start": 737, - "end": 754 - } - ], - "suggest": "", - "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 28, - "endLine": 22, - "endColumn": 45, - "problem": "SharedArrayBufferDeprecated", - "autofix": [ + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "start": 737, + "end": 754, + "replacementText": "ArrayBuffer", + "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": [ + { + "start": 853, + "end": 870, + "replacementText": "ArrayBuffer", + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, { - "replacementText": "ArrayBuffer", - "start": 853, - "end": 870 + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 34, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "start": 945, + "end": 962, + "replacementText": "ArrayBuffer", + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 34 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" } - ], - "suggest": "", - "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", - "severity": "ERROR" - } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets index 6eaad40c1a5ffbe1fc2f9504cccec7da44362ec9..0b8ccbce20dd0e5dbb8df867eeeff48ea8ae2685 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets @@ -21,4 +21,10 @@ let newTypeName: NewTypeName // disable use new NewTypeName() let ntn: NewTypeName = new ArrayBuffer(0) // ERROR -function foo(atmo: Atomics) {} // NOT ERROR \ No newline at end of file +function foo(atmo: Atomics) {} // NOT ERROR + +class A extends ArrayBuffer { + constructor() { + supper(1) + } +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json index 43cb4a27bcc78710d4aa5130c22ee053f66c3fbc..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json @@ -1,3 +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/no_support_arktsutils_locks_asynclock.ets b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets new file mode 100644 index 0000000000000000000000000000000000000000..d94d1d8c0ea0922836c9ad26a7a4557e79a06d6f --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.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 { ArkTSUtils } from '../main/oh_modules/@kit.ArkTS'; + +let lock1 = new ArkTSUtils.locks.AsyncLock(); + +let lock2 = new ArkTSUtils.locks.AsyncLock(); diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.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/no_support_arktsutils_locks_asynclock.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1dc77c9110c143ff5fcf5fdd6860ed2561825bc1 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.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": 10, + "endLine": 16, + "endColumn": 20, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 28, + "endLine": 18, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..4f28a159bfea63a3a7182761658f4eb20258ffda --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.autofix.json @@ -0,0 +1,81 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 20, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 605, + "end": 664, + "replacementText": "", + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 28, + "endLine": 18, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 678, + "end": 710, + "replacementText": "new AsyncLock()", + "line": 18, + "column": 28, + "endLine": 18, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 725, + "end": 757, + "replacementText": "new AsyncLock()", + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33 + } + ], + "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/concurrent/no_support_arktsutils_locks_asynclock.ets.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.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/no_support_arktsutils_locks_asynclock.ets.migrate.ets b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ee4ccf8991d7133a58c64c115603eef0fee634d --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.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 lock1 = new AsyncLock(); + +let lock2 = new AsyncLock(); diff --git a/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..104753dbf8b0d81802eedb16efed99e7d0cadcfb --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_arktsutils_locks_asynclock.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": 18, + "column": 5, + "endLine": 18, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 26, + "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": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 26, + "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/concurrent/no_support_isconcurrent.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json index ca28292f8e4d54b3a473114b5d2238f3fa55c03f..45c876de1fe4016de81e4c8b7c0665e6034c2937 100644 --- a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json @@ -13,26 +13,56 @@ "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" - } - ] + "result": [ + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 18, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 24, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "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": 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_isconcurrent2.ets b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets new file mode 100755 index 0000000000000000000000000000000000000000..2db768e0e8304c82051608308777fe918f3c97c6 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.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 { taskpool } from '@ohos.taskpool'; +import { taskpool as taskpool2 } from './@ohos.taskpool'; +import { otherTaskPool as taskpool1 } from './@ohos.taskpool'; + +function test1(){ +} +function isConcurrent() {} + +typeof taskpool.isConcurrent() ; //error +function test(){ + taskpool.isConcurrent(test5()) ; //error +} + +console.log(''+taskpool2.isConcurrent(test1)); + +taskpool2.isConcurrent(test1) +taskpool2.isConcurrent(test1) +taskpool2.isConcurrent(isConcurrent) +function test5(){ + taskpool2.isConcurrent(test1) + taskpool2.isConcurrent(test1) + taskpool2.isConcurrent(isConcurrent) +} +class Demo{ + get(){ + return taskpool1.isConcurrent(test); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets.args.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.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_isconcurrent2.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..25c12086b0fe149b891963542797bd3fceee5109 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.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": 15, + "column": 10, + "endLine": 15, + "endColumn": 18, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 31, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 25, + "endLine": 25, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..b9331d05ba1f182a8a451c219c9e51bcd4e67188 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent2.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/test/compiler/ets/rethrowingCheck4.ets b/ets2panda/linter/test/concurrent/oh_modules/sharedArrayBuffer.ts old mode 100644 new mode 100755 similarity index 49% rename from ets2panda/test/compiler/ets/rethrowingCheck4.ets rename to ets2panda/linter/test/concurrent/oh_modules/sharedArrayBuffer.ts index 7541229e7f3cbd04610433727913053c5ade1b39..cc5c84462f2a1a18a5f3644c13742d25b878daa7 --- a/ets2panda/test/compiler/ets/rethrowingCheck4.ets +++ b/ets2panda/linter/test/concurrent/oh_modules/sharedArrayBuffer.ts @@ -1,26 +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. - */ - -function b(foo: () => void throws) rethrows { - foo(); -} - -function foo() throws { - throw new Exception("I am an exception"); -} - -function bar(b: () => void throws) rethrows { - b(); -} +/* + * 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. + */ +// oh_modules/sharedArrayBuffer.ts +export interface SharedArrayBuffer { + /** + * Read-only. The length of the ArrayBuffer (in bytes). + */ + readonly byteLength: number; + +/** + * Returns a section of an SharedArrayBuffer. + */ + slice(begin: number, end?: number): SharedArrayBuffer; +} +interface SharedArrayBufferConstructor { + readonly prototype: SharedArrayBuffer; + new (byteLength: number): SharedArrayBuffer; +} +export declare var SharedArrayBuffer: SharedArrayBufferConstructor; + diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets index 22ef20b645ce008ca5ad7b59f5a35eed82cac0c0..6e6dfcec0288600fab3ffb50536b034c7b3ccfb3 100644 --- a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets @@ -39,3 +39,16 @@ switch (variable2) { case 'use shared': break; } + +function refreshToGetFontScale(): number { + 'use concurrent'; + const TAG = 'SCBScreenLock-refreshToGetFontScale'; + const log: LogHelper = LogHelper.getLogHelper(LogDomain.KG, TAG); + const FONT_SCALE_DEFAULT: number = 1; + try { + return uiAppearance.getFontScale(); + } catch (err) { + log.showError(`uiAppearance getFontScale err,code:${err?.code}`); + } + return FONT_SCALE_DEFAULT; +} 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 index 0a82914a53a6b965b052de59bd9d4bfe1d740554..f9dfdc772dc83fd212964400eda77a02506f0007 100644 --- a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json @@ -43,6 +43,16 @@ "suggest": "", "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 19, + "problem": "UseConcurrentDeprecated", + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" } ] -} +} \ No newline at end of file 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 index 052fc5f382c68d4ab6c6584c022fc23f840cb135..5bbd946da0b12511ee81ffdc5c5cf44556892866 100644 --- a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 605, "end": 617, - "replacementText": "" + "replacementText": "", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 13 } ], "suggest": "", @@ -51,7 +55,32 @@ { "start": 687, "end": 703, - "replacementText": "" + "replacementText": "", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 19, + "problem": "UseConcurrentDeprecated", + "autofix": [ + { + "start": 1019, + "end": 1036, + "replacementText": "", + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 19 } ], "suggest": "", @@ -59,4 +88,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file 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 index 5224e3b79f6ce4d369dcfc9ebaa26a63bc1b9219..3d0a51440ae6f35d669fc08ab51b7b3e344b0cdd 100644 --- a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets @@ -39,3 +39,16 @@ switch (variable2) { case 'use shared': break; } + +function refreshToGetFontScale(): number { + + const TAG = 'SCBScreenLock-refreshToGetFontScale'; + const log: LogHelper = LogHelper.getLogHelper(LogDomain.KG, TAG); + const FONT_SCALE_DEFAULT: number = 1; + try { + return uiAppearance.getFontScale(); + } catch (err) { + log.showError(`uiAppearance getFontScale err,code:${err?.code}`); + } + return FONT_SCALE_DEFAULT; +} diff --git a/ets2panda/linter/test/deprecatedapi/Back.ets b/ets2panda/linter/test/deprecatedapi/Back.ets new file mode 100755 index 0000000000000000000000000000000000000000..9f52ca72486548b68cc1538a40cdd998d6cb1e6b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Back.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. + */ +import { NavigationType } from './sdk/api/navigator' + +@Entry +@Component +struct Index { + build() { + Column() { + Navigator() { + Text('Back') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Back) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Back.ets.args.json b/ets2panda/linter/test/deprecatedapi/Back.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Back.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/deprecatedapi/Back.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Back.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..6be00cdd5440b6a9045e172b2665a21ddb0cdfed --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Back.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": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 21, + "endLine": 31, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Back.ets.json b/ets2panda/linter/test/deprecatedapi/Back.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Back.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/deprecatedapi/Baseline.ets b/ets2panda/linter/test/deprecatedapi/Baseline.ets new file mode 100755 index 0000000000000000000000000000000000000000..8890bc6380cf7b18a961f26f2ebfef1280c9e0c9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Baseline.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. + */ +import { Edge } from './sdk/api/enums'; + +@Entry +@Component +struct ScrollExample { + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + build() { + Stack({ alignContent: Alignment.TopStart }) { + Scroll(this.scroller) { + Column() { + ForEach(this.arr, (item: number) => { + Text(item.toString()) + .width('90%') + .height(150) + .backgroundColor(0xFFFFFF) + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .margin({ top: 10 }) + }, (item: string) => item) + }.width('100%') + } + .onScrollStop(() => { + const side1 = Edge.Baseline; + console.info('Scroll Stop'); + }) + }.width('100%').height('100%').backgroundColor(0xDCDCDC) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Baseline.ets.args.json b/ets2panda/linter/test/deprecatedapi/Baseline.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Baseline.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/deprecatedapi/Baseline.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Baseline.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..c93cba3dfae43680a4ac724b7a4f01c5f5c11f8e --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Baseline.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": 20, + "column": 28, + "endLine": 20, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 15, + "endLine": 40, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 13, + "endLine": 20, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Stack\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 27, + "endLine": 24, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Alignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroll\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 11, + "endLine": 27, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 13, + "endLine": 28, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 26, + "endLine": 34, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Baseline.ets.json old mode 100644 new mode 100755 similarity index 75% rename from ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json rename to ets2panda/linter/test/deprecatedapi/Baseline.ets.json index 4218268d314b5d23e17b0cb47ab709da3f410059..a8df15b58dcdfae228f6576c7342da649e364ff0 --- a/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json +++ b/ets2panda/linter/test/deprecatedapi/Baseline.ets.json @@ -15,13 +15,13 @@ ], "result": [ { - "line": 23, - "column": 13, - "endLine": 23, - "endColumn": 20, - "problem": "UnsupportPropNameFromValue", + "line": 40, + "column": 15, + "endLine": 40, + "endColumn": 36, + "problem": "AnyType", "suggest": "", - "rule": "Enum cannot get member name by member value (arkts-unsupport-prop-name-from-value)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/deprecatedapi/COMPONENT.ets b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets new file mode 100755 index 0000000000000000000000000000000000000000..04819456ce65d079caf6bdb63471e3ab80fb70b4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/COMPONENT.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 { XComponentType } from './sdk/api/enums'; + +@Entry +@Component +struct Index { + @State isLock: boolean = true; + @State xc_width: number = 500; + @State xc_height: number = 700; + myXComponentController: XComponentController = new MyXComponentController(); + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) { + XComponent({ + id: "XComponent", + type: XComponentType.COMPONENT, + controller: this.myXComponentController + }) + .onLoad(() => { + let surfaceRotation: SurfaceRotationOptions = { lock: this.isLock }; + this.myXComponentController.setXComponentSurfaceRotation(surfaceRotation); + console.log("getXComponentSurfaceRotation lock = " + + this.myXComponentController.getXComponentSurfaceRotation().lock); + }) + .width(this.xc_width) + .height(this.xc_height) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.args.json b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/COMPONENT.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/deprecatedapi/COMPONENT.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..06b2a341bf7163b7bf8e00222c40cd2842b81e5e --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/COMPONENT.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": 23, + "column": 54, + "endLine": 23, + "endColumn": 76, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 30, + "endLine": 29, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"COMPONENT\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponentController\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 37, + "endLine": 26, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 57, + "endLine": 26, + "endColumn": 66, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 91, + "endLine": 26, + "endColumn": 100, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 32, + "endLine": 33, + "endColumn": 54, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SurfaceRotationOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.json b/ets2panda/linter/test/deprecatedapi/COMPONENT.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/COMPONENT.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/deprecatedapi/CROSS_DEVICE.ets b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets new file mode 100755 index 0000000000000000000000000000000000000000..24c939c273c158b902a870cd139a590c06ba19fd --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.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. + */ +import { CopyOptions } from './sdk/api/enums'; + +@Component +struct child { + @Link customPopup: boolean + build() { + Column({ space: 10 }) { + Text('CROSS_DEVICE') + .copyOption(CopyOptions.CROSS_DEVICE) + .borderWidth(1) + .gesture(LongPressGesture({ repeat: true }) + .onActionEnd((event: GestureEvent) => { + this.customPopup = !this.customPopup + }) + ) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets.args.json b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.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/deprecatedapi/CROSS_DEVICE.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b401d4de7a8803d73544c45ccd6a071da1d93aad --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.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": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Link\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 18, + "endLine": 25, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"LongPressGesture\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 32, + "endLine": 26, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GestureEvent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets.json b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/CROSS_DEVICE.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/deprecatedapi/DeleteProp.ets b/ets2panda/linter/test/deprecatedapi/DeleteProp.ets new file mode 100755 index 0000000000000000000000000000000000000000..b5530beaf728f7870fffc6551318609e1a584d24 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/DeleteProp.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 { PersistentStorage } from './sdk/api/common_ts_ets_api'; + +PersistentStorage.DeleteProp('data1') \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/DeleteProp.ets.args.json b/ets2panda/linter/test/deprecatedapi/DeleteProp.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/DeleteProp.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/deprecatedapi/DeleteProp.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/DeleteProp.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/DeleteProp.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/deprecatedapi/DeleteProp.ets.json b/ets2panda/linter/test/deprecatedapi/DeleteProp.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/DeleteProp.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/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..20a4233eb7cd7f491bf2b9b1f335c204fbbe3f5c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.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. + */ +import router from './sdk/api/@system.router'; + +class L{ + enableAlertBeforeBackPage() { + router.enableAlertBeforeBackPage({ + message: 'Message Info', + success: ()=> { + console.log('success'); + }, + cancel: ()=> { + console.log('cancel'); + } + }); + } +} +export default new L() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.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/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b2dbe822307a6b71fd6c0a72ef02539b4c864b9f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.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": 12, + "endLine": 19, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"enableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.json b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/EnableAlertBeforeBackPageOptions_api.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/deprecatedapi/Link.ets b/ets2panda/linter/test/deprecatedapi/Link.ets new file mode 100755 index 0000000000000000000000000000000000000000..9f9a1cbd126972e8bea6af5b01d3ef1a17a57432 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Link.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 { AppStorage } from './sdk/api/common_ts_ets_api'; + +AppStorage.setOrCreate('PropA', 47); +let link1: SubscribedAbstractProperty = AppStorage.Link('PropA'); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Link.ets.args.json b/ets2panda/linter/test/deprecatedapi/Link.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Link.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/deprecatedapi/Link.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Link.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..a7692ce6523c271aa69ebc6693c0226ff43b5349 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Link.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": 12, + "endLine": 18, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Link.ets.json b/ets2panda/linter/test/deprecatedapi/Link.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Link.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/deprecatedapi/NavigationType.ets b/ets2panda/linter/test/deprecatedapi/NavigationType.ets new file mode 100755 index 0000000000000000000000000000000000000000..8c497641465f3e2c0a335541fc21fd7f7e2601f2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/NavigationType.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 { NavigationType } from './sdk/api/navigator' + +@Entry +@Component +struct Index { + build() { + Column() { + Navigator() { + Text('Replace') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Replace) + + Navigator() { + Text('Back') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Back) + + Navigator() { + Text('Push') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Push) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/NavigationType.ets.args.json b/ets2panda/linter/test/deprecatedapi/NavigationType.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/NavigationType.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/deprecatedapi/NavigationType.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/NavigationType.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..1ea98ff09667c16fe2672b12029f5dee1071d947 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/NavigationType.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": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 9, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 21, + "endLine": 45, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/NavigationType.ets.json b/ets2panda/linter/test/deprecatedapi/NavigationType.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/NavigationType.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/deprecatedapi/Push.ets b/ets2panda/linter/test/deprecatedapi/Push.ets new file mode 100755 index 0000000000000000000000000000000000000000..a357e4445ba5d249538943287e3f0469d8487de7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Push.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. + */ +import { NavigationType } from './sdk/api/navigator' + +@Entry +@Component +struct Index { + build() { + Column() { + Navigator() { + Text('Push') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Push) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Push.ets.args.json b/ets2panda/linter/test/deprecatedapi/Push.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Push.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/deprecatedapi/Push.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Push.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..6be00cdd5440b6a9045e172b2665a21ddb0cdfed --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Push.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": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 21, + "endLine": 31, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Push.ets.json b/ets2panda/linter/test/deprecatedapi/Push.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Push.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/deprecatedapi/Replace.ets b/ets2panda/linter/test/deprecatedapi/Replace.ets new file mode 100755 index 0000000000000000000000000000000000000000..c6ce7e7b51f477daabfe098c838ca3023c7c392b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Replace.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 { NavigationType } from './sdk/api/navigator' + +@Entry +@Component +struct Index { + build() { + Column() { + Navigator() { + Text('Replace') + .fontSize(20) + } + .target('pages/NewPage') + .type(NavigationType.Replace) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Replace.ets.args.json b/ets2panda/linter/test/deprecatedapi/Replace.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Replace.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/deprecatedapi/Replace.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/Replace.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..e80599387de9d58880840bb960e0e1556fe98aac --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Replace.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": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/Replace.ets.json b/ets2panda/linter/test/deprecatedapi/Replace.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/Replace.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/deprecatedapi/SM.ets b/ets2panda/linter/test/deprecatedapi/SM.ets new file mode 100755 index 0000000000000000000000000000000000000000..22de541ee10f5e8cba362bf35afc4716630c77f3 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SM.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 { SizeType } from './sdk/api/grid_container' + +@Entry +@Component +struct GridContainerExample { + @State sizeType: SizeType = SizeType.XS + + build() { + Column({ space: 5 }) { + Row() { + Button('SM').onClick(() => { this.sizeType = SizeType.SM }) + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/SM.ets.args.json b/ets2panda/linter/test/deprecatedapi/SM.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SM.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/deprecatedapi/SM.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/SM.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..646dee383ab3576f67433b45f8efef23db9a01f4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SM.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": 20, + "column": 31, + "endLine": 20, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 40, + "endLine": 20, + "endColumn": 42, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 54, + "endLine": 25, + "endColumn": 62, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 63, + "endLine": 25, + "endColumn": 65, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/SM.ets.json b/ets2panda/linter/test/deprecatedapi/SM.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SM.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/deprecatedapi/SetAndLink.ets b/ets2panda/linter/test/deprecatedapi/SetAndLink.ets new file mode 100755 index 0000000000000000000000000000000000000000..ebd4cd5e167d7897e9c515cf87f073f5cc9208b4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SetAndLink.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 { AppStorage } from './sdk/api/common_ts_ets_api'; + +AppStorage.setOrCreate('PropA', 47); +let link1: SubscribedAbstractProperty = AppStorage.SetAndLink('PropB', 49); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/SetAndLink.ets.args.json b/ets2panda/linter/test/deprecatedapi/SetAndLink.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SetAndLink.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/deprecatedapi/SetAndLink.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/SetAndLink.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..a7692ce6523c271aa69ebc6693c0226ff43b5349 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SetAndLink.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": 12, + "endLine": 18, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/SetAndLink.ets.json b/ets2panda/linter/test/deprecatedapi/SetAndLink.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/SetAndLink.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/deprecatedapi/UIContext.ets b/ets2panda/linter/test/deprecatedapi/UIContext.ets new file mode 100644 index 0000000000000000000000000000000000000000..66787ce456766cb84a27199d83383127d5e55846 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/UIContext.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. + */ + +import { promptAction } from '@kit.ArkUI'; + +try { + promptAction.showActionMenu({ //error + title: 'Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + }, + { + text: 'item2', + color: '#000000' + }, + ] + }, (err, data) => { + if (err) { + console.info('showActionMenu err: ' + err); + return; + } + console.info('showActionMenu success callback, click button: ' + data.index); + }) +} catch (error) { +}; \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/UIContext.ets.json b/ets2panda/linter/test/deprecatedapi/UIContext.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..f4da0d367fdfbd6f4e505b708458717c452dfaec --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/UIContext.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": 31, + "column": 7, + "endLine": 31, + "endColumn": 10, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 12, + "endLine": 31, + "endColumn": 16, + "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_decorator_and_interfaces_1.ets.args.json b/ets2panda/linter/test/deprecatedapi/UIContext.ets.json.args.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.args.json rename to ets2panda/linter/test/deprecatedapi/UIContext.ets.json.args.json diff --git a/ets2panda/linter/test/deprecatedapi/ability_component.ets b/ets2panda/linter/test/deprecatedapi/ability_component.ets new file mode 100755 index 0000000000000000000000000000000000000000..ecc3810d1d6bbc601cc76255b9bfce5e63c2e873 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ability_component.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. + */ + +@Entry +@Component +struct MyComponent { + + build() { + Column() { + AbilityComponent({ // error + want: { + bundleName: '', + abilityName: '' + }, + }) + .onConnect(() => { // error + console.log('AbilityComponent connect') + }) + .onDisconnect(() => { // error + console.log('AbilityComponent disconnect') + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ability_component.ets.args.json b/ets2panda/linter/test/deprecatedapi/ability_component.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ability_component.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/deprecatedapi/ability_component.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ability_component.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..977dd1e5910ac382c5f52afa86e5a96aeb1207ed --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ability_component.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": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AbilityComponent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ability_component.ets.json b/ets2panda/linter/test/deprecatedapi/ability_component.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ability_component.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/deprecatedapi/action_sheet.ets b/ets2panda/linter/test/deprecatedapi/action_sheet.ets new file mode 100644 index 0000000000000000000000000000000000000000..57437a6e3d5d6149576407570b1fa0a40490b1b2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/action_sheet.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. + */ + +import { ActionSheet } from './sdk/api/action_sheet' + +@Entry +@Component +struct ActionSheetExample { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Button('Click to Show ActionSheet') + .onClick(() => { + ActionSheet.show({ //error + title: 'ActionSheet title', + subtitle: 'ActionSheet subtitle', + message: 'message', + autoCancel: true, + confirm: { + defaultFocus: true, + value: 'Confirm button', + action: () => { + console.info('Get Alert Dialog handled'); + } + }, + cancel: () => { + console.info('actionSheet canceled'); + }, + onWillDismiss: (dismissDialogAction: DismissDialogAction) => { + console.info("reason=" + JSON.stringify(dismissDialogAction.reason)) + console.info("dialog onWillDismiss"); + if (dismissDialogAction.reason === DismissReason.PRESS_BACK) { + dismissDialogAction.dismiss(); + } + if (dismissDialogAction.reason === DismissReason.TOUCH_OUTSIDE) { + dismissDialogAction.dismiss(); + } + }, + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -10 }, + sheets: [ + { + title: 'apples', + action: () => { + console.info('apples'); + } + }, + { + title: 'bananas', + action: () => { + console.info('bananas'); + } + }, + { + title: 'pears', + action: () => { + console.info('pears'); + } + } + ] + }) + }) + }.width('100%') + .height('100%') + } +} \ 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/deprecatedapi/action_sheet.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.args.json rename to ets2panda/linter/test/deprecatedapi/action_sheet.ets.args.json diff --git a/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/action_sheet.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..be8eddb1ac5b03715219b01a3dd8d794dc0e43ae --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/action_sheet.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": 25, + "column": 23, + "endLine": 25, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"show\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 54, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 54, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 23, + "endLine": 22, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 37, + "endLine": 22, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 57, + "endLine": 22, + "endColumn": 66, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 91, + "endLine": 22, + "endColumn": 100, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 50, + "endLine": 40, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DismissDialogAction\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 50, + "endLine": 43, + "endColumn": 63, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DismissReason\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 50, + "endLine": 46, + "endColumn": 63, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DismissReason\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 24, + "endLine": 50, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DialogAlignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/action_sheet.ets.json b/ets2panda/linter/test/deprecatedapi/action_sheet.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/action_sheet.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/deprecatedapi/alert_dialog.ets b/ets2panda/linter/test/deprecatedapi/alert_dialog.ets new file mode 100644 index 0000000000000000000000000000000000000000..f6e0d243ff92f1138cb248463d47beacfa91bc32 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alert_dialog.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. + */ + +import { AlertDialog } from './sdk/api/alert_dialog' + +@Entry +@Component +struct AlertDialogExample { + build() { + Column({ space: 5 }) { + Button('AlertDialog Set Duration') + .onClick(() => { + AlertDialog.show( //error + { + title: 'AlertDialog 1', + message: 'Set Animation Duration open 3 second, close 100ms', + autoCancel: true, + alignment: DialogAlignment.Top, + offset: { dx: 0, dy: -20 }, + gridCount: 3, + transition: TransitionEffect.asymmetric(TransitionEffect.OPACITY + .animation({ duration: 3000, curve: Curve.Sharp }) + .combine(TransitionEffect.scale({ x: 1.5, y: 1.5 }).animation({ duration: 3000, curve: Curve.Sharp })), + TransitionEffect.OPACITY.animation({ duration: 100, curve: Curve.Smooth }) + .combine(TransitionEffect.scale({ x: 0.5, y: 0.5 }) + .animation({ duration: 100, curve: Curve.Smooth }))), + confirm: { + value: 'button', + action: () => { + console.info('Button-clicking callback'); + } + }, + cancel: () => { + console.info('Closed callbacks'); + } + } + ) + }) + .backgroundColor(0x317aff).height("88px") + }.width('100%').margin({ top: 5 }) + } +} \ 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/deprecatedapi/alert_dialog.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.args.json rename to ets2panda/linter/test/deprecatedapi/alert_dialog.ets.args.json diff --git a/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f2ee34f04565bd0ef3424458ddaf798c470a3eb2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alert_dialog.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": 25, + "column": 23, + "endLine": 25, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"show\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 26, + "endLine": 30, + "endColumn": 41, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DialogAlignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 27, + "endLine": 33, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 55, + "endLine": 33, + "endColumn": 71, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 53, + "endLine": 34, + "endColumn": 58, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 26, + "endLine": 35, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 104, + "endLine": 35, + "endColumn": 109, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 17, + "endLine": 36, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 76, + "endLine": 36, + "endColumn": 81, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 56, + "endLine": 38, + "endColumn": 61, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.json b/ets2panda/linter/test/deprecatedapi/alert_dialog.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alert_dialog.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/deprecatedapi/alphabet_indexer.ets b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets new file mode 100755 index 0000000000000000000000000000000000000000..7d19ba33f67fa6a36ebeebcdec5fd931d43e56ce --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 AlphabetIndexerSample { + private arrayA: string[] = ['安']; + private arrayB: string[] = ['卜', '白', '包', '毕', '丙']; + private arrayC: string[] = ['曹', '成', '陈', '催']; + private arrayL: string[] = ['刘', '李', '楼', '梁', '雷', '吕', '柳', '卢']; + private value: string[] = ['#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z']; + @State customBlurStyle: BlurStyle = BlurStyle.NONE; + + + build() { + Stack({ alignContent: Alignment.Start }) { + Row() { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.arrayA, (item: string) => { + ListItem() { + Text(item) + .width('80%') + .height('5%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + }, (item: string) => item) + + + ForEach(this.arrayB, (item: string) => { + ListItem() { + Text(item) + .width('80%') + .height('5%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + }, (item: string) => item) + + + ForEach(this.arrayC, (item: string) => { + ListItem() { + Text(item) + .width('80%') + .height('5%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + }, (item: string) => item) + + + ForEach(this.arrayL, (item: string) => { + ListItem() { + Text(item) + .width('80%') + .height('5%') + .fontSize(30) + .textAlign(TextAlign.Center) + } + }, (item: string) => item) + } + .width('30%') + .height('100%') + + + Column() { + Column() { + Text('切换模糊材质: ') + .fontSize(24) + .fontColor(0xcccccc) + .width('100%') + Button('COMPONENT_REGULAR') + .margin('5vp') + .width(200) + .onClick(() => { + this.customBlurStyle = BlurStyle.COMPONENT_REGULAR; + }) + Button('BACKGROUND_THIN') + .margin('5vp') + .width(200) + .onClick(() => { + this.customBlurStyle = BlurStyle.BACKGROUND_THIN; + }) + }.height('20%') + + + Column() { + AlphabetIndexer({ arrayValue: this.value, selected: 0 }) + .usingPopup(true) + .alignStyle(IndexerAlign.Left) + .popupItemBorderRadius(24) + .itemBorderRadius(14) + .popupBackgroundBlurStyle(this.customBlurStyle) + .popupTitleBackground(0xCCCCCC) + .onSelected((index: number) => { // error + console.info(this.value[index] + ' Selected!'); + }) + .onRequestPopupData((index: number) => { + if (this.value[index] == 'A') { + return this.arrayA; + } else if (this.value[index] == 'B') { + return this.arrayB; + } else if (this.value[index] == 'C') { + return this.arrayC; + } else if (this.value[index] == 'L') { + return this.arrayL; + } else { + return []; + } + }) + .onPopupSelect((index: number) => { + console.info('onPopupSelected:' + index); + }) + } + .height('80%') + } + .width('70%') + } + .width('100%') + .height('100%') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.args.json b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..d2e38450182b0b142ac12d0cf4d031db500ccc79 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.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": "" + } +} diff --git a/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..780289c0535a27bf4febfe903f81a1fdf3abe1c3 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.arkts2.json @@ -0,0 +1,428 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 111, + "column": 41, + "endLine": 111, + "endColumn": 46, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 32, + "endLine": 114, + "endColumn": 37, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 39, + "endLine": 116, + "endColumn": 44, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 39, + "endLine": 118, + "endColumn": 44, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 39, + "endLine": 120, + "endColumn": 44, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 26, + "endLine": 123, + "endColumn": 28, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 4, + "endLine": 27, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 27, + "endLine": 27, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BlurStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 39, + "endLine": 27, + "endColumn": 48, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BlurStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Stack\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 27, + "endLine": 31, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Alignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 9, + "endLine": 33, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 15, + "endLine": 36, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 28, + "endLine": 40, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 11, + "endLine": 45, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 13, + "endLine": 46, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 15, + "endLine": 47, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 28, + "endLine": 51, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 11, + "endLine": 56, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 13, + "endLine": 57, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 15, + "endLine": 58, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 28, + "endLine": 62, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 11, + "endLine": 67, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 13, + "endLine": 68, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 15, + "endLine": 69, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 9, + "endLine": 81, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 11, + "endLine": 82, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 13, + "endLine": 83, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 13, + "endLine": 87, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 40, + "endLine": 91, + "endColumn": 49, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BlurStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 13, + "endLine": 93, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 40, + "endLine": 97, + "endColumn": 49, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BlurStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 11, + "endLine": 102, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 13, + "endLine": 103, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AlphabetIndexer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 27, + "endLine": 105, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"IndexerAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.json b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/alphabet_indexer.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/deprecatedapi/animator.ets b/ets2panda/linter/test/deprecatedapi/animator.ets new file mode 100644 index 0000000000000000000000000000000000000000..8368d9d9b986ba7839752fd00e49dfecb30846be --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animator.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 { Animator as animator, AnimatorOptions } from './sdk/api/@ohos.animator'; + +let options: AnimatorOptions = { + duration: 1500, + easing: "friction", + delay: 0, + fill: "forwards", + direction: "normal", + iterations: 3, + begin: 200.0, + end: 400.0 +}; +animator.create(options); //error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/animator.ets.args.json b/ets2panda/linter/test/deprecatedapi/animator.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animator.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/deprecatedapi/animator.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/animator.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9cc4016ef79548fa28dc05a8907fa2ee20d6ab5b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animator.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": 28, + "column": 10, + "endLine": 28, + "endColumn": 16, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"create\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Animator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/animator.ets.json b/ets2panda/linter/test/deprecatedapi/animator.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animator.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/deprecatedapi/animatorResultOnrepeat_api.ets b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..1d8f620a9d0b0fe97a1d6ed4763cb98e634b3992 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.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. + */ +import Animator as animator, AnimatorResult from './sdk/api/@ohos.animator'; + +let AnimatorResult: AnimatorResult | undefined = animator.create(options) + +AnimatorResult.onrepeat = () => { //error + console.info("onrepeat callback") +} + +AnimatorResult.oncancel = () => { //error + console.info("oncancel callback") +} + +AnimatorResult.onfinish = () => { //error + console.info("onfinish callback") +} + +AnimatorResult.onframe = (value) => { //error + console.info("onframe callback") +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.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/deprecatedapi/animatorResultOnrepeat_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..438dabb8d35905e8f6d4fd111334d1f2eafdb706 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.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": 15, + "column": 1, + "endLine": 15, + "endColumn": 20, + "problem": "ImportAssignment", + "suggest": "", + "rule": "\"require\" and \"import\" assignment are not supported (arkts-no-require)", + "severity": "ERROR" + }, + { + "line": 15, + "column": 21, + "endLine": 15, + "endColumn": 45, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 27, + "endLine": 31, + "endColumn": 32, + "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/deprecatedapi/animatorResultOnrepeat_api.ets.json b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..438dabb8d35905e8f6d4fd111334d1f2eafdb706 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/animatorResultOnrepeat_api.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": 15, + "column": 1, + "endLine": 15, + "endColumn": 20, + "problem": "ImportAssignment", + "suggest": "", + "rule": "\"require\" and \"import\" assignment are not supported (arkts-no-require)", + "severity": "ERROR" + }, + { + "line": 15, + "column": 21, + "endLine": 15, + "endColumn": 45, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 27, + "endLine": 31, + "endColumn": 32, + "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/deprecatedapi/appStorageIsMutable_api.ets b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..2e73b25e23b8270c012594790da8814435209ae4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.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 { AppStorage } from './sdk/api/common_ts_ets_api'; + +AppStorage.SetOrCreate('PropA', 47); +let res: boolean = AppStorage.IsMutable('simpleProp'); //error + +let value: number = AppStorage.Get('PropA') as number; //error + +let res: boolean = AppStorage.Clear(); //error + +let value: boolean = AppStorage.Delete('PropA') as boolean; //error + +let value: number = AppStorage.Size(); //error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.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/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..cc96bf0126b11d0e3e2035e1ccb6d760760bdeaf --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.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": 31, + "endLine": 18, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IsMutable\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 44, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 32, + "endLine": 20, + "endColumn": 35, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Get\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 31, + "endLine": 22, + "endColumn": 36, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Clear\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 33, + "endLine": 24, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Delete\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 32, + "endLine": 26, + "endColumn": 36, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Size\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.json b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appStorageIsMutable_api.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/deprecatedapi/appscreenOnVisible_api.ets b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..7ed0caf1a2f6f232f435c3d378399b021f0bc117 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.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 App from './sdk/api/@system.app'; +import { GridContainerInterface } from './sdk/api/grid_container'; + +export default class Req { + requestFullWindow() { + App.screenOnVisible({ + }); + } +} + +GridContainerInterface.GridContainerAttribute \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.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/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..1c07495231aef8eb2c4571e13a740802c7474223 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.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": 9, + "endLine": 20, + "endColumn": 24, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"screenOnVisible\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 24, + "endLine": 25, + "endColumn": 46, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridContainerAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.json b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/appscreenOnVisible_api.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/deprecatedapi/backRouterOptionsUri_api.ets b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..0a37728e9f10164a45fd3a1f232fc03003351f47 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.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. + */ +import router from './sdk/api/@system.router'; + +class H{ + backToDetail() { + router.back({uri:'pages/detail/detail'}); + } +} +export default new H() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.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/deprecatedapi/backRouterOptionsUri_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.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/deprecatedapi/backRouterOptionsUri_api.ets.json b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/backRouterOptionsUri_api.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/deprecatedapi/buttons.ets b/ets2panda/linter/test/deprecatedapi/buttons.ets new file mode 100755 index 0000000000000000000000000000000000000000..80574cbd32e3aab0e1e00a93eb10f1fcfda551d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/buttons.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 prompt from './sdk/api/@ohos.prompt' + + +prompt.showDialog({ + title: 'showDialog Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + }, + { + text: 'button2', + color: '#000000' + } + ] +}, (err, data) => { + if (err) { + console.info('showDialog err: ' + err); + return; + } + console.info('showDialog success callback, click button: ' + data.index); +}); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/buttons.ets.args.json b/ets2panda/linter/test/deprecatedapi/buttons.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/buttons.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/deprecatedapi/buttons.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/buttons.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ffbd574589f2bc3c8827dab63e3233993effd021 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/buttons.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": 18, + "column": 8, + "endLine": 18, + "endColumn": 18, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 10, + "endLine": 31, + "endColumn": 14, + "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/deprecatedapi/buttons.ets.json b/ets2panda/linter/test/deprecatedapi/buttons.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f3ebadfbb714381766f4118f21e74e2c7d6b08f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/buttons.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": 31, + "column": 5, + "endLine": 31, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 10, + "endLine": 31, + "endColumn": 14, + "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/deprecatedapi/chip_group_api.ets b/ets2panda/linter/test/deprecatedapi/chip_group_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..ee4e8bf889eb1098e1b0f60174cb2bda7737f710 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/chip_group_api.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 {ChipGroupItemOptions} from './sdk/api/ChipGroup'; + +@Entry +struct Index { + build() { + Column() { + ChipGroup({ + items: [ + { + prefixIcon: { src: $r('app.media.icon') }, + label: { text: "操作块1" }, + .suffixIcon: { src: $r('sys.media.ohos_ic_public_cut') }, //error + allowClose: false + } + ] + }) + } + } +} +class Test implements ChipGroupItemOptions{ + suffixIcon?: IconOptions | undefined; + get(){ + return this.suffixIcon; + } + set(suffixIcon?: IconOptions | undefined){ + suffixIcon = { src: $r('sys.media.ohos_ic_public_cut') }; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/chip_group_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/chip_group_api.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/chip_group_api.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/deprecatedapi/chip_group_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/chip_group_api.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..57125855d0633cc9a2ff1e8248725d39c800f522 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/chip_group_api.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": 35, + "column": 3, + "endLine": 35, + "endColumn": 13, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 32, + "endLine": 24, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 33, + "endLine": 26, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 16, + "endLine": 35, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"IconOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 20, + "endLine": 39, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"IconOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 25, + "endLine": 40, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/chip_group_api.ets.json b/ets2panda/linter/test/deprecatedapi/chip_group_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..0c1bacf603e53b76a2d38202ed721c276cadb32b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/chip_group_api.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": 36, + "column": 3, + "endLine": 36, + "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/deprecatedapi/common.ets b/ets2panda/linter/test/deprecatedapi/common.ets new file mode 100644 index 0000000000000000000000000000000000000000..12386489df3d9b137e4a9ad5ec6fea637093ff0b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common.ets @@ -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. + */ + +@Entry +@Component +struct ClipExample { + build() { + Column({ space: 15 }) { + Row() { + Image($r('app.media.testImg')) + .clip(new Circle({})) //error + + Button() + .transition({ + type: TransitionType.Insert, //error + opacity: 0, //error + translate: {x: 1}, //error + scale: {x: 1}, //error + rotate: {angle: 1} //error + }) + .onClick(() => { + let context: Context = getContext(this); //error + console.info("CacheDir:" + context.cacheDir); + }) + + Button('Touch').height(40).width(100) + .onTouch((event?: TouchEvent) => { + if (event) { + event.touches[0].screenX; //error + event.touches[0].screenY; //error + } + }) + .onClick((event?: ClickEvent) => { + if (event) { + event.screenX; //error + event.screenY; //error + } + }) + .onMouse((event: MouseEvent):void => { + if (event) { + event.screenX; //error + event.screenY; //error + } + }) + } + .borderRadius(20) + } + .width('100%') + .margin({ top: 15 }) + } +} + + +px2lpx(200); //error +lpx2px(200); //error +px2fp(200); //error +fp2px(200); //error +px2vp(200); //error +vp2px(200); //error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common.ets.args.json b/ets2panda/linter/test/deprecatedapi/common.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common.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/deprecatedapi/common.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ad8333f4adcb6823bee92cf790f13cd3782eea0f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common.ets.arkts2.json @@ -0,0 +1,258 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 21, + "endLine": 23, + "endColumn": 27, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 13, + "endLine": 41, + "endColumn": 29, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 29, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Image\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Circle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TransitionType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 26, + "endLine": 34, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 36, + "endLine": 34, + "endColumn": 46, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"getContext\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 27, + "endLine": 39, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TouchEvent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 27, + "endLine": 45, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ClickEvent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 26, + "endLine": 51, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"MouseEvent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 1, + "endLine": 66, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"px2lpx\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"lpx2px\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"px2fp\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"fp2px\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"px2vp\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"vp2px\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common.ets.json b/ets2panda/linter/test/deprecatedapi/common.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..f24a1d0316bb093ee66951a8bdb172ca061aaa1c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common.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": 41, + "column": 13, + "endLine": 41, + "endColumn": 29, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 29, + "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/deprecatedapi/common_api.ets b/ets2panda/linter/test/deprecatedapi/common_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..142187d98c3c3307470165b08f711769c3d6b42a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_api.ets @@ -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 {DragEvent,CustomPopupOptions} from './sdk/api/common'; +import {LayoutInfo,LayoutChild,LayoutBorderInfo,TransitionOptions} from './sdk/api/common'; + +function get(aa:number){ + const globalEvent : DragEvent = {} + return globalEvent.getX();//error +} +function onMeasure(selfLayoutInfo: LayoutInfo, borderInfo: Array, children: Array){//error + selfLayoutInfo as LayoutInfo;//error + typeof (borderInfo[0] as LayoutBorderInfo);//error +} + +class Test implements LayoutChild{//error + set(child:LayoutChild){//error + return child as LayoutInfo;//error + } +} +class Test2 extends Test implements LayoutBorderInfo,TransitionOptions{ //error + private layoutInfo: LayoutInfo|undefined = undefined;//error + get(option:Map){//error + option.set('',{}); + } +} + +@Entry +@Component +struct Example { + @State uri: string = ""; + @State blockArr: string[] = []; + @State handlePopup: boolean = false; + @State customPopup: boolean = false; + udKey: string = ''; + globalEvent : DragEvent = {} + + @State handlePopup: boolean = false + private scroller: Scroller = new Scroller(); + + aboutToAppear(): void { + animateTo({ // error + duration: 2000, + curve: Curve.EaseOut, + iterations: 3, + playMode: PlayMode.Normal, + onFinish: () => { + console.info('play end'); + } + }, () => { + }); + } + + onLayout(children: LayoutChild[], constraint: ConstraintSizeOptions): void {// error *2 + let layoutChild: LayoutChild = children[0];// error + layoutChild.constraint; // error + layoutChild.position; // error + layoutChild.name; // error + layoutChild.id; // error + layoutChild.borderInfo.borderWidth; // error *2 + layoutChild.borderInfo.padding; // error *2 + layoutChild.borderInfo.margin; // error *2 + layoutChild.layout({ position: { x: 0, y: 0 }, constraint: constraint }); // error *3 + layoutChild.measure(constraint); // error + } + + onMeasure(children: LayoutChild[], constraint: ConstraintSizeOptions): void {// error *2 + } + + // Popup builder + @Builder popupBuilder() { + Row({ space: 2 }) { + }.width(100).height(50).padding(5) + } + build() { + Column() { + Text('Image drag and drop') + .fontSize('30dp') + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) { + Image($r('app.media.startIcon')) + .width(100) + .height(100) + .border({ width: 1 }) + .draggable(true) + .onDragStart((event:DragEvent) => { + typeof event.getX(); //error + (event as DragEvent).getY(); //error + console.log('',event.getY()); //error + }) + } + .margin({ bottom: this.globalEvent.getY() }) //error + Row() { + Column(){ + } + .border({width: 1}) + .height('90%') + .width('100%') + .onDrop((event?: DragEvent, extraParams?: string) => { + console.log("enter onDrop") + const x = event?.getX(); //error + const y = event?.getY(); //error + }, {disableDataPrefetch: true}) + } + .height("50%") + .width("90%") + .border({ width: 1 }) + + Button('PopupOptions') + .bindPopup(this.handlePopup, { + message: 'This is a popup with PopupOptions', + placementOnTop: true// error + }) + .useSizeType({}) // error + + List({ space: 10, scroller: this.scroller }) + .onScroll((xOffset: number, scrollState: ScrollState): void => { // error + }) + .width('100%') + .height(90) + .touchable(true)// error + .mask(new CircleAttribute()) // error + } + } + onLayout(children: Array//error + , constraint: ConstraintSizeOptions) { + children[0].borderInfo as LayoutBorderInfo;//error + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/common_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_api.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/deprecatedapi/common_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d74d9c0a2c9518d08b2163fc2b28a4c6a26fbc04 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_api.ets.arkts2.json @@ -0,0 +1,678 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 22, + "endLine": 20, + "endColumn": 26, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 36, + "endLine": 22, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 66, + "endLine": 22, + "endColumn": 82, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 101, + "endLine": 22, + "endColumn": 112, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 11, + "endLine": 24, + "endColumn": 24, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 28, + "endLine": 24, + "endColumn": 44, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 23, + "endLine": 27, + "endColumn": 34, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 13, + "endLine": 28, + "endColumn": 24, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 21, + "endLine": 29, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 38, + "endLine": 32, + "endColumn": 54, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 55, + "endLine": 32, + "endColumn": 72, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"TransitionOptions\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 23, + "endLine": 33, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 25, + "endLine": 34, + "endColumn": 42, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"TransitionOptions\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 36, + "endLine": 50, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 3, + "endLine": 76, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 3, + "endLine": 65, + "endColumn": 11, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"onLayout\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 22, + "endLine": 65, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 36, + "endLine": 66, + "endColumn": 47, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 17, + "endLine": 68, + "endColumn": 25, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 3, + "endLine": 78, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"onMeasure\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 23, + "endLine": 78, + "endColumn": 34, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 26, + "endLine": 97, + "endColumn": 30, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 38, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 34, + "endLine": 99, + "endColumn": 38, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 42, + "endLine": 102, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 28, + "endLine": 111, + "endColumn": 32, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getX\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 28, + "endLine": 112, + "endColumn": 32, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getY\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 17, + "endLine": 132, + "endColumn": 32, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 138, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 28, + "endLine": 135, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutChild\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 31, + "endLine": 137, + "endColumn": 47, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LayoutBorderInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 2, + "endLine": 39, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 2, + "endLine": 40, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 4, + "endLine": 42, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 4, + "endLine": 43, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 4, + "endLine": 44, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 29, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 36, + "endLine": 50, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"animateTo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 14, + "endLine": 55, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 17, + "endLine": 57, + "endColumn": 25, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"PlayMode\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 49, + "endLine": 65, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 50, + "endLine": 78, + "endColumn": 71, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 4, + "endLine": 82, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 7, + "endLine": 88, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 7, + "endLine": 90, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 25, + "endLine": 90, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 39, + "endLine": 90, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 56, + "endLine": 90, + "endColumn": 65, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 90, + "endLine": 90, + "endColumn": 99, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 9, + "endLine": 91, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Image\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 15, + "endLine": 91, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 9, + "endLine": 104, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 7, + "endLine": 119, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 7, + "endLine": 126, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 48, + "endLine": 127, + "endColumn": 59, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ScrollState\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 17, + "endLine": 132, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"CircleAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 19, + "endLine": 136, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_api.ets.json b/ets2panda/linter/test/deprecatedapi/common_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_api.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/deprecatedapi/common_ts_ets_api.ets b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a4c1c4ff4d4739c640830e81a8598fabc5a7799 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.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. + */ + +import { LocalStorage } from './sdk/api/common_ts_ets_api' + +@Entry +@Component +struct SharedLocalStorage { + localStorage = LocalStorage.getShared(); //error + + build() { + Row() { + Column() { + Button("Change Local Storage to 47") + .onClick(() => { + this.localStorage?.setOrCreate("propA", 47); + }) + Button("Get Local Storage") + .onClick(() => { + console.info(`localStorage: ${this.localStorage?.get("propA")}`); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.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/deprecatedapi/common_ts_ets_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..73c734b101ff3b97d044ac4ea32218757e67bd84 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.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": 21, + "column": 31, + "endLine": 21, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getShared\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api.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/deprecatedapi/common_ts_ets_api1.ets b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets new file mode 100755 index 0000000000000000000000000000000000000000..6ee8fd02c0f8587c74494aa39a3425d2a0d199f9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.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. + */ +AppStorage.Set("username", "John"); // error +console.log(AppStorage.get("username")); +let keys: IterableIterator = AppStorage.Keys(); // error +let simple = AppStorage.staticClear(); // error +AppStorage.setOrCreate('simpleProp', 121); +AppStorage.Has('simpleProp'); // error +AppStorage.setOrCreate('PropA', 47); +let prop: SubscribedAbstractProperty = AppStorage.SetAndProp('PropB', 49); // error +AppStorage.SetOrCreate('PropA', 47); // error +PersistentStorage.PersistProp('aProp', 47); // error +AppStorage.Prop("username"); // error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets.args.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.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/deprecatedapi/common_ts_ets_api1.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..354c71bb3a9c853b3f9a3f7af94a4d3e88ea4f37 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.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": 18, + "column": 5, + "endLine": 18, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 13, + "endLine": 16, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 38, + "endLine": 17, + "endColumn": 48, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 14, + "endLine": 18, + "endColumn": 24, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 48, + "endLine": 22, + "endColumn": 58, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"PersistentStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets.json b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..fd824bf65e41784d02f355f28af1be96f899cff6 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/common_ts_ets_api1.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": 5, + "endLine": 18, + "endColumn": 38, + "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/deprecatedapi/componentSnapshot.ets b/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets new file mode 100644 index 0000000000000000000000000000000000000000..f049f9273b5d0087410dfed77e2d334a8e6363c6 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/componentSnapshot.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 { componentSnapshot } from '@kit.ArkUI'; + +@Entry +@Component +struct SnapshotExample { + @Builder + RandomBuilder() { + Flex() { + Text('Test menu') + .fontSize(20) + .width(100) + .height(50) + .textAlign(TextAlign.Center) + } + .width(100) + } + + build() { + Column() { + Button("click to generate UI snapshot") + .onClick(() => { + componentSnapshot.get("root", () => {}); //error + componentSnapshot.get("root"); //error + componentSnapshot.createFromBuilder(() => { this.RandomBuilder()}, () => {}); //error + componentSnapshot.createFromBuilder(() => { this.RandomBuilder()}); //error + }).margin(10) + } + .width('100%') + .height('100%') + .alignItems(HorizontalAlign.Center) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets.args.json b/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/componentSnapshot.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/deprecatedapi/componentSnapshot.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0a2ee2b048b71d39da22c3df82c882d116eca646 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/componentSnapshot.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": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 29, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 7, + "endLine": 35, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 17, + "endLine": 45, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HorizontalAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets.json b/ets2panda/linter/test/deprecatedapi/componentSnapshot.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/componentSnapshot.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/deprecatedapi/curves.ets b/ets2panda/linter/test/deprecatedapi/curves.ets new file mode 100644 index 0000000000000000000000000000000000000000..c13a0cfce6ce35e2f8432a6072c35b669ee7a339 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curves.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 { curves } from '@kit.ArkUI'; +curves.cubicBezier(0.1, 0.0, 0.1, 1.0);//error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/curves.ets.args.json b/ets2panda/linter/test/deprecatedapi/curves.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curves.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/deprecatedapi/curves.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/curves.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curves.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/deprecatedapi/curves.ets.json b/ets2panda/linter/test/deprecatedapi/curves.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curves.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/deprecatedapi/curvesInit_api.ets b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..db08bd6b30d3280d2403d9130ccee0b113294424 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curvesInit_api.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 { curves } from './sdk/api/@ohos.curves'; + +curves.init() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curvesInit_api.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/deprecatedapi/curvesInit_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7adf5115af630830722e70fef7249a45633787b4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curvesInit_api.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": 8, + "endLine": 17, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"init\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.json b/ets2panda/linter/test/deprecatedapi/curvesInit_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/curvesInit_api.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/deprecatedapi/custom_api.ets b/ets2panda/linter/test/deprecatedapi/custom_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..a809862de1c8de194898de44a4cdb19bdf2ee43b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/custom_api.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 {PanelType} from './sdk/api/panel' + +@@Entry +@Component +struct WrapContentPanelExample { + @State isVisible: boolean = true + build() { + Column() { + Panel(this.isVisible) + .type(PanelType.CUSTOM) // error + } + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/custom_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/custom_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/custom_api.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/deprecatedapi/custom_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/custom_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..57081a47c2217e4f25a90699423436d4601ad758 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/custom_api.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": 17, + "endColumn": 2, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 23, + "endLine": 24, + "endColumn": 29, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"CUSTOM\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/custom_api.ets.json b/ets2panda/linter/test/deprecatedapi/custom_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/custom_api.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/deprecatedapi/date_picker.ets b/ets2panda/linter/test/deprecatedapi/date_picker.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5937657163f4357e9fde0b64e18341613a4df22 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/date_picker.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. + */ + +@Entry +@Component +struct DatePickerExample { + private selectedDate: Date = new Date('2021-08-08'); + + build() { + Column() { + Button("DatePickerDialog") + .margin(20) + .onClick(() => { + DatePickerDialog.show({ //error + onAccept: () => {}, //error + onChange: () => {} //error + }) //error + }) + + DatePicker({ + start: new Date('1970-1-1'), + end: new Date('2100-1-1'), + selected: this.selectedDate + }).onChange(() => {}) //error + + }.width('100%').height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/date_picker.ets.args.json b/ets2panda/linter/test/deprecatedapi/date_picker.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/date_picker.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/deprecatedapi/date_picker.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/date_picker.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e542ed7533e578b5c263bc9aa98187b4a39a5067 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/date_picker.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": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 11, + "endLine": 26, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DatePickerDialog\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DatePicker\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/date_picker.ets.json b/ets2panda/linter/test/deprecatedapi/date_picker.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/date_picker.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/deprecatedapi/deprecated_api_common_utils.ets b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets new file mode 100644 index 0000000000000000000000000000000000000000..700f35d0a8ebde2205298181290849e340c266e0 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.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. + */ + +import { componentUtils } from '@kit.ArkUI'; + +@Entry +@Component +struct CommonUtilsExample { + + aboutToAppear(): void { + let modePosition:componentUtils.ComponentInfo = componentUtils.getRectangleById("onClick"); // error + } + + build() { + Column() { + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets.args.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.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/deprecatedapi/deprecated_api_common_utils.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ce2955ca55158612f1e3169e24143b3a5dbe5d9f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.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": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_common_utils.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/deprecatedapi/deprecated_api_font.ets b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets new file mode 100755 index 0000000000000000000000000000000000000000..032b04c32363fe08f8df02c4705fd799bf1bae5c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.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 {font} from './sdk/api/@ohos.font'; + +@Entry +@Component +struct FontExample { + fontInfo2: font.FontInfo = font.getFontByName(''); // error + fontList: Array = new Array(); + + aboutToAppear(): void { + font.registerFont({ // error + familyName: 'mediumRawFile', + familySrc: $rawfile('font/medium.ttf') + }) + } + + build() { + Column() { + Button("getFontByName") + .onClick(() => { + this.fontInfo2 = font.getFontByName(''); // error + }) + Button("getSystemFontList") + .onClick(() => { + this.fontList = font.getSystemFontList(); // error + }) + Button("registerFont") + .onClick(() => { + font.registerFont({familyName: 'mediumRawFile', familySrc: $rawfile('font/medium.ttf')}); // error + }) + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.args.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.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/deprecatedapi/deprecated_api_font.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6b41b86aa510caf626c626da085527ef05ff78a9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.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": 20, + "column": 35, + "endLine": 20, + "endColumn": 48, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getFontByName\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 33, + "endLine": 21, + "endColumn": 38, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"registerFont\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 33, + "endLine": 34, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getFontByName\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 32, + "endLine": 38, + "endColumn": 49, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getSystemFontList\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 16, + "endLine": 42, + "endColumn": 28, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"registerFont\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$rawfile\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 70, + "endLine": 42, + "endColumn": 78, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$rawfile\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_font.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/deprecatedapi/deprecated_api_prompt_action.ets b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets new file mode 100644 index 0000000000000000000000000000000000000000..c17f35ce66bb70e7ba37b08cea768898ed7c2c60 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.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. + */ + +import { promptAction } from '@kit.ArkUI'; + +@Entry +@Component +struct PromptActionExample { + + aboutToAppear(): void { + promptAction.showToast({ // error + message: 'Hello World', + duration: 2000 + }); + + promptAction.showDialog({ // error + title: 'Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + } + ], + }); + + promptAction.showDialog({ // error + title: 'showDialog Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + } + ] + }, (err, data) => { + }); + + promptAction.showActionMenu({ // error + title: 'showActionMenu Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + } + ] + }); + + promptAction.showActionMenu({ // error + title: 'Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + } + ] + }, (err, data) => { + }) + + promptAction.closeCustomDialog(1); // error + promptAction.openCustomDialog({ // error + builder: () => { + }, + onWillDismiss: (dismissDialogAction: DismissDialogAction) => { + } + }); + } + + build() { + Column() { + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets.args.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.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/deprecatedapi/deprecated_api_prompt_action.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ce6f451ff3a80389d8e2ce6b288c31273194d768 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.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": 48, + "column": 9, + "endLine": 48, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 9, + "endLine": 69, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 14, + "endLine": 69, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 44, + "endLine": 76, + "endColumn": 63, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DismissDialogAction\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..2a8b234e1c72a6ed4e9026a89bb9cff0395f7b29 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_prompt_action.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": 48, + "column": 9, + "endLine": 48, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 9, + "endLine": 69, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 14, + "endLine": 69, + "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/deprecatedapi/deprecated_api_router.ets b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets new file mode 100755 index 0000000000000000000000000000000000000000..a5ca89df3c1e3abe7068bdc00a3b5b4857045b7a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets @@ -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 router from './sdk/api/@system.router'; + +class L{ + enableAlertBeforeBackPage() { + router.enableAlertBeforeBackPage({ //error + message: 'Message Info', + success: ()=> { + console.log('success'); + }, + cancel: ()=> { + console.log('cancel'); + } + }); + } +} + +class RouterParams { + data1: string; + + constructor(str: string) { + this.data1 = str; + } +} + +@Entry +@Component +struct RouterExample { + + aboutToAppear(): void { + router.replaceNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }); + + router.replaceNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, (err) => { + }); + + router.replaceNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, router.RouterMode.Standard); + + router.replaceNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, router.RouterMode.Standard, (err) => { + }); + + router.pushNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }); + + router.pushNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, (err) => { + }) + + router.pushNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, router.RouterMode.Standard); + + router.pushNamedRoute({ // error + name: 'myPage', + params: new RouterParams('message') + }, router.RouterMode.Standard, (err) => { + }) + + let obj = router.getParams(); // error + router.hideAlertBeforeBackPage(); // error + router.showAlertBeforeBackPage({ // error + message: 'Message Info' + }); + let options: Array = router.getStateByUrl('pages/index'); // error + let options1: router.RouterState | undefined = router.getStateByIndex(1); // error + let page = router.getState(); // error + let length = router.getLength(); // error + router.clear(); // error + router.back({ url: 'pages/detail' }); // error + router.back(1); // error + router.back(1, { info: 'From Home' }); // error + router.replaceUrl({ // error + url: 'pages/detail', + params: new RouterParams('message') + }); + router.replaceUrl({ // error + url: 'pages/detail', + params: new RouterParams('message') + }, (err) => { + }); + router.replaceUrl({ // error + url: 'pages/detail', + params: new RouterParams('message') + }, router.RouterMode.Standard); + router.replaceUrl({ // error + url: 'pages/detail', + params: new RouterParams('message') + }, router.RouterMode.Standard, (err) => { + }); + + router.pushUrl({ // error + url: 'pages/routerpage2', + params: {name: 'message', age: 1} + }); + + router.pushUrl({ // error + url: 'pages/routerpage2', + params: new RouterParams('message') + }, (err) => { + }); + + router.pushUrl({ // error + url: 'pages/routerpage2', + params: new RouterParams('message') + }, router.RouterMode.Standard); + + router.pushUrl({ // error + url: 'pages/routerpage2', + params: new RouterParams('message') + }, router.RouterMode.Standard, (err) => { + }) + } + + build() { + Column() { + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.args.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.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/deprecatedapi/deprecated_api_router.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..3ed0edea9e804fc1d347a454938e3db7e1922898 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.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": 19, + "column": 12, + "endLine": 19, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"enableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 37, + "endLine": 63, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 9, + "endLine": 74, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 37, + "endLine": 85, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 9, + "endLine": 88, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 9, + "endLine": 95, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 9, + "endLine": 96, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 12, + "endLine": 97, + "endColumn": 17, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"clear\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 9, + "endLine": 108, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 37, + "endLine": 117, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 9, + "endLine": 128, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 37, + "endLine": 139, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 2, + "endLine": 39, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 2, + "endLine": 40, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 5, + "endLine": 144, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..405836ab2912121892e0fb2a3e8d3c6c3a5cc33a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_router.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": 52, + "column": 9, + "endLine": 52, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 37, + "endLine": 63, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 9, + "endLine": 74, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 37, + "endLine": 85, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 9, + "endLine": 88, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 9, + "endLine": 95, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 9, + "endLine": 96, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 9, + "endLine": 108, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 37, + "endLine": 117, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 9, + "endLine": 128, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 37, + "endLine": 139, + "endColumn": 40, + "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/deprecatedapi/deprecated_api_time_picker.ets b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1b1f0869618702f12dedc302fc2521d6b64bfba --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.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. + */ + +@Entry +@Component +struct TimePickerDialogExample { + + aboutToAppear(): void { + TimePickerDialog.show(); + TimePickerDialog.show({useMilitaryTime: true}); + } + + build() { + Column() { + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets.args.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.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/deprecatedapi/deprecated_api_time_picker.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1af038e5b70c2a49a22760284383fc43921a23fa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.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": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TimePickerDialog\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TimePickerDialog\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets.json b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/deprecated_api_time_picker.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/deprecatedapi/dragController.ets b/ets2panda/linter/test/deprecatedapi/dragController.ets new file mode 100644 index 0000000000000000000000000000000000000000..1fc9a633b8f5fa605d424013d8d018e370a35257 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/dragController.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. + */ + +import { dragController } from "@kit.ArkUI"; +import { image } from '@kit.ImageKit'; + +@Entry +@Component +struct DragControllerPage { + @State pixmap: image.PixelMap | null = null + + @Builder + DraggingBuilder() { + Column() { + Text("DraggingBuilder") + .fontColor(Color.White) + .fontSize(12) + } + .width(100) + .height(100) + .backgroundColor(Color.Blue) + } + + @Builder + CustomDragView() { + Column() { + Text('Drag Me') + .fontSize(18) + .fontColor(Color.Black) + } + .width(100) + .height(50) + .backgroundColor(Color.White) + } + + private customBuilders: Array = [this.CustomDragView]; + + build() { + Column() { + Button('drag') + .margin(10) + .onDragEnter(() => { + dragController.getDragPreview(); //error + }) + .onTouch((event?: TouchEvent) => { + if (event) { + let dragInfo: dragController.DragInfo = { + pointerId: 0, + extraParams: '' + } + dragController.createDragAction(this.customBuilders, dragInfo); //error + + dragController.executeDrag(() => { //error + this.DraggingBuilder() + }, dragInfo, (err, eve) => { + }); + + dragController.executeDrag(() => { //error + this.DraggingBuilder() + }, dragInfo); + } + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/dragController.ets.args.json b/ets2panda/linter/test/deprecatedapi/dragController.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/dragController.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/deprecatedapi/dragController.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/dragController.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f6115f9b1400c878506799ce8a1f3c4a40d6b30d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/dragController.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": 67, + "column": 27, + "endLine": 67, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 32, + "endLine": 67, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 25, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 22, + "endLine": 33, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 4, + "endLine": 36, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 20, + "endLine": 41, + "endColumn": 25, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 22, + "endLine": 45, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 33, + "endLine": 48, + "endColumn": 46, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"CustomBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 49, + "endLine": 48, + "endColumn": 61, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DragItemInfo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 27, + "endLine": 57, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TouchEvent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/dragController.ets.json b/ets2panda/linter/test/deprecatedapi/dragController.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..fcedf465955a961dd6523968783383316d82dc8d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/dragController.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": 67, + "column": 27, + "endLine": 67, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 32, + "endLine": 67, + "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/deprecatedapi/enums.ets b/ets2panda/linter/test/deprecatedapi/enums.ets new file mode 100644 index 0000000000000000000000000000000000000000..5135fbb18e7bfe30d4ae3a8ea9e5073841ceea14 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/enums.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. + */ + +@Entry +@Component +struct ScrollExample { + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + build() { + Stack({ alignContent: Alignment.TopStart }) { + Scroll(this.scroller) { + Column() { + ForEach(this.arr, (item: number) => { + Text(item.toString()) + }, (item: string) => item) + }.width('100%') + } + + Button('back Center') + .height('5%') + .onClick(() => { + this.scroller.scrollEdge(Edge.Center); //error + }) + .margin({ top: 160, left: 20 }) + Button('back Middle') + .height('5%') + .onClick(() => { + this.scroller.scrollEdge(Edge.Middle); //error + }) + .margin({ top: 210, left: 20 }) + }.width('100%').height('100%').backgroundColor(0xDCDCDC) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/enums.ets.args.json b/ets2panda/linter/test/deprecatedapi/enums.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/enums.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/deprecatedapi/enums.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/enums.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..c4e4d2b7bc3fc9da7b0eb9c02dbc3a7b797c1edc --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/enums.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": 19, + "column": 28, + "endLine": 19, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 28, + "endLine": 19, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Stack\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Alignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroll\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 11, + "endLine": 26, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 36, + "endLine": 35, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Edge\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 36, + "endLine": 41, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Edge\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/enums.ets.json b/ets2panda/linter/test/deprecatedapi/enums.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/enums.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/deprecatedapi/environmentEnvProp_api.ets b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..ee528bd4ad87e66b108e3c889aebbfdf68f15e6b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.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 { Environment } from './sdk/api/common_ts_ets_api'; + +Environment.EnvProp('accessibilityEnabled', 'default'); //error + +let keys: Array = Environment.Keys(); //error + +Environment.EnvProps([{ key: 'accessibilityEnabled', defaultValue: 'default' }, { //error + key: 'languageCode', + defaultValue: 'en' +}, { key: 'prop', defaultValue: 'hhhh' }]); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.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/deprecatedapi/environmentEnvProp_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..e7d32ce03d923653ccef1f66aa18b722903d6c7d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.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": 13, + "endLine": 17, + "endColumn": 20, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"EnvProp\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 39, + "endLine": 19, + "endColumn": 43, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Keys\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 13, + "endLine": 21, + "endColumn": 21, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"EnvProps\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.json b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/environmentEnvProp_api.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/deprecatedapi/foldable_api.ets b/ets2panda/linter/test/deprecatedapi/foldable_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..de997623bfe14662921cfc3b36af43970da77aa0 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/foldable_api.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 {PanelType} from './sdk/api/panel' + +@@Entry +@Component +struct WrapContentPanelExample { + @State isVisible: boolean = true + build() { + Column() { + Panel(this.isVisible) + .type(PanelType.Foldable) // error + } + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/foldable_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/foldable_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/foldable_api.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/deprecatedapi/foldable_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/foldable_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..272fe50def471bbabb32a1bf52a4a284ea93ea1b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/foldable_api.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": 17, + "endColumn": 2, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 23, + "endLine": 24, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Foldable\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/foldable_api.ets.json b/ets2panda/linter/test/deprecatedapi/foldable_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/foldable_api.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/deprecatedapi/getLength.ets b/ets2panda/linter/test/deprecatedapi/getLength.ets new file mode 100755 index 0000000000000000000000000000000000000000..897957626a7ff0726cf67c071a5af131c6252b9a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getLength.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. + */ +import router from './sdk/api/@system.router'; +class J{ + getLength() { + let size = router.getLength(); + console.log('pages stack size = ' + size); + } +} +export default new J() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/getLength.ets.args.json b/ets2panda/linter/test/deprecatedapi/getLength.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getLength.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/deprecatedapi/getLength.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/getLength.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7c08a340f938a9098f617645e5ea936ae70eee66 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getLength.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": 9, + "endLine": 18, + "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/deprecatedapi/getLength.ets.json b/ets2panda/linter/test/deprecatedapi/getLength.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7c08a340f938a9098f617645e5ea936ae70eee66 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getLength.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": 9, + "endLine": 18, + "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/deprecatedapi/getParams.ets b/ets2panda/linter/test/deprecatedapi/getParams.ets new file mode 100755 index 0000000000000000000000000000000000000000..69c220cec56f9833f9311cd2ab6e0a2070edb83c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getParams.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 router from './sdk/api/@system.router'; + +let params: Object = router.getParams(); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/getParams.ets.args.json b/ets2panda/linter/test/deprecatedapi/getParams.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getParams.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/deprecatedapi/getParams.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/getParams.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getParams.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/deprecatedapi/getParams.ets.json b/ets2panda/linter/test/deprecatedapi/getParams.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/getParams.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/deprecatedapi/gridAttributeonScroll_api.ets b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..30d8bc150c9293466f938406ac7fb7fa9d9445cc --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.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 { GridAttribute } from './sdk/api/grid'; + +@Entry +@Component +struct GridExample { + @State scrollPos: number = 0; + @State scrollStatus: string = 'IDLE'; + + build() { + Grid() { + ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], () => { + }) + } + .columnsTemplate('1fr 1fr 1fr') + .onScroll((offset, state) => { + this.scrollPos = offset; + this.scrollStatus = ScrollState[state]; + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.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/deprecatedapi/gridAttributeonScroll_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..1bdf00e261b2576b4874d078fd102ef38e93ba51 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.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": 29, + "column": 16, + "endLine": 29, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 24, + "endLine": 29, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Grid\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 27, + "endLine": 31, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ScrollState\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets.json b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..847ccb380cc335698340e7cbb59584979693d731 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridAttributeonScroll_api.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": 29, + "column": 16, + "endLine": 29, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 24, + "endLine": 29, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..57cca2901b5103e23c4bfa5329be23599edc1a41 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.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 {GridContainerOptions} from './sdk/api/grid_container'; + +@Entry +@Component +struct GridContainerExample { + @State sizeType: SizeType = SizeType.XS + + build() { + Column({ space: 5 }) { + GridContainer({ columns: 12, sizeType: this.sizeType, gutter: 10, margin: 20 }) { + }.width('90%') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.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/deprecatedapi/gridContainerOptionsMargin_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..5037aad4243dcaea9473aac65895def4b7056d8d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.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": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 31, + "endLine": 20, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets.json b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridContainerOptionsMargin_api.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/deprecatedapi/gridItem.ets b/ets2panda/linter/test/deprecatedapi/gridItem.ets new file mode 100755 index 0000000000000000000000000000000000000000..d99fe0cef1170522a0a0c0a91f64e9a5d1328900 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridItem.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. + */ +@Entry +@Component +struct GridItemExample { + build() { + Column() { + Grid() { + GridItem() + .width('100%') + .height('100%') + .forceRebuild(false); // error + } + .columnsTemplate('1fr 1fr 1fr 1fr 1fr') + .rowsTemplate('1fr 1fr 1fr 1fr 1fr') + .width('90%').height(300) + }.width('100%').margin({ top: 5 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridItem.ets.args.json b/ets2panda/linter/test/deprecatedapi/gridItem.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..aa0b62d6c8953d91487fe6b2039ac56853c4c1a1 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridItem.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/deprecatedapi/gridItem.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/gridItem.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..91e1aefaaa241e96cebda3c31e2e238d2b4e35ce --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridItem.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": 15, + "column": 2, + "endLine": 15, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Grid\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/gridItem.ets.json b/ets2panda/linter/test/deprecatedapi/gridItem.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/gridItem.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/deprecatedapi/grid_container.ets b/ets2panda/linter/test/deprecatedapi/grid_container.ets new file mode 100755 index 0000000000000000000000000000000000000000..c8d95d26ecd8ccffa7096c5ab7aee865a0767ce5 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/grid_container.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. + */ + +@Entry +@Component +struct GridContainerExample { + @State sizeType: SizeType = SizeType.MD // error + private options: GridContainerOptions = { + columns: 12, // error + sizeType: this.sizeType, // error + gutter: 10, // error + margin: 20 // error + } + + build() { + Column({ space: 5 }) { + GridContainer({ + columns: 12, + sizeType: this.sizeType, + gutter: 10, + margin: 20 + }) { + Row() { + Text('1') + .height(50).backgroundColor(0x4682B4).textAlign(TextAlign.Center) + } + }.width('90%') + + GridContainer(this.options) { + Row() { + Text('1') + .useSizeType({ + xs: { span: 6, offset: 0 }, + sm: { span: 2, offset: 0 }, + md: { span: 2, offset: 0 }, + lg: { span: 2, offset: 0 } + }) + .height(50).backgroundColor(0x4682B4).textAlign(TextAlign.Center) + } + }.width('90%') + + Text('Click Simulate to change the device width').fontSize(9).width('90%').fontColor(0xCCCCCC) + Row() { + Button('LG') + .onClick(() => { + this.sizeType = SizeType.LG // error + }).backgroundColor(0x317aff) + Button('Auto') + .onClick(() => { + this.sizeType = SizeType.Auto // error + }).backgroundColor(0x317aff) + } + }.width('100%').margin({ top: 5 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/grid_container.ets.args.json b/ets2panda/linter/test/deprecatedapi/grid_container.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/grid_container.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/deprecatedapi/grid_container.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/grid_container.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..a3163ebbecfa04ced4f4c265470ceb5d8750ebee --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/grid_container.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": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 31, + "endLine": 19, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridContainerOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 9, + "endLine": 35, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 61, + "endLine": 37, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 7, + "endLine": 41, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GridContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 9, + "endLine": 42, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 61, + "endLine": 50, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 7, + "endLine": 55, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 9, + "endLine": 56, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 29, + "endLine": 58, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 9, + "endLine": 60, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 29, + "endLine": 62, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/grid_container.ets.json b/ets2panda/linter/test/deprecatedapi/grid_container.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/grid_container.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/deprecatedapi/image_animator.ets b/ets2panda/linter/test/deprecatedapi/image_animator.ets new file mode 100644 index 0000000000000000000000000000000000000000..91114d198fdc7292bc40661bd436d38dc289dcec --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/image_animator.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. + */ + +@Entry +@Component +struct ImageAnimatorExample { + + build() { + Column({ space: 10 }) { + ImageAnimator() + .preDecode(0) //error + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/image_animator.ets.args.json b/ets2panda/linter/test/deprecatedapi/image_animator.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/image_animator.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/deprecatedapi/image_animator.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/image_animator.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d20426041e9ec9729a72b960f99b8b60b8a03188 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/image_animator.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": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ImageAnimator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/image_animator.ets.json b/ets2panda/linter/test/deprecatedapi/image_animator.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/image_animator.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/deprecatedapi/inspector.ets b/ets2panda/linter/test/deprecatedapi/inspector.ets new file mode 100644 index 0000000000000000000000000000000000000000..d041d776c5bda0f085360fae3310bf56223a3791 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/inspector.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 inspector from '@ohos.arkui.inspector' + +@Entry +@Component +struct ImageExample { + build() { + Column() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) { + Row({ space: 5 }) { + Image($r('app.media.app_icon')) + .width(110) + .height(110) + .border({ width: 1 }) + .id('IMAGE_ID') + } + } + }.height(320).width(360).padding({ right: 10, top: 10 }) + } + + listener:inspector.ComponentObserver = inspector.createComponentObserver('IMAGE_ID') //error + + aboutToAppear() { + let onLayoutComplete:()=>void=():void=>{} + let onDrawComplete:()=>void=():void=>{} + let FuncLayout = onLayoutComplete // bind current js instance + let FuncDraw = onDrawComplete // bind current js instance + + this.listener.on('layout', FuncLayout) + this.listener.on('draw', FuncDraw) + } +} diff --git a/ets2panda/linter/test/deprecatedapi/inspector.ets.args.json b/ets2panda/linter/test/deprecatedapi/inspector.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/inspector.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/deprecatedapi/inspector.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/inspector.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9ba207e17625c99785d18cf0a7a9a1c76600a9da --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/inspector.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": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 25, + "endLine": 23, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 39, + "endLine": 23, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 59, + "endLine": 23, + "endColumn": 68, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 11, + "endLine": 25, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Image\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/inspector.ets.json b/ets2panda/linter/test/deprecatedapi/inspector.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/inspector.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/deprecatedapi/lazy_for_each.ets b/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets new file mode 100644 index 0000000000000000000000000000000000000000..fbc16f834896d3f31bfaf1f5acb400c6ce15f134 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): string { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdded(index); //error + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChanged(index); //error + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDeleted(index); //error + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMoved(from, to); //error + }) + } +} + +class MyDataSource extends BasicDataSource { + private dataArray: string[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): string { + return this.dataArray[index]; + } + + public addData(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: string): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + +@Entry +@Component +struct MyComponent { + private data: MyDataSource = new MyDataSource(); + + aboutToAppear() { + for (let i = 0; i <= 20; i++) { + this.data.pushData(`Hello ${i}`); + } + } + + build() { + List({ space: 3 }) { + LazyForEach(this.data, (item: string) => { + ListItem() { + Row() { + Text(item).fontSize(50) + .onAppear(() => { + console.info(`appear: ${item}`); + }) + }.margin({ left: 10, right: 10 }) + } + }, (item: string) => item) + }.cachedCount(5) + } +} diff --git a/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets.args.json b/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/lazy_for_each.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/deprecatedapi/lazy_for_each.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7d0cfc0cb7f92a89dbfdf0bac3dacc16ff298865 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/lazy_for_each.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": 25, + "column": 33, + "endLine": 25, + "endColumn": 38, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 27, + "endLine": 82, + "endColumn": 32, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 34, + "endLine": 16, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"IDataSource\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 22, + "endLine": 17, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DataChangeListener\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 40, + "endLine": 28, + "endColumn": 58, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DataChangeListener\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 42, + "endLine": 35, + "endColumn": 60, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"DataChangeListener\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 2, + "endLine": 96, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 2, + "endLine": 97, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 5, + "endLine": 108, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"LazyForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 9, + "endLine": 110, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 11, + "endLine": 111, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 13, + "endLine": 112, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets.json b/ets2panda/linter/test/deprecatedapi/lazy_for_each.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/lazy_for_each.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/deprecatedapi/list.ets b/ets2panda/linter/test/deprecatedapi/list.ets new file mode 100755 index 0000000000000000000000000000000000000000..914b230b1038672dd3b919a7297d3c2e4bc91e23 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/list.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. + */ +@Entry +@Component +struct ListExample { + build() { + Column() { + List({ space: 20, initialIndex: 0 }) + .listDirection(Axis.Vertical) + .scrollBar(BarState.Off) + .friction(0.6) + .divider({ + strokeWidth: 2, + color: 0xFFFFFF, + startMargin: 20, + endMargin: 20 + }) + .edgeEffect(EdgeEffect.Spring) + .editMode(false)// error + .width('90%') + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + .padding({ top: 5 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/list.ets.args.json b/ets2panda/linter/test/deprecatedapi/list.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/list.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/deprecatedapi/list.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/list.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..75b354f00d3696a600225a53ac5a92a7f8259dbb --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/list.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": 15, + "column": 2, + "endLine": 15, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 24, + "endLine": 21, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Axis\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BarState\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 21, + "endLine": 30, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"EdgeEffect\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/list.ets.json b/ets2panda/linter/test/deprecatedapi/list.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/list.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/deprecatedapi/listitem_api.ets b/ets2panda/linter/test/deprecatedapi/listitem_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..1972648696c11df05dd8656018ac78a130f90425 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/listitem_api.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. + */ +import {ListItemAttribute,Sticky,EditMode} from './sdk/api/list_item'; + +@Entry +@Component +struct ListItemExample { + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + + build() { + Column() { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.arr, (item: number) => { + ListItem() + .sticky(Sticky.Normal) //error + .editable(true) //error + .editable(EditMode.Deletable); //error + }, (item: string) => item) + }.width('90%') + .scrollBar(BarState.Off) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/listitem_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/listitem_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/listitem_api.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/deprecatedapi/listitem_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/listitem_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..bc005af887f5478332049bcd25dfcb26498f07ef --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/listitem_api.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": 27, + "column": 21, + "endLine": 27, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Sticky\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"EditMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 11, + "endLine": 26, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 18, + "endLine": 32, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BarState\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/listitem_api.ets.json b/ets2panda/linter/test/deprecatedapi/listitem_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/listitem_api.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/deprecatedapi/matrix4Rotate_api.ets b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..28fe3c5414db15869bc5519c5280b4b52e994c83 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.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 { matrix4 } from './sdk/api/@ohos.matrix4'; + +@Entry +@Component +struct Test { + private matrix1 = matrix4.rotate({ // error + x: 1, + y: 1, + z: 2, + angle: 30 + }); + private matrix1 = matrix4.copy(); // error + + private matrix1 = matrix4.translate({ x: 100 }); // error + + build() { + Column() { + }.width("100%").margin({ top: 50 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.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/deprecatedapi/matrix4Rotate_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..7eaba6bdbb881c0bb98b8a76b31a7e032de7dcef --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.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": 20, + "column": 29, + "endLine": 20, + "endColumn": 35, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"rotate\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 29, + "endLine": 26, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"copy\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 29, + "endLine": 28, + "endColumn": 38, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"translate\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.json b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/matrix4Rotate_api.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/deprecatedapi/measure.ets b/ets2panda/linter/test/deprecatedapi/measure.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcde2d53ca6739444a392bba783d8e41f98e976c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/measure.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. + */ + +import { MeasureText } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + textSize: SizeOptions = MeasureText.measureTextSize({ //error + textContent: "Hello World", + fontSize: '50px' + }); + @State textWidth: number = MeasureText.measureText({ //error + textContent: "Hello World", + fontSize: '50px' + }); + + build() { + Row() { + Column() { + Text(`The width of 'Hello World': ${this.textSize.width}`) + Text(`The width of 'Hello World': ${this.textWidth}`) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/measure.ets.args.json b/ets2panda/linter/test/deprecatedapi/measure.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/measure.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/deprecatedapi/measure.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/measure.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a52ce66124292611d03e23134bd8d79db201d134 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/measure.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": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 13, + "endLine": 21, + "endColumn": 24, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 9, + "endLine": 33, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 9, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/measure.ets.json b/ets2panda/linter/test/deprecatedapi/measure.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/measure.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/deprecatedapi/mediaquery.ets b/ets2panda/linter/test/deprecatedapi/mediaquery.ets new file mode 100644 index 0000000000000000000000000000000000000000..be7cc2c88613b133dfc05e9890b53441db9753e8 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/mediaquery.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. + */ + +import { mediaquery } from '@kit.ArkUI'; + +@Entry +@Component +struct MediaQueryExample { + @State color: string = '#DB7093' + @State text: string = 'Portrait' + listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)'); //error + + onPortrait(mediaQueryResult:mediaquery.MediaQueryResult) { + if (mediaQueryResult.matches) { + this.color = '#FFD700' + this.text = 'Landscape' + } else { + this.color = '#DB7093' + this.text = 'Portrait' + } + } + + aboutToAppear() { + let portraitFunc = (mediaQueryResult: mediaquery.MediaQueryResult): void => this.onPortrait(mediaQueryResult) + this.listener.on('change', portraitFunc); + } + + + aboutToDisappear() { + this.listener.off('change'); + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text(this.text).fontSize(24).fontColor(this.color) + } + .width('100%').height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/mediaquery.ets.args.json b/ets2panda/linter/test/deprecatedapi/mediaquery.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/mediaquery.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/deprecatedapi/mediaquery.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/mediaquery.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1aaeb2ff4050758a33e7cc2327b13f51f4c1cf6f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/mediaquery.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": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 23, + "endLine": 46, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 37, + "endLine": 46, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 57, + "endLine": 46, + "endColumn": 66, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 91, + "endLine": 46, + "endColumn": 100, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 7, + "endLine": 47, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/mediaquery.ets.json b/ets2panda/linter/test/deprecatedapi/mediaquery.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/mediaquery.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/deprecatedapi/minibar_api.ets b/ets2panda/linter/test/deprecatedapi/minibar_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..2429a98b61a670558e1574a9d6d7eac4027e23e9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/minibar_api.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 {PanelType} from './sdk/api/panel' + +@@Entry +@Component +struct WrapContentPanelExample { + @State isVisible: boolean = true + build() { + Column() { + Panel(this.isVisible) + .type(PanelType.Minibar) // error + } + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/minibar_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/minibar_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/minibar_api.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/deprecatedapi/minibar_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/minibar_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..c6074fab7b1f09c089ea282b9938c4b649a92181 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/minibar_api.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": 17, + "endColumn": 2, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 23, + "endLine": 24, + "endColumn": 30, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Minibar\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/minibar_api.ets.json b/ets2panda/linter/test/deprecatedapi/minibar_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/minibar_api.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/deprecatedapi/navigation.ets b/ets2panda/linter/test/deprecatedapi/navigation.ets new file mode 100644 index 0000000000000000000000000000000000000000..244b22cd1a50d17b88f5a13a767e280d082c89e3 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigation.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. + */ + +@Entry +@Component +struct NavigationExample { + build() { + Column({ space: 15 }) { + Row() { + Navigation() + .subTitle("test") //error + .toolBar() //error + } + .borderRadius(20) + } + .width('100%') + .margin({ top: 15 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navigation.ets.args.json b/ets2panda/linter/test/deprecatedapi/navigation.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigation.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/deprecatedapi/navigation.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/navigation.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7700e8eb238931a7ff23ac286ecd8d9a06ad2b5a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigation.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": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigation\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navigation.ets.json b/ets2panda/linter/test/deprecatedapi/navigation.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigation.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/deprecatedapi/navigator_api.ets b/ets2panda/linter/test/deprecatedapi/navigator_api.ets new file mode 100644 index 0000000000000000000000000000000000000000..f0a513452e0eb4c7c487eb2d86857aea0a56ce98 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigator_api.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 {NavigatorInstance,Navigator,NavigatorAttribute} from './sdk/api/navigator'; + +function aa(tt:NavigatorAttribute){//error + const a = new NavigatorAttribute() //error + typeof a.active(false);//error + return a as NavigatorAttribute;//error +} +@Entry +@Component +struct NavigatorExample { + @State active: boolean = false; + @State name: NameObject = { name: 'news' }; + + build() { + Flex({ + direction: FlexDirection.Column, + alignItems: ItemAlign.Start, + justifyContent: FlexAlign.SpaceBetween + }) { + Navigator({//error + target: 'pages/container/navigator/Detail', + type: NavigationType.Push + }).onClick(()=>{ + const attr = new NavigatorAttribute(); //error + attr.target('111')//error + }).params(new TextObject(this.name)) + NavigatorInstance.active(false);//error + }.height(150).width(350).padding(35); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navigator_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/navigator_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigator_api.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/deprecatedapi/navigator_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/navigator_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..d89f2a2fbfd985b33e98eb47ee0b06f973e70d9f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigator_api.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": 16, + "endLine": 17, + "endColumn": 34, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 36, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 12, + "endLine": 19, + "endColumn": 18, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"active\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 15, + "endLine": 20, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 16, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Navigator\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 26, + "endLine": 38, + "endColumn": 44, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavigatorAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 20, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"target\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 21, + "endLine": 40, + "endColumn": 31, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 25, + "endLine": 41, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"active\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 2, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Flex\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 18, + "endLine": 30, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexDirection\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 32, + "endLine": 30, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 19, + "endLine": 31, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 15, + "endLine": 36, + "endColumn": 29, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"NavigationType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navigator_api.ets.json b/ets2panda/linter/test/deprecatedapi/navigator_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navigator_api.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/deprecatedapi/navrouter_api.ets b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3f483241757f946564e1f0cac33e32f1f6ca87c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navrouter_api.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 {NavRouterInstance,NavRouter,NavRouterAttribute} from './sdk/api/nav_router'; +import {NavRouteMode,NavRouterInterface,RouteInfo} from './sdk/api/nav_router'; + +@Entry +@Component +struct NavRouterExample { + @State isActiveWLAN: boolean = false + @State isActiveBluetooth: boolean = false + + build() { + Navigation() { + NavRouter() //error + .mode(NavRouteMode.PUSH_WITH_RECREATE) //error*3 + NavRouter({name:'',param:undefined}) //error *3 + .mode(NavRouteMode.PUSH_WITH_RECREATE) //error*3 + .onStateChange((isActivated: boolean) => { //error + console.log(NavRouteMode.REPLACE+'') //error*2 + const attr = new NavRouterAttribute(); //error + attr.mode(NavRouteMode.PUSH); //error*3 + }) + NavRouterInstance.mode(NavRouteMode.REPLACE) //error*3 + } + } +} +class Test implements NavRouterInterface {//error + public (): NavRouterAttribute;//error + public (value: RouteInfo): NavRouterAttribute;//error *2 + public (value?: RouteInfo): NavRouterAttribute|void {//error*2 + const attribute: NavRouterAttribute|undefined = undefined;//error + } +} +interface Demo extends NavRouterInterface{//error +} diff --git a/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navrouter_api.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/deprecatedapi/navrouter_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..57e21154938a7df953c23043da19152c49d91ca2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.arkts2.json @@ -0,0 +1,428 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 10, + "endLine": 27, + "endColumn": 14, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 16, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouter\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 28, + "endLine": 27, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PUSH_WITH_RECREATE\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 23, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"onStateChange\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 14, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 16, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouter\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"name\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"param\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 28, + "endLine": 29, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PUSH_WITH_RECREATE\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 35, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 36, + "endLine": 31, + "endColumn": 43, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"REPLACE\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 28, + "endLine": 32, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 16, + "endLine": 33, + "endColumn": 20, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 21, + "endLine": 33, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 34, + "endLine": 33, + "endColumn": 38, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PUSH\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 25, + "endLine": 35, + "endColumn": 29, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"mode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 42, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouteMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 43, + "endLine": 35, + "endColumn": 50, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"REPLACE\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 23, + "endLine": 39, + "endColumn": 41, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterInterface\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 33, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 14, + "endLine": 40, + "endColumn": 32, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 49, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 18, + "endLine": 41, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"RouteInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 30, + "endLine": 41, + "endColumn": 48, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 3, + "endLine": 42, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 3, + "endLine": 44, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 31, + "endLine": 42, + "endColumn": 54, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 19, + "endLine": 42, + "endColumn": 28, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"RouteInfo\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 50, + "endLine": 42, + "endColumn": 54, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 31, + "endLine": 42, + "endColumn": 49, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 22, + "endLine": 43, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterAttribute\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 24, + "endLine": 46, + "endColumn": 42, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NavRouterInterface\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Navigation\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.json b/ets2panda/linter/test/deprecatedapi/navrouter_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/navrouter_api.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/deprecatedapi/node_api.ets b/ets2panda/linter/test/deprecatedapi/node_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..5e1932af73e10d644a935daf8142e3bcd77da2ce --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/node_api.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 {XComponentType} from './sdk/api/enums' +@Entry +@Component +struct XComponentNodeExample { + build() { + Column() { + XComponent(XComponentType.NODE) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/node_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/node_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/node_api.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/deprecatedapi/node_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/node_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..def7da8f2c60645bd2886b05b83bcf743e98ac33 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/node_api.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": 21, + "column": 33, + "endLine": 21, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"NODE\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/node_api.ets.json b/ets2panda/linter/test/deprecatedapi/node_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/node_api.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/deprecatedapi/ohos_animator.ets b/ets2panda/linter/test/deprecatedapi/ohos_animator.ets new file mode 100755 index 0000000000000000000000000000000000000000..30544f0142a52e321e37147d8c58fbb7eae60ead --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_animator.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. + */ + +import { Animator as animator, AnimatorOptions, AnimatorResult } from '@kit.ArkUI'; + +let options: AnimatorOptions = { + duration: 1500, + easing: "friction", + delay: 0, + fill: "forwards", + direction: "normal", + iterations: 3, + begin: 200.0, + end: 400.0, +}; +this.animator = animator.createAnimator(options); // error +let animatorResult: AnimatorResult = animator.create(options); +animatorResult.update(options); // error diff --git a/ets2panda/linter/test/deprecatedapi/ohos_animator.ets.args.json b/ets2panda/linter/test/deprecatedapi/ohos_animator.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_animator.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/deprecatedapi/ohos_animator.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_animator.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0ee8803766fd9c60dfee0ba66243e14bd07a4e18 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_animator.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": 30, + "column": 1, + "endLine": 30, + "endColumn": 31, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Animator\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ohos_animator.ets.json b/ets2panda/linter/test/deprecatedapi/ohos_animator.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_animator.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/deprecatedapi/ohos_curves.ets b/ets2panda/linter/test/deprecatedapi/ohos_curves.ets new file mode 100755 index 0000000000000000000000000000000000000000..4b8d21ca2c510d663890861a144a9d9d6f2cfce3 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_curves.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 { curves } from '@kit.ArkUI'; + +class AnimationHelper { + steps() { + curves.steps(9, true); // error + } +} + +curves.spring(10, 1, 228, 30) // error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ohos_curves.ets.args.json b/ets2panda/linter/test/deprecatedapi/ohos_curves.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_curves.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/deprecatedapi/ohos_curves.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_curves.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_curves.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/deprecatedapi/ohos_curves.ets.json b/ets2panda/linter/test/deprecatedapi/ohos_curves.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_curves.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/deprecatedapi/ohos_matrix4.ets b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets new file mode 100755 index 0000000000000000000000000000000000000000..f5b77dfb5b28a5869dd2791fdf978b15be9e0e8a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.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 { matrix4 } from '@kit.ArkUI'; + +@Entry +@Component +struct Test { + private matrix1 = matrix4 + .scale({ + // error + x: 2, + y: 3, + z: 4, + centerX: 50, + centerY: 50 + }); + private originPoint: number[] = [50, 50]; + private transformPoint = matrix4.transformPoint([this.originPoint[0], this.originPoint[1]]); // error + private matrix2 = matrix4.identity().scale({ x: 2 }); + + build() { + Column() { + Text('Test') + .width("40%") + .height(100) + .transform(this.matrix1) + Text(`矩阵变换后的坐标:[${this.transformPoint}]`) + .fontSize(16) + .margin({ top: 100 }) + Text("test") + .transform(matrix4.combine(this.matrix2))// error + .width("40%") + .height(100) + .margin({ top: 50 }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.args.json b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.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/deprecatedapi/ohos_matrix4.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..d5842a17bf4ec11cd82be1c96c68d2166f3cf7c1 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.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": 21, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 95, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 52, + "endLine": 31, + "endColumn": 68, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 73, + "endLine": 31, + "endColumn": 89, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 7, + "endLine": 43, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.json b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..336c0150b8a3f1496c3d317b9aaa4d7598c75242 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_matrix4.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": 3, + "endLine": 29, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 95, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 56, + "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/deprecatedapi/ohos_prompt.ets b/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets new file mode 100755 index 0000000000000000000000000000000000000000..dd82bbcdc35a7483e68edae1991675110ffb3dfd --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import prompt from '@ohos.prompt'; + +const toastOptions: prompt.ShowToastOptions = { + message: 'Message Info', //error + duration: 2000 +}; + +prompt.showDialog(toastOptions)//error + .then(data => { + console.info('showDialog success, click button: ' + data.index); + }) + .catch((err: Error) => { + console.info('showDialog error: ' + err); + }) + +const dialogOptions: prompt.ShowDialogOptions = { // error + title: 'Title Info', + message: 'Message Info' +}; + +prompt.showDialog(dialogOptions)// error + .then(data => { + console.info('showDialog success'); + }) + +prompt.showDialog({ + title: 'showDialog Title Info', // error + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + }, + { + text: 'button2', + color: '#000000' + } + ] +}, (err, data) => { + if (err) { + console.info('showDialog err: ' + err); + return; + } + console.info('showDialog success callback, click button: ' + data.index); // error +}); +prompt.showActionMenu({ + title: 'Title Info', + buttons: [// error + { + text: 'button1', + color: '#000000' + }, + { + text: 'button2', + color: '#000000' + } + ], +}) + .then(data => { + console.info('showActionMenu success, click button: ' + data.index); + }) + .catch((err: Error) => { + console.info('showActionMenu error: ' + err); + }) + +const button: prompt.Button = { + text: 'test', + color: 'red' // error +}; + +prompt.showDialog({ + title: 'Title Info', + message: 'Message Info', + buttons: [button], +}) + .then(data => { + console.info('showDialog success, click button: ' + data.index); + }) + .catch((err: Error) => { + console.info('showDialog error: ' + err); + }) + +prompt.showToast({ // error + message: 'Message Info', + duration: 2000 +}); + +let response: Promise = prompt.showDialog({ // error + title: 'Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + }, + { + text: 'button2', + color: '#000000' + } + ], +}) + .then(data => { + console.info('showDialog success, click button: ' + data.index); + return data; + }) + .catch((err: Error) => { + console.info('showDialog error: ' + err); + throw err; + }); + +prompt.showToast({ // error + message: 'Message Info', + duration: 2000 +}); + diff --git a/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets.args.json b/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_prompt.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/deprecatedapi/ohos_prompt.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..642f794c6c14c1c3e865b2e2ca66083f1b4f93e7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_prompt.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": 24, + "column": 9, + "endLine": 24, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 9, + "endLine": 37, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 9, + "endLine": 74, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 9, + "endLine": 91, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 9, + "endLine": 120, + "endColumn": 4, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 9, + "endLine": 117, + "endColumn": 13, + "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/deprecatedapi/ohos_prompt.ets.json b/ets2panda/linter/test/deprecatedapi/ohos_prompt.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..642f794c6c14c1c3e865b2e2ca66083f1b4f93e7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_prompt.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": 24, + "column": 9, + "endLine": 24, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 9, + "endLine": 37, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 9, + "endLine": 74, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 9, + "endLine": 91, + "endColumn": 13, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 9, + "endLine": 120, + "endColumn": 4, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 9, + "endLine": 117, + "endColumn": 13, + "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/deprecatedapi/ohos_router.ets b/ets2panda/linter/test/deprecatedapi/ohos_router.ets new file mode 100755 index 0000000000000000000000000000000000000000..ae611f9ff3fd531d665d86b222a9b1c635f40421 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_router.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. + */ + +import router from '@ohos.router'; + +router.enableAlertBeforeBackPage({ // error + message: 'Message Info' +}); + +class routerParams { + data1: string; + + constructor(str: string) { + this.data1 = str; + } +} + +router.replace({ // error + url: 'pages/detail', + params: new routerParams('message') +}); + +router.disableAlertBeforeBackPage(); // error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/ohos_router.ets.args.json b/ets2panda/linter/test/deprecatedapi/ohos_router.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_router.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/deprecatedapi/ohos_router.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/ohos_router.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_router.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/deprecatedapi/ohos_router.ets.json b/ets2panda/linter/test/deprecatedapi/ohos_router.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/ohos_router.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/deprecatedapi/panelModePanelMode_api.ets b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..bf817a2f4843d7eef5ce101db9799348ea58f9c6 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.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 {PanelMode} from './sdk/api/panel'; + +@Entry +@Component +struct PanelExample { + @State show: boolean = false + + build() { + Column() { + Panel(this.show) { + Column() { + } + } + .mode(PanelMode.Mini) //error + Panel(this.show) { + Column() { + } + } + .mode(PanelMode.Half) //error + Panel(this.show) { + Column() { + } + } + .mode(PanelMode.Full) //error + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.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/deprecatedapi/panelModePanelMode_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ef40455b9ca93add729f1161ae55b785aa6a5fd9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.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": 28, + "column": 13, + "endLine": 28, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Mini\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 23, + "endLine": 33, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Half\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelMode\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 23, + "endLine": 38, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Full\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 9, + "endLine": 35, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.json b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/panelModePanelMode_api.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/deprecatedapi/persistentStoragePersistProps_api.ets b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..a15ecce3cf2b761577d6397d9089a1d2af58e15e --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.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 { PersistentStorage } from './sdk/api/common_ts_ets_api'; + +PersistentStorage.PersistProps([{ key: 'highScore', defaultValue: '0' }, { key: 'wightScore', defaultValue: '1' }]); //error +PersistentStorage.Keys(); //error \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.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/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..561f0d678b154d1fde55286eec533cfcb4d76ddc --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.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": 17, + "column": 19, + "endLine": 17, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PersistProps\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 19, + "endLine": 18, + "endColumn": 23, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Keys\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.json b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/persistentStoragePersistProps_api.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/deprecatedapi/progress.ets b/ets2panda/linter/test/deprecatedapi/progress.ets new file mode 100755 index 0000000000000000000000000000000000000000..523cdab0b9967e71bed8105324fb99506d3a6a8a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/progress.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. + */ + +@Entry +@Component +struct ProgressExample { + private gradientColor: LinearGradient = new LinearGradient([{ color: Color.Yellow, offset: 0.5 }, + { color: Color.Orange, offset: 1.0 }]) + private progress: ProgressOptions = { + value: 70, + total: 100, + type: ProgressType.Ring, + style: ProgressStyle.Linear // error + }; + + build() { + Column({ space: 15 }) { + Text('Gradient Color').fontSize(9).fontColor(0xCCCCCC).width('90%') + Progress(this.progress) + .width(100).style({ strokeWidth: 20 }) + .color(this.gradientColor) + }.width('100%').padding({ top: 5 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/progress.ets.args.json b/ets2panda/linter/test/deprecatedapi/progress.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/progress.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/deprecatedapi/progress.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/progress.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..9f2cb2ef50766faf9c49734ec706c3f4099620ba --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/progress.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": 19, + "column": 47, + "endLine": 19, + "endColumn": 61, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 26, + "endLine": 19, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"LinearGradient\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 47, + "endLine": 19, + "endColumn": 61, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"LinearGradient\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 72, + "endLine": 19, + "endColumn": 77, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 14, + "endLine": 20, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 21, + "endLine": 21, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ProgressOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 37, + "endLine": 21, + "endColumn": 49, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ProgressType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 11, + "endLine": 24, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ProgressType\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 12, + "endLine": 25, + "endColumn": 25, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ProgressStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Progress\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/progress.ets.json b/ets2panda/linter/test/deprecatedapi/progress.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/progress.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/deprecatedapi/prompts_api.ets b/ets2panda/linter/test/deprecatedapi/prompts_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..c6f549d289635b8e3271dbdc7553da18cb93b824 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/prompts_api.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. + */ +import prompt from './sdk/api/@ohos.prompt' + +prompt.showToast({ + message: 'www', + duration: 2000, + bottom: 20, +}); + +prompt.showDialog({ + title: 'Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + }, + ], +}) + +prompt.showActionMenu({ + title: 'Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + }, + { + text: 'item2', + color: '#000000' + }, + ] +}, (err, data) => { + if (err) { + console.info('showActionMenu err: ' + err); + return; + } + console.info('showActionMenu success callback, click button: ' + data.index); +}) + +prompt.showDialog({ + title: 'showDialog Title Info', + message: 'Message Info', + buttons: [ + { + text: 'button1', + color: '#000000' + }, + { + text: 'button2', + color: '#000000' + } + ] +}, (err, data) => { + if (err) { + console.info('showDialog err: ' + err); + return; + } + console.info('showDialog success callback, click button: ' + data.index); +}); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/prompts_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/prompts_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/prompts_api.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/deprecatedapi/prompts_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/prompts_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..53b184dcb966ec450771389dd29ba611f0d9032f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/prompts_api.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": 17, + "column": 8, + "endLine": 17, + "endColumn": 17, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showToast\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 11, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"duration\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 9, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 18, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 8, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 8, + "endLine": 34, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 7, + "endLine": 43, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 8, + "endLine": 54, + "endColumn": 18, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showDialog\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 3, + "endLine": 55, + "endColumn": 8, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"title\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"message\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 7, + "endLine": 60, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 7, + "endLine": 64, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 10, + "endLine": 67, + "endColumn": 14, + "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/deprecatedapi/prompts_api.ets.json b/ets2panda/linter/test/deprecatedapi/prompts_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..bf8516a85b5a1242ca48f44d05087ec3ee41f55c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/prompts_api.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": 46, + "column": 5, + "endLine": 46, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 10, + "endLine": 67, + "endColumn": 14, + "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/deprecatedapi/refresh.ets b/ets2panda/linter/test/deprecatedapi/refresh.ets new file mode 100644 index 0000000000000000000000000000000000000000..f58c225b7c6e748e4cf0ac5c7b53abbe59c409f5 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/refresh.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Entry +@Component +struct RefreshExample { + @State isRefreshing: boolean = false; + @State promptText: string = "Refreshing..."; + @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; + + + build() { + Column() { + Refresh({ refreshing: $$this.isRefreshing, offset: 1 }) { //error + List() { + ForEach(this.arr, (item: string) => { + ListItem() { + Text('' + item) + .width('70%') + .height(80) + .fontSize(16) + .margin(10) + .textAlign(TextAlign.Center) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .onScrollIndex((first: number) => { + console.info(first.toString()); + }) + .width('100%') + .height('100%') + .alignListItem(ListItemAlign.Center) + .scrollBar(BarState.Off) + } + .backgroundColor(0x89CFF0) + .pullToRefresh(true) + .refreshOffset(96) + .onStateChange((refreshStatus: RefreshStatus) => { + console.info('Refresh onStatueChange state is ' + refreshStatus); + }) + .onOffsetChange((value: number) => { + console.info('Refresh onOffsetChange offset:' + value); + }) + .onRefreshing(() => { + setTimeout(() => { + this.isRefreshing = false; + }, 2000) + console.log('onRefreshing test'); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/refresh.ets.args.json b/ets2panda/linter/test/deprecatedapi/refresh.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/refresh.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/deprecatedapi/refresh.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/refresh.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1feb7c3c60487ef34820d61fd3aa988acded1b47 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/refresh.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": 26, + "column": 29, + "endLine": 26, + "endColumn": 48, + "problem": "DoubleDollarBindingNotSupported", + "suggest": "", + "rule": "\"$$\" for bidirectional data binding is not supported (arkui-no-$$-bidirectional-data-binding)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Refresh\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 13, + "endLine": 29, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 15, + "endLine": 30, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 28, + "endLine": 35, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 24, + "endLine": 46, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItemAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 20, + "endLine": 47, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BarState\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 38, + "endLine": 52, + "endColumn": 51, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RefreshStatus\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/refresh.ets.json b/ets2panda/linter/test/deprecatedapi/refresh.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/refresh.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/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..542dae4405efc784596a00e80d41e97e2be54f43 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.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. + */ +import Router from './sdk/api/@system.router'; + +class Z{ + disableAlertBeforeBackPage() { + Router.disableAlertBeforeBackPage({ + success: () => { + console.log('success'); + }, + cancel: () => { + console.log('cancel'); + }, + complete: () => { + console.log('cancel'); + } + }); + } +} +export default new Z() + +class C{ + replacePage() { + Router.replace({ + uri: 'pages/detail/detail', + params: { + data1: 'message' + } + }); + } +} +export default new C() + +class I{ + clearPage() { + Router.clear(); + } +} +export default new I() + +Router \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.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/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..13f2b04663178be67bde27ca94747c32f2bdb666 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.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": 19, + "column": 12, + "endLine": 19, + "endColumn": 38, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"disableAlertBeforeBackPage\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 14, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"success\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 15, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"complete\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 12, + "endLine": 36, + "endColumn": 19, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"replace\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"uri\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 13, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"params\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 17, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"clear\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 7, + "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/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.json b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..bc846022c12b599c5a2bb361e32514e403fa3d3d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerDisableAlertBeforeBackPage_api.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": 53, + "column": 1, + "endLine": 53, + "endColumn": 7, + "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/deprecatedapi/routerOptionsUri_api.ets b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..0a37728e9f10164a45fd3a1f232fc03003351f47 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.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. + */ +import router from './sdk/api/@system.router'; + +class H{ + backToDetail() { + router.back({uri:'pages/detail/detail'}); + } +} +export default new H() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.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/deprecatedapi/routerOptionsUri_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.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/deprecatedapi/routerOptionsUri_api.ets.json b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerOptionsUri_api.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/deprecatedapi/routerPush_api.ets b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..e8b1028e9481c37aa5c25a1a42b54ca6116c1c78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerPush_api.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 { router } from './sdk/api/@ohos.router'; + +class innerParams { + data3: number[]; + + constructor(tuple: number[]) { + this.data3 = tuple; + } +} + +class routerParams { + data1: string; + data2: innerParams; + + constructor(str: string, tuple: number[]) { + this.data1 = str; + this.data2 = new innerParams(tuple); + } +} + +router.push({ + url: 'pages/routerpage2', + params: new routerParams('message', [123, 456, 789]) +}); \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerPush_api.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/deprecatedapi/routerPush_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..75f13d829815cbb41452b9ed7b8e43405ed67919 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerPush_api.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": 35, + "column": 8, + "endLine": 35, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"push\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.json b/ets2panda/linter/test/deprecatedapi/routerPush_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerPush_api.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/deprecatedapi/routerStateIndex_api.ets b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..8bc04f1c264c776d0ee6e858b77dce9d0c025b20 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.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. + */ +import RouterState from './sdk/api/@system.router'; + +class K{ + getState() { + let page = RouterState.getState().index; + } +} +export default new K() \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.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/deprecatedapi/routerStateIndex_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..bd4e05e281364c8da7fbd022427d8660f057aefa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.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": 9, + "endLine": 19, + "endColumn": 44, + "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/deprecatedapi/routerStateIndex_api.ets.json b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..bd4e05e281364c8da7fbd022427d8660f057aefa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/routerStateIndex_api.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": 19, + "column": 9, + "endLine": 19, + "endColumn": 44, + "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/deprecatedapi/scroll_api.ets b/ets2panda/linter/test/deprecatedapi/scroll_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..0e584adaccb79dfd4d8327c19cb656f8e56df46b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/scroll_api.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. + */ +import {ScrollDirection,Scroller,ScrollAttribute} from './sdk/api/scroll'; + +const scroller: Scroller = new Scroller() +@Entry +@Component +struct ScrollExample { + + build() { + Stack({ alignContent: Alignment.TopStart }) { + Scroll(scroller) + .scrollable(ScrollDirection.Free) //error + Column() { + }.width('100%') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/scroll_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/scroll_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/scroll_api.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/deprecatedapi/scroll_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/scroll_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..9ad6cbf5bf902779eb177fb3292e80dcf9668b37 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/scroll_api.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": 25, + "column": 37, + "endLine": 25, + "endColumn": 41, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Free\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Stack\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Alignment\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroll\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/scroll_api.ets.json b/ets2panda/linter/test/deprecatedapi/scroll_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/scroll_api.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/deprecatedapi/sdk/api/@ohos.animator.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.animator.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..3fea7915eac8a117c22f118e80e9b8c2cb50bf0e --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.animator.d.ts @@ -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. + */ + +export declare class Animator { + static createAnimator(options: AnimatorOptions): AnimatorResult; + static create(options: AnimatorOptions): AnimatorResult; +} + +export interface AnimatorOptions { + duration: number; + easing: string; + delay: number; + fill: "none" | "forwards" | "backwards" | "both"; + direction: "normal" | "reverse" | "alternate" | "alternate-reverse"; + iterations: number; + begin: number; + end: number; +} + +export interface AnimatorResult { + update(options: AnimatorOptions): void; + reset(options: AnimatorOptions): void; + reset(options: AnimatorOptions | SimpleAnimatorOptions): void; + play(): void; + finish(): void; + pause(): void; + cancel(): void; + reverse(): void; + onframe: (progress: number) => void; + onFrame: (progress: number) => void; + onfinish: () => void; + onFinish: () => void; + oncancel: () => void; + onCancel: () => void; + onrepeat: () => void; + onRepeat: () => void; + setExpectedFrameRateRange(rateRange: ExpectedFrameRateRange): void; +} + +export declare class SimpleAnimatorOptions { + duration(duration: number): SimpleAnimatorOptions; + easing(curve: string): SimpleAnimatorOptions; + delay(delay: number): SimpleAnimatorOptions; + fill(fillMode: FillMode): SimpleAnimatorOptions; + direction(direction: PlayMode): SimpleAnimatorOptions; + iterations(iterations: number): SimpleAnimatorOptions; +} + +declare enum PlayMode { + Normal, + Reverse, + Alternate, + AlternateReverse +} + +declare interface ExpectedFrameRateRange { + min: number; + max: number; + expected: number; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.curves.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.curves.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..8d7164186ce16777d6ebc2f398c765abbc41d631 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.curves.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 namespace curves { + function init(curve?: Curve): string; +} diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.font.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.font.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..d8a7e565ce3b06649db971abadab352a0dbebab4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.font.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 namespace font { + function getFontByName(fontName: string): FontInfo; + function getSystemFontList(): Array; + function registerFont(options: FontOptions): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.matrix4.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.matrix4.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..29f253a989d28078c193956f21a11690401d0a65 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.matrix4.d.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 declare namespace matrix4 { + function rotate(options: RotateOption): Matrix4Transit; + function copy(): Matrix4Transit; + function translate(options: TranslateOption): Matrix4Transit; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.prompt.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.prompt.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..d8a0fae2aac6e8af4a52dc294f23fe187d28f284 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.prompt.d.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. + */ +declare namespace prompt { + + interface ShowToastOptions { + message: string; + duration?: number; + bottom?: string | number; + } + interface Button { + text: string; + color: string; + } + interface ShowDialogSuccessResponse { + index: number; + } + interface ShowDialogOptions { + title?: string; + message?: string; + buttons?: [ + Button, + Button?, + Button? + ]; + } + interface ActionMenuSuccessResponse { + index: number; + } + interface ActionMenuOptions { + title?: string; + buttons: [ + Button, + Button?, + Button?, + Button?, + Button?, + Button? + ]; + } + function showToast(options: ShowToastOptions): void; + function showDialog(options: ShowDialogOptions, callback: AsyncCallback): void; + function showDialog(options: ShowDialogOptions): Promise; + function showActionMenu(options: ActionMenuOptions, callback: AsyncCallback): void; + function showActionMenu(options: ActionMenuOptions): Promise; +} +export default prompt; diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.router.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.router.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..9c2e6dc51a3b83ba737b17072cac18e4d678398d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@ohos.router.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 namespace router { + function push(options: RouterOptions): void; +} + +export interface BackRouterOptions { + uri?: string; + params?: Object; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@system.app.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.app.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..274e07311ccd4ebbf7d5ce242853d3012a68b401 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.app.d.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 default class App { + static setImageCacheCount(value: number): void; + static setImageRawDataCacheSize(value: number): void; + static setImageFileCacheSize(value: number): void; + static screenOnVisible(options?: ScreenOnVisibleOptions): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@system.prompt.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.prompt.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..cf2a916ea8b3603fc88e2f50f42a4853f197e6e5 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.prompt.d.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 default class Prompt { + static showToast(options: ShowToastOptions): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/@system.router.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.router.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..771cd691992e9241b0a0f94cecca58e5bd9d2fdf --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/@system.router.d.ts @@ -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. + */ + +export default class Router { + static enableAlertBeforeBackPage(options: EnableAlertBeforeBackPageOptions): void; + static disableAlertBeforeBackPage(options?: DisableAlertBeforeBackPageOptions): void; + static replace(options: RouterOptions): void; + static clear(): void; +} + +export interface DisableAlertBeforeBackPageOptions { + success?: (errMsg: string) => void; + complete?: () => void; +} + +export interface RouterState { + index: number; + name: string; + path: string; +} + +export interface RouterOptions { + uri: string; + params?: Object; +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/esobject_with_string_key.ets b/ets2panda/linter/test/deprecatedapi/sdk/api/ChipGroup.d.ets similarity index 89% rename from ets2panda/test/ast/compiler/ets/esobject_with_string_key.ets rename to ets2panda/linter/test/deprecatedapi/sdk/api/ChipGroup.d.ets index b2468c1afbf2b44a7ebdef824f8d09a92759bc7c..552b88513cf344f80c93b4409b36e817285e9fd1 100644 --- a/ets2panda/test/ast/compiler/ets/esobject_with_string_key.ets +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/ChipGroup.d.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -function foo (es: JSValue, str: string): string { - return es[str]; -} \ No newline at end of file +export interface ChipGroupItemOptions { + suffixIcon?: IconOptions; +} diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/action_sheet.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/action_sheet.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ad8ab60c94222eab5c432cbaaec1cf171730974 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/action_sheet.d.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. + */ + +export interface ActionSheetOptions { + autoCancel?: boolean; + showInSubWindow?: boolean; + isModal?: boolean; +} + +export declare class ActionSheet { + static show(value: ActionSheetOptions); +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/alert_dialog.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/alert_dialog.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a26a6671d472ddf5d82fb800d2ed4e456975739b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/alert_dialog.d.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. + */ + +export declare class AlertDialog { + static show(value: AlertDialogParamWithConfirm | AlertDialogParamWithButtons | AlertDialogParamWithOptions); +} + +declare interface AlertDialogParamWithConfirm extends AlertDialogParam { + confirm?: AlertDialogButtonBaseOptions; +} + +declare interface AlertDialogParamWithButtons extends AlertDialogParam { + primaryButton: AlertDialogButtonBaseOptions; + secondaryButton: AlertDialogButtonBaseOptions; +} + +declare interface AlertDialogParamWithOptions extends AlertDialogParam { + buttons: Array; +} + +declare interface AlertDialogButtonBaseOptions {} + +declare interface AlertDialogParam {} + +declare interface AlertDialogButtonOptions extends AlertDialogButtonBaseOptions { + primary?: boolean; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/common.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/common.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..ab9ed204bd66018bf38960d81ae116ca120c54ac --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/common.d.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. + */ + +export declare interface CustomPopupOptions { + maskColor?: Color | string | Resource | number; +} + +export declare interface DragEvent { + getX(): number; + getY(): number; +} +declare class CommonMethod { + gridSpan(value: number): T; + gridOffset(value: number): T; +} +export declare interface LayoutInfo {} +export declare interface LayoutChild {} +export declare interface LayoutBorderInfo {} +export declare interface TransitionOptions {} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/common_ts_ets_api.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/common_ts_ets_api.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..4498350f03186a2debad00175b32cd533f56ba7f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/common_ts_ets_api.d.ts @@ -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 declare class LocalStorage { + constructor(initializingProperties?: Object); + static getShared(): LocalStorage; +} + +export declare class Environment { + static EnvProp(key: string, value: S): boolean; + static Keys(): Array; + static EnvProps(props: { + key: string; + defaultValue: any; + }[]): void; +} + +export declare class AppStorage { + static IsMutable(propName: string): boolean; + static Get(propName: string): T | undefined; + static Clear(): boolean; + static Delete(propName: string): boolean; + static Size(): number; +} + +export declare class PersistentStorage { + static PersistProps(properties: { + key: string; + defaultValue: any; + }[]): void; + static Keys(): Array; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/enums.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/enums.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..f08eae1aea29c05b534457210c81d5a22c6619bb --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/enums.d.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. + */ + +export declare enum XComponentType { + SURFACEE, + COMPONENT, + TEXTURE, + NODE +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/grid.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/grid.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..49c677c793dfb970977a3ffeca4e5c178e0fffa4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/grid.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 class GridAttribute extends ScrollableCommonMethod { + onScroll(event: (scrollOffset: number, scrollState: ScrollState) => void): GridAttribute; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/grid_container.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/grid_container.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..6cbc689ddd628a95391cfd57e7ecb9566b1d0580 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/grid_container.d.ts @@ -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. + */ + +export interface GridContainerInterface { + + (value?: GridContainerOptions): GridContainerAttribute; +} + +export declare class GridContainerAttribute extends ColumnAttribute { +} + +export declare enum SizeType { + Auto, + XS, + SM, + MD, + LG +} + +export declare interface GridContainerOptions { + columns?: number | "auto"; + sizeType?: SizeType; + gutter?: number | string; + margin?: number | string; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/list_item.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/list_item.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..d8394f36bafdd354579db5e49ae75729d7047f35 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/list_item.d.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. + */ + +export declare class ListItemAttribute extends CommonMethod { + sticky(value: Sticky): ListItemAttribute; + editable(value: boolean | EditMode): ListItemAttribute; +} + +export declare enum Sticky { + None, + Normal, + Opacity +} + +export declare enum EditMode { + None, + Deletable, + Movable +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/nav_router.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/nav_router.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..ddce579ce4cdf1ce5b613b2143b67ee8e921bb63 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/nav_router.d.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. + */ + +export declare const NavRouterInstance: NavRouterAttribute; +export declare const NavRouter: NavRouterInterface; + +export declare class NavRouterAttribute extends CommonMethod { + mode(mode: NavRouteMode): NavRouterAttribute; + onStateChange(callback: (isActivated: boolean) => void): NavRouterAttribute; +} + +export declare enum NavRouteMode{ + PUSH_WITH_RECREATE, + PUSH, + REPLACE +} + +export declare interface NavRouterInterface { + (): NavRouterAttribute + (value: RouteInfo): NavRouterAttribute; +} + +export declare interface RouteInfo { + name: string; + param?: unknown; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/navigator.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/navigator.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..7a9894459b38b9fa1d352eab3f6e0ae084faa56c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/navigator.d.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. + */ + +export declare const NavigatorInstance: NavigatorAttribute; +export declare const Navigator: NavigatorInterface; + +export declare class NavigatorAttribute extends CommonMethod { + active(value: boolean): NavigatorAttribute; + type(value: NavigationType): NavigatorAttribute; + target(value: string): NavigatorAttribute; + params(value: object): NavigatorAttribute; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/panel.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/panel.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..b011566efad9aec0da31ebd343302136d239738f --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/panel.d.ts @@ -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 declare enum PanelHeight { + WRAP_CONTENT = 'wrapContent' +} +export declare enum PanelType { + Minibar = 0, + Foldable = 1, + Temporary = 2, + CUSTOM = 3 +} +export declare enum PanelMode { + Mini, + Half, + Full +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/scroll.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/scroll.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..96bb53c6482b7d53a7ee4311430a9cf73ed85bb2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/scroll.d.ts @@ -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. + */ + +export declare class ScrollAttribute extends ScrollableCommonMethod { + onScroll(event: (xOffset: number, yOffset: number) => void): ScrollAttribute; + onScrollEnd(event: () => void): ScrollAttribute; +} + +export declare enum ScrollDirection { + Vertical, + Horizontal, + Free, + None +} +export declare class Scroller{ + scrollPage(value: { + next: boolean; + direction?: Axis; + }); +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/slider.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/slider.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f2aae70dd88065d93815de2de9480f26f4557d78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/slider.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 class SliderAttribute extends CommonMethod { + minLabel(value: string): SliderAttribute; + maxLabel(value: string): SliderAttribute; +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sdk/api/swiper.d.ts b/ets2panda/linter/test/deprecatedapi/sdk/api/swiper.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..0c33e754d3ab49d627939ac10257d55e2b197abb --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sdk/api/swiper.d.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. + */ + +export declare interface IndicatorStyle { + left?: Length; + top?: Length; + right?: Length; + bottom?: Length; + size?: Length; + mask?: boolean; + color?: ResourceColor; + selectedColor?: ResourceColor; +} +export declare class SwiperAttribute extends CommonMethod { + indicatorStyle(value?: IndicatorStyle): SwiperAttribute; +} + +export declare enum SwiperDisplayMode { + Stretch, + AutoLinear, + STRETCH, + AUTO_LINEAR +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..2adcbc65c5e9e47fa498a1e5ee11cbb438e674fd --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.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 App from './sdk/api/@system.app'; + +export default class Req { + requestFullWindow() { + App.setImageCacheCount(104857600); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.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/deprecatedapi/setImageCacheCount_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..bb10d761e7eb77663d69e7523a373aee0ad44330 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.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": 9, + "endLine": 19, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"setImageCacheCount\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.json b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageCacheCount_api.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/deprecatedapi/setImageFileCacheSize_api.ets b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..d391c2718ccca26b50f16cf76512cefc4705b5c0 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.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 App from './sdk/api/@system.app'; + +export default class Req { + requestFullWindow() { + App.setImageFileCacheSize(104857600); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.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/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b9b2d94b66338c813a90c14f0767b39ef89f0d72 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.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": 9, + "endLine": 19, + "endColumn": 30, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"setImageFileCacheSize\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.json b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageFileCacheSize_api.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/deprecatedapi/setImageRawDataCacheSize_api.ets b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..8e717bba1fb9c70ec174ba47feafac997e8dd6ad --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.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 App from './sdk/api/@system.app'; + +export default class Req { + requestFullWindow() { + App.setImageRawDataCacheSize(104857600); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.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/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..5238aea41b95937f9844932222072371071f044c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.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": 9, + "endLine": 19, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"setImageRawDataCacheSize\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.json b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/setImageRawDataCacheSize_api.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/deprecatedapi/shortName.ets b/ets2panda/linter/test/deprecatedapi/shortName.ets new file mode 100755 index 0000000000000000000000000000000000000000..a51ac48ceb7d93ead8aea6e9cbf39e76a91c84b7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/shortName.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 { ElementName } from './sdk/api/elementName'; + +funtion a() { + console.log(ElementName.shortName) +} diff --git a/ets2panda/linter/test/deprecatedapi/shortName.ets.args.json b/ets2panda/linter/test/deprecatedapi/shortName.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/shortName.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/deprecatedapi/shortName.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/shortName.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/shortName.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/deprecatedapi/shortName.ets.json b/ets2panda/linter/test/deprecatedapi/shortName.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/shortName.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/deprecatedapi/showActionMenu.ets b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets new file mode 100755 index 0000000000000000000000000000000000000000..543db4aed1d7d5f0430132be6de1ae4a9c348768 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets @@ -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. + */ +import prompt from './sdk/api/@ohos.prompt'; + + +prompt.showActionMenu({ + title: 'Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + }, + { + text: 'item2', + color: '#000000' + }, + ] +}, (err, data) => { + if (err) { + console.info('showActionMenu err: ' + err); + return; + } + console.info('showActionMenu success callback, click button: ' + data.index); +}) + +prompt.showActionMenu({ + title: 'Title Info', + buttons: [ + { + text: 'item1', + color: '#666666' + }, + { + text: 'item2', + color: '#000000' + }, + ] +}).then(()=>{ + +}) \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.args.json b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showActionMenu.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/deprecatedapi/showActionMenu.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..3ac87ce66de491252a590c825b39070358234778 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showActionMenu.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": 8, + "endLine": 18, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 8, + "endLine": 38, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"showActionMenu\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 10, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"buttons\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 7, + "endLine": 43, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 7, + "endLine": 47, + "endColumn": 12, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.json b/ets2panda/linter/test/deprecatedapi/showActionMenu.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..496f2c021f17b4c85cd1fe5c601d30e5686c36e9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showActionMenu.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": 30, + "column": 5, + "endLine": 30, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 14, + "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/deprecatedapi/showToast_api.ets b/ets2panda/linter/test/deprecatedapi/showToast_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..a59df53bff76a6fa7a1da5fc6c3fdde2df680c97 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showToast_api.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. + */ +import Prompt from "./sdk/api/@system.prompt" +class A{ + showToast() { + Prompt.showToast({ + message: 'Message Info', + }); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/showToast_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/showToast_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showToast_api.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/deprecatedapi/showToast_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/showToast_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..9f33816e3cec28049daae4692712ce23c2a5b084 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showToast_api.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": [] +} diff --git a/ets2panda/linter/test/deprecatedapi/showToast_api.ets.json b/ets2panda/linter/test/deprecatedapi/showToast_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f33816e3cec28049daae4692712ce23c2a5b084 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/showToast_api.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/deprecatedapi/sizeType.ets b/ets2panda/linter/test/deprecatedapi/sizeType.ets new file mode 100755 index 0000000000000000000000000000000000000000..ec52efea3e623cf9c7eb7b31292ae6d64b61a3ce --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeType.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. + */ +import { SizeType } from './sdk/api/grid_container' + +@Entry +@Component +struct GridContainerExample { + @State sizeType: SizeType = SizeType.XS + + build() { + Column({ space: 5 }) { + Text('Click Simulate to change the device width').fontSize(9).width('90%').fontColor(0xCCCCCC) + Row() { + Button('XS') + .onClick(() => { + this.sizeType = SizeType.XS + }).backgroundColor(0x317aff) + Button('SM') + .onClick(() => { + this.sizeType = SizeType.SM + }).backgroundColor(0x317aff) + Button('MD') + .onClick(() => { + this.sizeType = SizeType.MD + }).backgroundColor(0x317aff) + Button('LG') + .onClick(() => { + this.sizeType = SizeType.LG + }).backgroundColor(0x317aff) + } + }.width('100%').margin({ top: 5 }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sizeType.ets.args.json b/ets2panda/linter/test/deprecatedapi/sizeType.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeType.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/deprecatedapi/sizeType.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/sizeType.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..832bb8301efdd620dca298bef2bb5fc0143a93a6 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeType.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": 20, + "column": 31, + "endLine": 20, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 40, + "endLine": 20, + "endColumn": 42, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 29, + "endLine": 28, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 38, + "endLine": 28, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 29, + "endLine": 32, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 38, + "endLine": 32, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 29, + "endLine": 36, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 38, + "endLine": 36, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"MD\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 29, + "endLine": 40, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 38, + "endLine": 40, + "endColumn": 40, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"LG\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 9, + "endLine": 34, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 9, + "endLine": 38, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sizeType.ets.json b/ets2panda/linter/test/deprecatedapi/sizeType.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeType.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/deprecatedapi/sizeTypeXS_api.ets b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..9f6cc8207dfe58be5217f4abed9573cf2c3d7a64 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.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 {SizeType} from './sdk/api/grid_container'; + +@Entry +@Component +struct ResponsiveExample { + @StorageLink('currentSizeType') currentSizeType: SizeType = SizeType.SM; + + build() { + Column() { + if (this.currentSizeType === SizeType.XS) { + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.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/deprecatedapi/sizeTypeXS_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..be4383aba184430630271ac83b69e622038b2be9 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.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": 20, + "column": 63, + "endLine": 20, + "endColumn": 71, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 72, + "endLine": 20, + "endColumn": 74, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SM\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 36, + "endLine": 24, + "endColumn": 44, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"SizeType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 45, + "endLine": 24, + "endColumn": 47, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"XS\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"StorageLink\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.json b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/sizeTypeXS_api.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/deprecatedapi/slider_api.ets b/ets2panda/linter/test/deprecatedapi/slider_api.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ec3620c2eb0995594f53b65e0a6179d1911ae52 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/slider_api.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. + */ +import {SliderAttribute} from './sdk/api/slider'; + +@Entry +@Component +struct SliderExample { + build() { + Column({ space: 8 }) { + Row() { + Slider() + .minLabel('aa') //error + .maxLabel('bb') //error + } + .width('100%') + }.width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/slider_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/slider_api.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/slider_api.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/deprecatedapi/slider_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/slider_api.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..82f220ef5e014178fccf39a259d3aeed9e5c0cf0 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/slider_api.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": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/slider_api.ets.json b/ets2panda/linter/test/deprecatedapi/slider_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/slider_api.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/deprecatedapi/swiper_api.ets b/ets2panda/linter/test/deprecatedapi/swiper_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..07a2506defed6a3f55e7cd2f8ef035df79fc6a89 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.ets @@ -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. + */ +import {IndicatorStyle,SwiperDisplayMode} from './sdk/api/swiper'; + +class Test extends Test implements IndicatorStyle{ //error + layoutInfo: IndicatorStyle|undefined = undefined;//error + get(option:Map){//error + option.set('',{top:100,color:1111});//error + option.set('',{bottom:SwiperDisplayMode.Stretch})//error + } + getInfo(){ + return this.layoutInfo; + } + set(){ + typeof this.layoutInfo?.left//error + this.layoutInfo?.right == 100//error + this.layoutInfo?.color?.toString()//error + const info = this.layoutInfo; + console.log(info?.selectedColor+'');//error + this.getInfo()?.mask//error + this.layoutInfo?.bottom//error + setTop(this.getInfo()) + } + setSize(layoutInfo: IndicatorStyle|undefined){//error + layoutInfo?.size ;//error + } +} +function setTop(layoutInfo: IndicatorStyle|undefined ){//error + layoutInfo?.top == 0;//error +} +function getBotton(){ + new Test().getInfo()?.bottom;//error + const test = new Test(); + return test.layoutInfo?.bottom;//error +} +function get(){ + const AutoLinear = SwiperDisplayMode.AutoLinear//error + typeof SwiperDisplayMode.Stretch;//error + return SwiperDisplayMode.AUTO_LINEAR;//error +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.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/deprecatedapi/swiper_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..0d7d48b7bd59d68dded16567af1fbab103cd08c2 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.arkts2.json @@ -0,0 +1,258 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 11, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 37, + "endLine": 17, + "endColumn": 51, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 29, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 25, + "endLine": 19, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 23, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"top\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 20, + "endLine": 21, + "endColumn": 26, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 45, + "endLine": 21, + "endColumn": 52, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Stretch\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 29, + "endLine": 27, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"left\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 22, + "endLine": 28, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"right\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 27, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"color\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 36, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"selectedColor\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 25, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"mask\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 22, + "endLine": 33, + "endColumn": 28, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 23, + "endLine": 36, + "endColumn": 37, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 17, + "endLine": 37, + "endColumn": 21, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"size\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 29, + "endLine": 40, + "endColumn": 43, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"IndicatorStyle\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 15, + "endLine": 41, + "endColumn": 18, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"top\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 25, + "endLine": 44, + "endColumn": 31, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 27, + "endLine": 46, + "endColumn": 33, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"bottom\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 40, + "endLine": 49, + "endColumn": 50, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"AutoLinear\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 28, + "endLine": 50, + "endColumn": 35, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Stretch\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 28, + "endLine": 51, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"AUTO_LINEAR\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/swiper_api.ets.json b/ets2panda/linter/test/deprecatedapi/swiper_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..828c0d03a22449f6f683532ff0b945b8eb38c668 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/swiper_api.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": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "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/deprecatedapi/system_prompt.ets b/ets2panda/linter/test/deprecatedapi/system_prompt.ets new file mode 100755 index 0000000000000000000000000000000000000000..af14dd835279282e24405ec1f4320cc49cd03c85 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_prompt.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. + */ + +import prompt, { ShowToastOptions } from '@system.prompt'; + +class A { + private options: ShowToastOptions = { // error + message: 'Message Info', // error + duration: 2000, // error + bottom: 10 // error + } + + showToast() { + prompt.showToast(this.options); + } +} + +export default new A() diff --git a/ets2panda/linter/test/deprecatedapi/system_prompt.ets.args.json b/ets2panda/linter/test/deprecatedapi/system_prompt.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_prompt.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/deprecatedapi/system_prompt.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/system_prompt.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_prompt.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/deprecatedapi/system_prompt.ets.json b/ets2panda/linter/test/deprecatedapi/system_prompt.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_prompt.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/deprecatedapi/system_router.ets b/ets2panda/linter/test/deprecatedapi/system_router.ets new file mode 100755 index 0000000000000000000000000000000000000000..fd53ea0ce38981d75b29b98e0b2de27ed12785b7 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_router.ets @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router, { + BackRouterOptions, + DisableAlertBeforeBackPageOptions, + EnableAlertBeforeBackPageOptions, RouterOptions, RouterState } from '@system.router'; + +class K { + private router: RouterOptions = { + uri: 'pages/routerpage2/routerpage2', + params: { // error + data1: 'message', + data2: { + data3: [123, 456, 789] + } + } + } + + private options: BackRouterOptions = { + uri: 'pages/detail/detail', // error + params: { // error + data1: 'message' + } + } + + getState() { + let page: RouterState = router.getState(); // error + console.log('current index = ' + page.index); // error + console.log('current name = ' + page.name); // error + console.log('current path = ' + page.path); // error + } + + pushPage() { + router.push(this.router); // error + } + + defaultBack() { + router.back(this.options); // error + } +} + +export default new K() + +class L { + private options: EnableAlertBeforeBackPageOptions = { + message: 'Message Info', + success: () => { + console.log('success'); + }, + cancel: () => { // error + console.log('cancel'); + }, + complete: () => { // error + console.log('complete'); + } + } + + enableAlertBeforeBackPage() { + router.enableAlertBeforeBackPage(this.options); + } +} + +class M { + enableAlertBeforeBackPage() { + router.enableAlertBeforeBackPage({ + message: 'Message Info', + success: () => { // error + console.log('success'); + }, + cancel: () => { + console.log('cancel'); + } + }); + } +} + +class Z { + private options: DisableAlertBeforeBackPageOptions = { // error + success: () => { + console.log('success'); + }, + cancel: () => { + console.log('cancel'); + } + } + + disableAlertBeforeBackPage() { + router.disableAlertBeforeBackPage(this.options); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/system_router.ets.args.json b/ets2panda/linter/test/deprecatedapi/system_router.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_router.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/deprecatedapi/system_router.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/system_router.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..bc7f37b6ed6a7d55e4bb110bda7f253f21db8c88 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_router.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": 24, + "column": 13, + "endLine": 24, + "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": 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": 34, + "column": 13, + "endLine": 34, + "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/deprecatedapi/system_router.ets.json b/ets2panda/linter/test/deprecatedapi/system_router.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..bc7f37b6ed6a7d55e4bb110bda7f253f21db8c88 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/system_router.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": 24, + "column": 13, + "endLine": 24, + "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": 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": 34, + "column": 13, + "endLine": 34, + "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/deprecatedapi/temporary_api.ets b/ets2panda/linter/test/deprecatedapi/temporary_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..014b717110d37d6683ece1956e966f06832c080a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/temporary_api.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 {PanelType} from './sdk/api/panel' + +@@Entry +@Component +struct WrapContentPanelExample { + @State isVisible: boolean = true + build() { + Column() { + Panel(this.isVisible) + .type(PanelType.Temporary) // error + } + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/temporary_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/temporary_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/temporary_api.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/deprecatedapi/temporary_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/temporary_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..e534260a3e278e602efd63462f1f0681a94a76b4 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/temporary_api.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": 17, + "endColumn": 2, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 22, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelType\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 23, + "endLine": 24, + "endColumn": 32, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"Temporary\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/temporary_api.ets.json b/ets2panda/linter/test/deprecatedapi/temporary_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/temporary_api.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/deprecatedapi/text_input.ets b/ets2panda/linter/test/deprecatedapi/text_input.ets new file mode 100644 index 0000000000000000000000000000000000000000..34ea448f8453d32505d6209f0535bbc998a9f1ab --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_input.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. + */ + +@Entry +@Component +struct TextInputExample { + controller: TextInputController = new TextInputController(); + + build() { + Column() { + TextInput({ controller: this.controller }) + .onEditChanged((isEditing: boolean) => { //error + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/text_input.ets.args.json b/ets2panda/linter/test/deprecatedapi/text_input.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_input.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/deprecatedapi/text_input.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/text_input.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..dd029d72759d079651eeae7e5aef81800af40361 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_input.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": 19, + "column": 41, + "endLine": 19, + "endColumn": 60, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 15, + "endLine": 19, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextInputController\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 41, + "endLine": 19, + "endColumn": 60, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextInputController\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextInput\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/text_input.ets.json b/ets2panda/linter/test/deprecatedapi/text_input.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_input.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/deprecatedapi/text_picker.ets b/ets2panda/linter/test/deprecatedapi/text_picker.ets new file mode 100644 index 0000000000000000000000000000000000000000..9cf5d2196f51eb2e7d1c6fd4bec01f98cd79815c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_picker.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. + */ + +@Entry +@Component +struct TextPickerExample { + private select: number = 1; + private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4']; + + + build() { + Column() { + Button("TextPickerDialog") + .margin(20) + .onClick(() => { + TextPickerDialog.show() //error + }) + + TextPicker({ + range: this.fruits, + selected: this.select, + value: this.fruits[this.select] + }).onAccept(()=> {}) //error + .onCancel(()=> {}) //error + + }.width('100%').height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/text_picker.ets.args.json b/ets2panda/linter/test/deprecatedapi/text_picker.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_picker.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/deprecatedapi/text_picker.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/text_picker.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a20dae643a57c231e3e452314b9ad9c6f42c9097 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_picker.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": 34, + "column": 28, + "endLine": 34, + "endColumn": 39, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextPickerDialog\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextPicker\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/text_picker.ets.json b/ets2panda/linter/test/deprecatedapi/text_picker.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/text_picker.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/deprecatedapi/wrap_content_api.ets b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets new file mode 100755 index 0000000000000000000000000000000000000000..34cec151b3183d52dd3fa924a9f668d9f89b5698 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/wrap_content_api.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 {PanelHeight} from './sdk/api/panel' + +@@Entry +@Component +struct WrapContentPanelExample { + @State isVisible: boolean = true + build() { + Column() { + Panel(this.isVisible) + .height(PanelHeight.WRAP_CONTENT) //error + } + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.args.json b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/wrap_content_api.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/deprecatedapi/wrap_content_api.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..65983ca6efc6dee25af56f1f500f5f0abd3f5d66 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/wrap_content_api.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": 17, + "endColumn": 2, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 15, + "endLine": 24, + "endColumn": 26, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"PanelHeight\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 27, + "endLine": 24, + "endColumn": 39, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"WRAP_CONTENT\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 4, + "endLine": 20, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Panel\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.json b/ets2panda/linter/test/deprecatedapi/wrap_content_api.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/wrap_content_api.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/deprecatedapi/xcomponent.ets b/ets2panda/linter/test/deprecatedapi/xcomponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..89b2897eecb25d473319c2121b9a708d13beeb8b --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/xcomponent.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. + */ + +@Entry +@Component +struct PreviewArea { + xcomponentController: XComponentController = new XComponentController() + build() { + Row() { + XComponent({ + id: 'xcomponent', + type: 'type', + controller: this.xcomponentController + }) + .onLoad(() => { + this.xcomponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080}); //error + }) + } + .backgroundColor(Color.Black) + .position({x: 0, y: 48}) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/xcomponent.ets.args.json b/ets2panda/linter/test/deprecatedapi/xcomponent.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/xcomponent.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/deprecatedapi/xcomponent.ets.arkts2.json b/ets2panda/linter/test/deprecatedapi/xcomponent.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9314e0e8f99ab9a0d2f4394900fd8734099c230d --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/xcomponent.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": 19, + "column": 52, + "endLine": 19, + "endColumn": 72, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 6, + "endLine": 32, + "endColumn": 14, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 25, + "endLine": 19, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponentController\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 52, + "endLine": 19, + "endColumn": 72, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponentController\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"XComponent\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/deprecatedapi/xcomponent.ets.json b/ets2panda/linter/test/deprecatedapi/xcomponent.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/deprecatedapi/xcomponent.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/interop/binary_operation_js_obj.ets b/ets2panda/linter/test/interop/binary_operation_js_obj.ets old mode 100755 new mode 100644 index 29bfa417e57a9375c0c37fa471bf0fa9b52f0080..472ad5669d75bba44ac209e2e148c3b4570a1a0e --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets @@ -12,8 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' -import {foo} from "./binary_operation_js_obj_js" +import {foo,m,n} from "./binary_operation_js_obj_js" let a = foo.a let b = foo.b a + b @@ -21,4 +20,24 @@ a - b a * b a / b a % b -a ** b \ No newline at end of file +a ** b + +m + n +m % n +m ** n + +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/binary_operation_js_obj.ets.args.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json index 3318ebbbcfd0ce90dc5f69df69452a3201e4204d..b13bb90d5b5f6d3dc5f0d054663eeba637fcc7dd 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json @@ -1,21 +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" - } -} +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT 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 old mode 100755 new mode 100644 index cf8ab0e5ee0d29567a66579c525bfcff6284988e..39a05cb8694b6c8153ba18282398a22115fa441d --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json @@ -15,29 +15,19 @@ ], "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, + "line": 15, "column": 1, - "endLine": 16, - "endColumn": 49, + "endLine": 15, + "endColumn": 53, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 17, + "line": 16, "column": 9, - "endLine": 17, + "endLine": 16, "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", @@ -49,16 +39,16 @@ "column": 9, "endLine": 17, "endColumn": 14, - "problem": "InteropJsObjectUsage", + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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, + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 2, "problem": "BinaryOperations", "suggest": "", "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", @@ -66,43 +56,263 @@ }, { "line": 18, - "column": 9, + "column": 5, "endLine": 18, - "endColumn": 14, - "problem": "InteropObjectProperty", + "endColumn": 6, + "problem": "BinaryOperations", "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 18, - "column": 9, - "endLine": 18, - "endColumn": 14, - "problem": "InteropJsObjectUsage", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "BinaryOperations", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 18, - "column": 9, - "endLine": 18, - "endColumn": 14, + "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": 6, + "endLine": 23, + "endColumn": 7, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 5, + "problem": "ExponentOp", + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 6, "problem": "BinaryOperations", "suggest": "", "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 24, + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 6, + "endLine": 27, + "endColumn": 7, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, "column": 3, - "endLine": 24, + "endLine": 27, "endColumn": 5, "problem": "ExponentOp", "suggest": "", "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 5, + "problem": "ExponentOp", + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 11, + "endLine": 35, + "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": 41, + "column": 4, + "endLine": 41, + "endColumn": 6, + "problem": "ExponentOp", + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "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 old mode 100755 new mode 100644 index 39d941b73fa9f5a260bd97728a1c4e292919e08a..e69f9263e1ea1130b54db6a908b63b11361801fa --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json @@ -15,35 +15,34 @@ ], "result": [ { - "line": 16, + "line": 15, "column": 1, - "endLine": 16, - "endColumn": 49, - "problem": "ImportAfterStatement", + "endLine": 15, + "endColumn": 53, + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { "line": 16, - "column": 1, + "column": 9, "endLine": 16, - "endColumn": 49, - "problem": "InterOpImportJs", + "endColumn": 14, + "problem": "InteropObjectProperty", "autofix": [ - { - "start": 617, - "end": 665, - "replacementText": "" - }, { "start": 665, - "end": 665, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./binary_operation_js_obj_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" + "end": 670, + "replacementText": "foo.getProperty(\"a\")", + "line": 16, + "column": 9, + "endLine": 16, + "endColumn": 14 } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -54,9 +53,13 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 674, - "end": 679, - "replacementText": "foo.getPropertyByName(\"a\")" + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\")", + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14 } ], "suggest": "", @@ -64,92 +67,580 @@ "severity": "ERROR" }, { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 14, - "problem": "InteropJsObjectUsage", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 2, + "problem": "BinaryOperations", "autofix": [ { - "replacementText": "foo.getPropertyByName('a').toNumber()", - "start": 674, - "end": 679 + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 2 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 14, + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 6, "problem": "BinaryOperations", + "autofix": [ + { + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 6 + } + ], "suggest": "", "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 18, - "column": 9, - "endLine": 18, - "endColumn": 14, - "problem": "InteropObjectProperty", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "BinaryOperations", "autofix": [ { - "start": 688, - "end": 693, - "replacementText": "foo.getPropertyByName(\"b\")" + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 2 } ], "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 18, - "column": 9, - "endLine": 18, - "endColumn": 14, - "problem": "InteropJsObjectUsage", + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6, + "problem": "BinaryOperations", "autofix": [ { - "replacementText": "foo.getPropertyByName('b').toNumber()", - "start": 688, - "end": 693 + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 18, - "column": 9, - "endLine": 18, - "endColumn": 14, + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 665, + "end": 670, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7, "problem": "BinaryOperations", + "autofix": [ + { + "start": 679, + "end": 684, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7 + } + ], "suggest": "", "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 3, - "endLine": 24, + "endLine": 23, "endColumn": 5, "problem": "ExponentOp", "autofix": [ { "replacementText": "Math.pow(a, b)", - "start": 724, - "end": 730 + "start": 715, + "end": 721, + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 5 + } + ], + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 723, + "end": 724, + "replacementText": "m.toNumber()", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 727, + "end": 728, + "replacementText": "n.toNumber()", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 729, + "end": 730, + "replacementText": "m.toNumber()", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 733, + "end": 734, + "replacementText": "n.toNumber()", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 2, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 735, + "end": 736, + "replacementText": "m.toNumber()", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 6, + "endLine": 27, + "endColumn": 7, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 740, + "end": 741, + "replacementText": "n.toNumber()", + "line": 27, + "column": 6, + "endLine": 27, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 3, + "endLine": 27, + "endColumn": 5, + "problem": "ExponentOp", + "autofix": [ + { + "replacementText": "Math.pow(m, n)", + "start": 735, + "end": 741, + "line": 27, + "column": 3, + "endLine": 27, + "endColumn": 5 + } + ], + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 5, + "problem": "ExponentOp", + "autofix": [ + { + "replacementText": "Math.pow(x, y)", + "start": 782, + "end": 788, + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 5 + } + ], + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 791, + "end": 791, + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12 + }, + { + "start": 798, + "end": 798, + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 6, + "problem": "ExponentOp", + "autofix": [ + { + "replacementText": "Math.pow(x2, y2)", + "start": 873, + "end": 881, + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 6 } ], "suggest": "", "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 884, + "end": 889, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "BinaryOperations", + "autofix": [ + { + "start": 892, + "end": 897, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 884, + "end": 889, + "replacementText": "foo.getProperty(\"a\")", + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 892, + "end": 897, + "replacementText": "foo.getProperty(\"b\")", + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json index 24e48e6dcb622409f469756ff0b09fbb2879d9cc..e28baca176a2b17f328386775efec64717650b4b 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json @@ -15,13 +15,13 @@ ], "result": [ { - "line": 16, - "column": 1, - "endLine": 16, - "endColumn": 49, - "problem": "ImportAfterStatement", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "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/interop/binary_operation_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets index b8312ed47e269fe6e0cab7bd8dc9b4497db4bdf1..4ab35224f729634f5956af6e1c0720b54f3ec868 100644 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets @@ -12,15 +12,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./binary_operation_js_obj_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); - -let a = foo.getPropertyByName("a") -let b = foo.getPropertyByName("b") +import {foo,m,n} from "./binary_operation_js_obj_js" +let a = foo.getProperty("a") +let b = foo.getProperty("b") a + b a - b a * b a / b a % b -Math.pow(a, b) \ No newline at end of file +Math.pow(a, b) + +m.toNumber() + n.toNumber() +m.toNumber() % n.toNumber() +Math.pow(m.toNumber(), n.toNumber()) + +let x = 1, y = 2; +x + y; +x - y; +x % y; +Math.pow(x, y); + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +let bar: GeneratedObjectLiteralInterface_1 = { a: 1, b: 2 }; + +let x2 = bar.a, y2 = bar.b; +x2 + y2; +x2 - y2; +x2 % y2; +Math.pow(x2, y2); + +foo.getProperty("a").toNumber() + foo.getProperty("b").toNumber(); \ 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 index 2d5cf16415581dd7948488a6b9d733264bb45774..0f7384dffa2b6c6d565e67310f0736f6dfa48252 100644 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json @@ -14,11 +14,21 @@ "limitations under the License." ], "result": [ + { + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 53, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, { "line": 16, "column": 5, "endLine": 16, - "endColumn": 73, + "endColumn": 29, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,41 +38,51 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 56, + "endColumn": 29, "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", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 15, + "problem": "MathPow", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 35, - "problem": "AnyType", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 37, + "problem": "MathPow", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, { - "line": 26, + "line": 33, "column": 1, - "endLine": 26, + "endLine": 33, "endColumn": 15, "problem": "MathPow", "suggest": "", "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 45, + "endColumn": 17, + "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/interop/binary_operation_js_obj_js.js b/ets2panda/linter/test/interop/binary_operation_js_obj_js.js index aaf9c1dd4e9e4e7e46d0cf3efb92bb573817fde8..c8f9951bdacb9a6fd47ef3704d312293cb78ffd4 100755 --- a/ets2panda/linter/test/interop/binary_operation_js_obj_js.js +++ b/ets2panda/linter/test/interop/binary_operation_js_obj_js.js @@ -14,3 +14,5 @@ */ export let foo = {a: 1, b: 2} +export let m = 3 +export let n = 2 \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function.ets b/ets2panda/linter/test/interop/call_function.ets index b76d862f4a67e010fbb3cd04176ba255c400dab8..63596274071ecb6f425932990d09bc832f3c7736 100644 --- a/ets2panda/linter/test/interop/call_function.ets +++ b/ets2panda/linter/test/interop/call_function.ets @@ -1,19 +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' -import {foo,bar} from "./call_function_js" - -foo() -bar(123) \ No newline at end of file +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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,bar} from "./call_function_js" +import {a,b} from "./call_function_js" + +foo() +bar(123) + +//a(); +b(); diff --git a/ets2panda/linter/test/interop/call_function.ets.args.json b/ets2panda/linter/test/interop/call_function.ets.args.json index 9c3d9734324a7b8b9c89fa7f62dce43ac44888ca..d683e78822869ab7d4dca23d3cc629224baf1046 100644 --- a/ets2panda/linter/test/interop/call_function.ets.args.json +++ b/ets2panda/linter/test/interop/call_function.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/interop/call_function.ets.arkts2.json b/ets2panda/linter/test/interop/call_function.ets.arkts2.json index 7ab8a8de0ec9c79ca03a6256077c43dbcdeabacc..7d49040d1edd0dd59a4130fe6d0a6436dc541ece 100644 --- a/ets2panda/linter/test/interop/call_function.ets.arkts2.json +++ b/ets2panda/linter/test/interop/call_function.ets.arkts2.json @@ -15,35 +15,25 @@ ], "result": [ { - "line": 16, + "line": 15, "column": 1, - "endLine": 16, + "endLine": 15, "endColumn": 43, - "problem": "ImportAfterStatement", + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { "line": 16, "column": 1, "endLine": 16, - "endColumn": 43, + "endColumn": 39, "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": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, { "line": 18, "column": 1, @@ -59,16 +49,16 @@ "column": 1, "endLine": 19, "endColumn": 9, - "problem": "InteropJsObjectCallStaticFunc", + "problem": "CallJSFunction", "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { - "line": 19, + "line": 22, "column": 1, - "endLine": 19, - "endColumn": 9, + "endLine": 22, + "endColumn": 4, "problem": "CallJSFunction", "suggest": "", "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", diff --git a/ets2panda/linter/test/interop/call_function.ets.autofix.json b/ets2panda/linter/test/interop/call_function.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..23cae64d8fb73aa01b144d9908a74f1237182fa6 --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.ets.autofix.json @@ -0,0 +1,101 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 1, + "endLine": 15, + "endColumn": 43, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 39, + "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", + "autofix": [ + { + "start": 687, + "end": 692, + "replacementText": "foo.invoke()", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 6 + } + ], + "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", + "autofix": [ + { + "start": 693, + "end": 701, + "replacementText": "bar.invoke(ESValue.wrap(123))", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 4, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 710, + "end": 713, + "replacementText": "b.invoke()", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 4 + } + ], + "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/call_function.ets.json b/ets2panda/linter/test/interop/call_function.ets.json index 08b4bd7b56c82c9eeb61e1bd092388f21bb9f59a..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/call_function.ets.json +++ b/ets2panda/linter/test/interop/call_function.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function.ets.migrate.ets b/ets2panda/linter/test/interop/call_function.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcbc148413e962b9a36ff6b43409c74ba619a890 --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.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. + */ +import {foo,bar} from "./call_function_js" +import {a,b} from "./call_function_js" + +foo.invoke() +bar.invoke(ESValue.wrap(123)) + +//a(); +b.invoke(); diff --git a/ets2panda/linter/test/interop/call_function.ets.migrate.json b/ets2panda/linter/test/interop/call_function.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c9ca5e0d96fd9c8b231049bc0b25fc487020c4e1 --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.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": 15, + "column": 1, + "endLine": 15, + "endColumn": 43, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 39, + "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/call_function_js.js b/ets2panda/linter/test/interop/call_function_js.js index 1ca0a23aebf1d5ffa73f72c779aa2d87675ab0da..2a35cd0c1f7c9cb84e24dab16b70ec7dc44ca419 100644 --- a/ets2panda/linter/test/interop/call_function_js.js +++ b/ets2panda/linter/test/interop/call_function_js.js @@ -14,4 +14,6 @@ */ export function foo(){} -export function bar(a){} \ No newline at end of file +export function bar(a){} +export function a(){} +export function b(){} \ 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 index ee45f2bcf310af18a40e73daac122f063494253f..891ae57a57c60ed2252efb4a8f74c928702b2589 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets +++ b/ets2panda/linter/test/interop/call_object_methods.ets @@ -12,7 +12,6 @@ * 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.arkts2.json b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json index db5e5b5f975b37094e186a4cd0156697d9175b7d..9456012d7f65d2cc920933e3a0c0a6185344364a 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json @@ -15,19 +15,9 @@ ], "result": [ { - "line": 16, + "line": 15, "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, + "endLine": 15, "endColumn": 47, "problem": "InterOpImportJs", "suggest": "", @@ -35,19 +25,9 @@ "severity": "ERROR" }, { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 13, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 18, + "line": 17, "column": 1, - "endLine": 18, + "endLine": 17, "endColumn": 13, "problem": "InteropCallObjectMethods", "suggest": "", diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json index 5831cf051021f917ffd4bae670b8366c6b275fd1..38146c50105976ef7198ced9b96d9c56a8eb3aa7 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json @@ -15,53 +15,32 @@ ], "result": [ { - "line": 16, + "line": 15, "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, + "endLine": 15, "endColumn": 47, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 617, - "end": 663, - "replacementText": "" - }, - { - "start": 663, - "end": 663, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./call_object_methods_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, + "line": 17, "column": 1, - "endLine": 18, - "endColumn": 13, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 1, - "endLine": 18, + "endLine": 17, "endColumn": 13, "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 652, + "end": 664, + "replacementText": "foo.invokeMethod(\"bar\", ESValue.wrap(123))", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 13 + } + ], "suggest": "", "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.json b/ets2panda/linter/test/interop/call_object_methods.ets.json index 8866623ce527a677439958b81b87b48a69851ee5..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 68b5f0fb6ec187e516f776f78c8b881cd2f57741..10f763e3223da9dcfa0885a9765220b4ac37a2df 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets @@ -12,10 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./call_object_methods_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); +import { foo } from "./call_object_methods_js" - -foo.bar(123) +foo.invokeMethod("bar", ESValue.wrap(123)) diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json index eb6c6ba8e76491e7e89b0bf9c4a41b19de74bc7e..94a7c680a7bed414b3aac1b4c0da3972817f96d1 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json @@ -15,23 +15,13 @@ ], "result": [ { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 69, - "problem": "AnyType", + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 47, + "problem": "InterOpImportJs", "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)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/ignore_files/unique_types.ts b/ets2panda/linter/test/interop/ignore_files/unique_types.ts index 1c19752b632c2db52b8a99eee6213add566520d7..60cf239e961e8bc48fb661fd84822eb98ed45d71 100644 --- a/ets2panda/linter/test/interop/ignore_files/unique_types.ts +++ b/ets2panda/linter/test/interop/ignore_files/unique_types.ts @@ -13,24 +13,223 @@ * limitations under the License. */ -type SomeType = { - name: string, -} +// any 类型 +let any_var: any = 10; +any_var = "string"; +export {any_var} + +// unknown类型 +export let unknown_var:unknown = 10; + +// Symbol类型 +export let symbol_var: symbol = Symbol("description"); + +// Function类型 +export let function_var: Function = function() { + console.log("Hello, World!"); + return true; +}; -enum X { +//mixed enum +export enum enum_var { a = 0, b = '1', } -type UnionString = "A" | "B"; -type TemplateLiteralType = `${UnionString}_id`; +export class A { + static instance = new A(); +} -export let objectLiteralType: SomeType; -export let mixedEnumType: X; -export let intersectionType: SomeType & X; -export let templateLiteralType: TemplateLiteralType; +export interface B { + name:string +} -export function tsFunction() { - throw 123; -}; -export let stringType: string; +//用例一 +export function throw_number() { + throw 123; +} + +export function throw_string() { + throw "error"; +} + +export function throw_boolean() { + throw true; +} + +export function throw_bigint() { + throw 111n; +} + +export function throw_obj() { + throw { name:'error' }; +} + +export function throw_error() { + throw new Error("error"); +} + +export class SubError extends Error { + extraField: number = 123; + foo() { return 456; } +} + +export function throwErrorSubClass() { + throw new SubError(); +} +export function throwRangeError() { + throw new RangeError(); +} + +//用例二 +export class ObjectLiteralClass { + name:string = "" +} + +export interface ObjectLiteralInter { + name:string +} +//用例三 +//类装饰器 +export function MyClassDecorator(klass: Object) {} + +//属性装饰器 +export function propertyDecorator(target: Object, propertyKey: string) { + console.log(Property Decorator called on: ${target.constructor.name} with propertyKey: ${propertyKey}); +} + +//方法装饰器 +export function methodDecorator(target: Object, propertyKey: string , descriptor: PropertyDescriptor) { + console.log(Method Decorator called on: ${target.constructor.name} with propertyKey: ${propertyKey}); + descriptor.value = function (...args: any[]) { + console.log(Called: ${propertyKey} with, args); + return args[0] * 2; + }; + return descriptor; +} + +// 参数装饰器 +export function parameterDecorator(target: Object, propertyKey: string , parameterIndex: number) { + console.log(Parameter Decorator called on: ${target.constructor.name} with propertyKey: ${propertyKey} and parameterIndex: ${parameterIndex}); +} + +// 访问器装饰器 +export function accessorDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) { + const originalGet = descriptor.get; + const originalSet = descriptor.set; + + descriptor.get = function() { + console.log(Getter for ${propertyKey} called.); + return originalGet.apply(this); + }; + descriptor.set = function(value) { + console.log(Setter for ${propertyKey} called with value: ${value}); + originalSet.apply(this, [value]); + }; + return descriptor; +} + +// 装饰器工厂 +export function readonly1(isReadonly: boolean) { + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { + if (isReadonly) { + descriptor.writable = false; + } + }; +} + +export let num_boxed = new Number(123) +export let bool_boxed = new Boolean(true) +export let str_boxed = new String('hello') +export let bigint_boxed = BigInt(123n) + +export function ts_object_method(prx: any) { + Object.getOwnPropertyDescriptor(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib not undefined + Object.getOwnPropertyDescriptors(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 not {} + Object.getOwnPropertyNames(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 ["a"] + Object.hasOwn(prx, "a") // true + Object.isExtensible(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true + Object.isFrozen(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 false + Object.isSealed(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 false + Object.keys(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 ["a"] + Object.setPrototypeOf(prx, {}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib OK + Object.values(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-no-inferred-generic-params [1] + prx.hasOwnProperty("a") // true + prx.propertyIsEnumerable("a") // true +} + +export function ts_object_method_getOwnPropertyDescriptor(prx: any) { + return Object.getOwnPropertyDescriptor(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib not undefined +} +export function ts_object_method_getOwnPropertyDescriptors(prx: any) { + return Object.getOwnPropertyDescriptors(prx)// arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib not {} +} +export function ts_object_method_getOwnPropertyNames(prx: any) { + return Object.getOwnPropertyNames(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 ["a"] +} +export function ts_object_method_hasOwn(prx: any) { + return Object.hasOwn(prx, "a") // true +} +export function ts_object_method_isExtensible(prx: any) { + return Object.isExtensible(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib true +} +export function ts_object_method_isFrozen(prx: any) { + return Object.isFrozen(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib false +} + +export function ts_object_method_isSealed(prx: any) { + return Object.isSealed(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-limited-stdlib false +} + +export function ts_object_method_keys(prx: any) { + return Object.keys(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 3 ["a"] +} + +export function ts_object_method_setPrototypeOf(prx: any) { + return Object.setPrototypeOf(prx, {}) // arkts-limited-stdlib OK +} + +export function ts_object_method_values(prx: any) { + return Object.values(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 + arkts-no-inferred-generic-params [1] +} + +interface Iface { + a:number +} +export let interObj:Iface = {a:1} + +export function ts_reflect_method(prx: any) { + Reflect.apply(prx.getName, {a: 12}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 12 + Reflect.defineProperty(prx, 'newField', {value: 7}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true + Reflect.deleteProperty(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 true + Reflect.getOwnPropertyDescriptor(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 not undefined + Reflect.ownKeys(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 ['a'] + Reflect.isExtensible(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true + Reflect.set(prx, 'newField', 7) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true + Reflect.setPrototypeOf(prx, {}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} + +export function ts_reflect_method_apply(prx: any) { + Reflect.apply(prx.getName, {a: 12}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 12 +} +export function ts_reflect_method_defineProperty(prx: any) { + Reflect.defineProperty(prx, 'newField', {value: 7}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} +export function ts_reflect_method_deleteProperty(prx: any) { + Reflect.deleteProperty(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} +export function ts_reflect_method_getOwnPropertyDescriptor(prx: any) { + Reflect.getOwnPropertyDescriptor(prx, "a") // arkts-interop-ts2s-ts-object-on-static-instance * 2 not undefined +} +export function ts_reflect_method_ownKeys(prx: any) { + Reflect.ownKeys(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 ['a'] +} +export function ts_reflect_method_isExtensible(prx: any) { + Reflect.isExtensible(prx) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} +export function ts_reflect_method_set(prx: any) { + Reflect.set(prx, 'newField', 7) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} +export function ts_reflect_method_setPrototypeOf(prx: any) { + Reflect.setPrototypeOf(prx, {}) // arkts-interop-ts2s-ts-object-on-static-instance * 2 true +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ignore_files/unique_types2.ts b/ets2panda/linter/test/interop/ignore_files/unique_types2.ts new file mode 100644 index 0000000000000000000000000000000000000000..e915e9bb10b8a7abf3f4fdae9f26467d37d00f80 --- /dev/null +++ b/ets2panda/linter/test/interop/ignore_files/unique_types2.ts @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// any +let any_var: any = 10; +any_var = "string"; +export { any_var } + +// unknown +export let unknown_var: unknown = 10; + +// Symbol +export let symbol_var: symbol = Symbol("description"); + +// Function +export let function_var: Function = function () { + console.log("Hello, World!"); + return true; +}; + +// objectLiteral +export let objectLiteral_var: { x: number, y: string } = { x: 10, y: "hello" }; +export let objectLiteral_var2 = { x: 10, y: "hello" }; +export let objectLiteral_var3:{}; +export let objectLiteral_var32={}; +export let objectLiteral_var4 = { x: 1 }; +export function objectLiteral_var5() { + return { x: 1 }; +} +export function objectLiteral_var51(aa:{}):{}{ + return { x: 1 }; +} + +export class objectLiteral_var6 { + get() { return { a: '1' }; } + get2():{} { return {}; } + get3() { return {}; } + get4():{}|undefined {return; } + get1(): { x: number }|undefined { + return; + } + set(aa: { x: 1 }) { } + set3(aa: {}) { } + set1(aa: { x: 1 }|boolean) { } + set2(aa: { x: 1,y: string }|boolean,bb:string) { } +} +// enum +export enum enum_var { + a = 0, + b = '1', +} + +// function type +export type func_type = (arg: number) => string; +export type func_type2 = {(arg: number): string}; + +// Construct signature +export let constructor_type: { new(name: string): { name: string } } = class { + constructor(public name: string) { } +}; + +// Index Signature +let objIndexSignature_var: { [index: number]: string } = {}; +objIndexSignature_var[0] = "zero"; +objIndexSignature_var[1] = "one"; +export { objIndexSignature_var } + +// Intersection +interface TypeA { + a: number; +} +interface TypeB { + b: string; +} + +export let Intersection_obj: TypeA & TypeB = { a: 10, b: "hello" }; + +// keyof +export interface X { + a: number; + b: string; +} + +export type KeyOf_Type = keyof X; +export let de: KeyOf_Type; +export let key: keyof X; +export function keyFuns(){ + return key; +} +export class Keys{ + keys:keyof X; + set(x:keyof X|undefined){} + get():keyof X|void{} + get1(){ return this.keys} +} + +// typeof +let p = { x: 1, y: "" }; +export let typeOf_type = typeof p; +export let typeOf_type1: typeof p; +// let q: typeof p = { x: 2, y: "world" }; + +export let user = { name: "John", age: 25 }; + +export type SomeType = { + name: string, +} +//indexed access: type[index]。 +const MyArray = [{ name: "Alice", age: 15 }] +export type Person = typeof MyArray[number] +export let Person1 = MyArray[0] +type StringArray = string[]; +export type ElementType = StringArray[number]; +type Demo = { + id: number; + name: string; + address: { city: string; }; +}; +type NameType = Demo["name"]; +type CityType = Demo["address"]["city"]; +export type NameOrAddress =Demo["name" | "address"]; +export function getInfo(name:NameType){ + return name as CityType; +} +type Tuple = [string, number, boolean]; +type FirstElement = Tuple[0]; +type LastElement = Tuple[2]; +export class IndexAccess{ + par:Person; + set(city:CityType,NameOrAddr:NameOrAddress){} + get(name:NameType):Tuple|FirstElement|LastElement{ + return getInfo(name); + } +} +type UserKeys = keyof Demo; +export type UserValueTypes = Demo[UserKeys]; + +//Template Literal Types:${T}${U}... +type UnionString = "A" | "B"; +export type TemplateLiteralType =` ${UnionString}_id`; +type Direction = "up" | "down" | "left" | "right"; +type Action = "move" | "rotate"; +export type Commands = `${Action}_${Direction}`; +type PropEventNames = `${T}Changed`; +export type NameChanged = PropEventNames<"name">; +type Colors1 = "red" | "blue"; +type Sizes = "small" | "large"; +export type Variants = `${Colors1}_${Sizes}`; +type IsString = T extends string ? true : false; +export type Check = `${T}` extends string ? true : false; +export function testTemplateLiteralType(bb:Commands){ + let a :PropEventNames<"name">; +} + +export let objectLiteralType: SomeType; +export let mixedEnumType: X; +export let intersectionType: SomeType & X; +export let templateLiteralType: TemplateLiteralType|undefined; + +export function tsFunction() { }; +export let stringType: string; +export class Test{ + returnStr(){ + return stringType; + } +} +//conditional types:T extends U ? X : Y +type ExtractNumber = T extends number ? T : never; +export type NumbersOnly = ExtractNumber; +export type ReturnVal any> = + T extends (...args: any[]) => infer R ? R : never; +export type Num = ReturnVal<() => number>; + +//mapped types:{[K in KeyType]: TypeExpression} +type Readonly = { + readonly [K in keyof T]: T[K]; +}; +export type ReadonlyUser = Readonly; +export type Partial = { + [K in keyof T]?: T[K]; +}; +export type OptionalUser = Partial; +type Original = { + [key: string]: number; + name: string; +}; +export type Mapped = { + [K in keyof Original]: Original[K]; +}; + +export let sumType: { [index: number]: string ,temp:TemplateLiteralType,index:UserValueTypes} ; +//tool +type User = { + name: string; + age: number; + email: string; +}; +type Colors = 'red' | 'blue' | 'green' | 'yellow'; +// Pick +export type NameAndEmail = Pick; +// Omit +export type WithoutEmail = Omit; +// Exclude +export type PrimaryColors = Exclude; +// Extract +type Values = string | number | boolean | null; +export type PrimitiveValues = Extract; +// NonNullable +type Data = string | null | undefined; +export type CleanData = NonNullable; +// Parameters +function add(a: number, b: string): void { } +export type AddParams = Parameters; +// ConstructorParameters +class Per { + constructor(name: string, age: number) { } +} +export type PerParams = ConstructorParameters; +// ReturnType +function createUser(): { id: number; name: string } { + return { id: 1, name: 'Alice' }; +} +export type UserType = ReturnType; +// InstanceType +class Point { + x: number; + y: number; +} +export type PointInstance = InstanceType; +// NoInfer +type NoInfer = [T][T extends any ? 0 : never]; +export function identity(x: T, y: NoInfer): T { + return x; +} +// ThisParameterType +type getThis = (this: { name: string }) => void; +export type thisParameterType = ThisParameterType; +// OmitThisParameter +type GetThis = (this: { name: string }, x: number) => void; +export type WithoutThis = OmitThisParameter; +// ThisType +export type ClassThisType = ThisType<{ + getName(): string; +}>; +// Uppercase +type Greeting = 'hello'; +export type ShoutGreeting = Uppercase; +// Lowercase +export type QuietGreeting = Lowercase; +// Capitalize +export type CapitalizedWord = Capitalize; +// Uncapitalize +export type UncapitalizedWord = Uncapitalize; +export function getCapitalize(): Capitalize { + return 'Hello'; +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets old mode 100755 new mode 100644 index e1d4d726e42ed9cf3f7fa79d50e53f253d739e58..9d1ec94c5645af3a80526bed72513c2abe775a6b --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets @@ -12,10 +12,14 @@ * 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 + +foo.num++ +++foo.num +foo.num-- +--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 index 3318ebbbcfd0ce90dc5f69df69452a3201e4204d..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100755 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json @@ -1,21 +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" - } -} +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT 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 old mode 100755 new mode 100644 index 188523c143f3ab493bb3b4f0265a1bdce075661f..5bad488f024df4aa197090593f78d3744b78ad98 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json @@ -15,19 +15,9 @@ ], "result": [ { - "line": 16, + "line": 15, "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, + "endLine": 15, "endColumn": 52, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 5, - "endLine": 18, + "endLine": 17, "endColumn": 14, "problem": "InteropIncrementDecrement", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 5, - "endLine": 18, + "endLine": 17, "endColumn": 12, "problem": "InteropObjectProperty", "suggest": "", @@ -58,20 +48,20 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 12, - "problem": "InteropJsObjectUsage", + "endColumn": 14, + "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { "line": 18, - "column": 5, + "column": 7, "endLine": 18, - "endColumn": 12, - "problem": "BinaryOperations", + "endColumn": 14, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -86,112 +76,112 @@ }, { "line": 19, - "column": 7, + "column": 5, "endLine": 19, - "endColumn": 14, + "endColumn": 12, "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, + "line": 20, + "column": 5, + "endLine": 20, "endColumn": 14, - "problem": "InteropJsObjectUsage", + "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 7, - "endLine": 19, + "endLine": 20, "endColumn": 14, - "problem": "BinaryOperations", + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "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": 14, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 10, "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, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 8, "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", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 10, + "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 21, - "column": 5, - "endLine": 21, - "endColumn": 14, + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10, "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, + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 8, "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", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 10, + "problem": "InteropIncrementDecrement", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" } ] 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 old mode 100755 new mode 100644 index 4afb86a9323ee3ef2733e4dce39c5631a4cf024d..a1cbbe83681804cddd38d17118450601c696f4a2 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json @@ -15,58 +15,51 @@ ], "result": [ { - "line": 16, + "line": 15, "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, + "endLine": 15, "endColumn": 52, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 617, - "end": 668, - "replacementText": "" - }, - { - "start": 668, - "end": 668, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./increases_decreases_js_obj_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, + "line": 17, "column": 5, - "endLine": 18, + "endLine": 17, "endColumn": 14, "problem": "InteropIncrementDecrement", + "autofix": [ + { + "replacementText": "a = foo.getProperty(\"num\").toNumber()\nfoo.setProperty(num, a + 1)\na = a + 1\n", + "start": 673, + "end": 686, + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 14 + } + ], "suggest": "", "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 5, - "endLine": 18, + "endLine": 17, "endColumn": 12, "problem": "InteropObjectProperty", "autofix": [ { - "start": 690, - "end": 697, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 677, + "end": 684, + "replacementText": "foo.getProperty(\"num\")", + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 12 } ], "suggest": "", @@ -77,27 +70,42 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 12, - "problem": "InteropJsObjectUsage", + "endColumn": 14, + "problem": "InteropIncrementDecrement", "autofix": [ { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 690, - "end": 697 + "replacementText": "a = foo.getProperty(\"num\").toNumber()\na = a + 1\nfoo.setProperty(num, a)\n", + "start": 687, + "end": 700, + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 14 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { "line": 18, - "column": 5, + "column": 7, "endLine": 18, - "endColumn": 12, - "problem": "BinaryOperations", + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 693, + "end": 700, + "replacementText": "foo.getProperty(\"num\")", + "line": 18, + "column": 7, + "endLine": 18, + "endColumn": 14 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -106,21 +114,36 @@ "endLine": 19, "endColumn": 14, "problem": "InteropIncrementDecrement", + "autofix": [ + { + "replacementText": "a = foo.getProperty(\"num\").toNumber()\nfoo.setProperty(num, a - 1)\na = a - 1\n", + "start": 701, + "end": 714, + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 14 + } + ], "suggest": "", "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { "line": 19, - "column": 7, + "column": 5, "endLine": 19, - "endColumn": 14, + "endColumn": 12, "problem": "InteropObjectProperty", "autofix": [ { - "start": 706, - "end": 713, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 705, + "end": 712, + "replacementText": "foo.getProperty(\"num\")", + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 12 } ], "suggest": "", @@ -128,53 +151,83 @@ "severity": "ERROR" }, { - "line": 19, - "column": 7, - "endLine": 19, + "line": 20, + "column": 5, + "endLine": 20, "endColumn": 14, - "problem": "InteropJsObjectUsage", + "problem": "InteropIncrementDecrement", "autofix": [ { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 706, - "end": 713 + "replacementText": "a = foo.getProperty(\"num\").toNumber()\na = a - 1\nfoo.setProperty(num, a)\n", + "start": 715, + "end": 728, + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 14 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 7, - "endLine": 19, + "endLine": 20, "endColumn": 14, - "problem": "BinaryOperations", + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 721, + "end": 728, + "replacementText": "foo.getProperty(\"num\")", + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 14 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "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": 14, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 10, "problem": "InteropIncrementDecrement", + "autofix": [ + { + "replacementText": "let tmp_1 = foo.getProperty(\"num\").toNumber()\nfoo.setProperty(num, tmp_1 + 1)\ntmp_1 = tmp_1 + 1\n", + "start": 730, + "end": 739, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 10 + } + ], "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, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 8, "problem": "InteropObjectProperty", "autofix": [ { - "start": 718, - "end": 725, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 730, + "end": 737, + "replacementText": "foo.getProperty(\"num\")", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 8 } ], "suggest": "", @@ -182,53 +235,83 @@ "severity": "ERROR" }, { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 12, - "problem": "InteropJsObjectUsage", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 10, + "problem": "InteropIncrementDecrement", "autofix": [ { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 718, - "end": 725 + "replacementText": "let tmp_2 = foo.getProperty(\"num\").toNumber()\ntmp_2 = tmp_2 + 1\nfoo.setProperty(num, tmp_2)\n", + "start": 740, + "end": 749, + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 10 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 742, + "end": 749, + "replacementText": "foo.getProperty(\"num\")", + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 21, - "column": 5, - "endLine": 21, - "endColumn": 14, + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10, "problem": "InteropIncrementDecrement", + "autofix": [ + { + "replacementText": "let tmp_3 = foo.getProperty(\"num\").toNumber()\nfoo.setProperty(num, tmp_3 - 1)\ntmp_3 = tmp_3 - 1\n", + "start": 750, + "end": 759, + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10 + } + ], "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, + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 8, "problem": "InteropObjectProperty", "autofix": [ { - "start": 734, - "end": 741, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 750, + "end": 757, + "replacementText": "foo.getProperty(\"num\")", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 8 } ], "suggest": "", @@ -236,30 +319,45 @@ "severity": "ERROR" }, { - "line": 21, - "column": 7, - "endLine": 21, - "endColumn": 14, - "problem": "InteropJsObjectUsage", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 10, + "problem": "InteropIncrementDecrement", "autofix": [ { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 734, - "end": 741 + "replacementText": "let tmp_4 = foo.getProperty(\"num\").toNumber()\ntmp_4 = tmp_4 - 1\nfoo.setProperty(num, tmp_4)\n", + "start": 760, + "end": 769, + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 10 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 762, + "end": 769, + "replacementText": "foo.getProperty(\"num\")", + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json index cf493da1d6fe4df6133341a3e3a1db1489feb321..ca88f857e960b437dcf767c0ac40be998c8f1236 100755 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 6abfb3b85cda23d6f198d736c9508551ecedb40d..ec338cc5eb48e1225057b0eae997924e96cc2698 100644 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets @@ -12,12 +12,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./increases_decreases_js_obj_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); - +import {foo} from "./increases_decreases_js_obj_js" let a: number =0 -a = foo.getPropertyByName("num")++ -a = ++foo.getPropertyByName("num") -a = foo.getPropertyByName("num")-- -a = --foo.getPropertyByName("num") +a = foo.getProperty("num").toNumber() +foo.setProperty(num, a + 1) +a = a + 1 + +a = foo.getProperty("num").toNumber() +a = a + 1 +foo.setProperty(num, a) + +a = foo.getProperty("num").toNumber() +foo.setProperty(num, a - 1) +a = a - 1 + +a = foo.getProperty("num").toNumber() +a = a - 1 +foo.setProperty(num, a) + + +let tmp_1 = foo.getProperty("num").toNumber() +foo.setProperty(num, tmp_1 + 1) +tmp_1 = tmp_1 + 1 + +let tmp_2 = foo.getProperty("num").toNumber() +tmp_2 = tmp_2 + 1 +foo.setProperty(num, tmp_2) + +let tmp_3 = foo.getProperty("num").toNumber() +foo.setProperty(num, tmp_3 - 1) +tmp_3 = tmp_3 - 1 + +let tmp_4 = foo.getProperty("num").toNumber() +tmp_4 = tmp_4 - 1 +foo.setProperty(num, tmp_4) + diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json index 3cbe2b5da335c01a2bbfb1dcf277bfe1681fcbc7..c1eebeb25c56ef572edb41bc0480ef0fb51e8bab 100644 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json @@ -15,20 +15,50 @@ ], "result": [ { - "line": 16, + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 52, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, "column": 5, - "endLine": 16, - "endColumn": 76, + "endLine": 42, + "endColumn": 46, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 17, + "line": 46, "column": 5, - "endLine": 17, - "endColumn": 56, + "endLine": 46, + "endColumn": 46, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets b/ets2panda/linter/test/interop/instantiated_js_obj.ets index f24de83f1ac2aea42269962eaa365a8f430dd622..e4208df9fe3ba98ef73b31b1fe28bb5b78d21053 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets @@ -13,7 +13,6 @@ * limitations under the License. */ -'use static' import {Foo, Foo1} from "./instantiated_js_obj_js" class A { num: number = 1; diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json index 20dfb7a06a067f6e23a2c32e5c1ba8138c621478..34788bf22c6c7d7625f502ed8377546927783037 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json @@ -15,19 +15,9 @@ ], "result": [ { - "line": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 51, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 22, "column": 1, - "endLine": 23, + "endLine": 22, "endColumn": 13, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 1, - "endLine": 24, + "endLine": 23, "endColumn": 17, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -55,9 +45,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 1, - "endLine": 25, + "endLine": 24, "endColumn": 17, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -65,9 +55,9 @@ "severity": "ERROR" }, { - "line": 27, + "line": 26, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 15, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -75,9 +65,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 1, - "endLine": 28, + "endLine": 27, "endColumn": 11, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -85,9 +75,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 31, "column": 1, - "endLine": 32, + "endLine": 31, "endColumn": 16, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -95,9 +85,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 1, - "endLine": 33, + "endLine": 32, "endColumn": 23, "problem": "InstantiatedJsOjbect", "suggest": "", diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json index a71b9e42ad902ca36566fbc2bfa5a3c1638941d0..c33df87234470f5b89bc7e42e08bfc83ee01fe56 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json @@ -15,48 +15,30 @@ ], "result": [ { - "line": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 51, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 618, - "end": 668, - "replacementText": "" - }, - { - "start": 668, - "end": 668, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./instantiated_js_obj_js');\nlet Foo = GeneratedImportVar_1.getPropertyByName('Foo');\nlet Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1');\n" - } - ], "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 23, + "line": 22, "column": 1, - "endLine": 23, + "endLine": 22, "endColumn": 13, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 728, - "end": 740, - "replacementText": "Foo.instantiate(ESObject.wrap(123))" + "start": 715, + "end": 727, + "replacementText": "Foo.instantiate(ESValue.wrap(123))", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 13 } ], "suggest": "", @@ -64,16 +46,20 @@ "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 1, - "endLine": 24, + "endLine": 23, "endColumn": 17, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 741, - "end": 757, - "replacementText": "Foo.instantiate(ESObject.wrap('hello'))" + "start": 728, + "end": 744, + "replacementText": "Foo.instantiate(ESValue.wrap('hello'))", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 17 } ], "suggest": "", @@ -81,16 +67,20 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 1, - "endLine": 25, + "endLine": 24, "endColumn": 17, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 758, - "end": 774, - "replacementText": "Foo.instantiate(ESObject.wrap(new A()))" + "start": 745, + "end": 761, + "replacementText": "Foo.instantiate(ESValue.wrap(new A()))", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 17 } ], "suggest": "", @@ -98,16 +88,20 @@ "severity": "ERROR" }, { - "line": 27, + "line": 26, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 15, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 795, - "end": 809, - "replacementText": "Foo.instantiate(ESObject.wrap(a.num))" + "start": 782, + "end": 796, + "replacementText": "Foo.instantiate(ESValue.wrap(a.num))", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 15 } ], "suggest": "", @@ -115,16 +109,20 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 1, - "endLine": 28, + "endLine": 27, "endColumn": 11, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 810, - "end": 820, - "replacementText": "Foo.instantiate(ESObject.wrap(a))" + "start": 797, + "end": 807, + "replacementText": "Foo.instantiate(ESValue.wrap(a))", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 11 } ], "suggest": "", @@ -132,16 +130,20 @@ "severity": "ERROR" }, { - "line": 32, + "line": 31, "column": 1, - "endLine": 32, + "endLine": 31, "endColumn": 16, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 861, - "end": 876, - "replacementText": "Foo.instantiate(ESObject.wrap(test()))" + "start": 848, + "end": 863, + "replacementText": "Foo.instantiate(ESValue.wrap(test()))", + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 16 } ], "suggest": "", @@ -149,16 +151,20 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 1, - "endLine": 33, + "endLine": 32, "endColumn": 23, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 877, - "end": 899, - "replacementText": "Foo1.instantiate(ESObject.wrap(123), ESObject.wrap('hello'))" + "start": 864, + "end": 886, + "replacementText": "Foo1.instantiate(ESValue.wrap(123), ESValue.wrap('hello'))", + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 23 } ], "suggest": "", diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.json index ad8f5eb1ae4e1f2ec507367301510cbc9e65607a..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 3baba970a3a84124533b3ff37a6b09dfd8a566bd..7d2d20947a6900edc13698bf2412558277bc3753 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets @@ -13,24 +13,20 @@ * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./instantiated_js_obj_js'); -let Foo = GeneratedImportVar_1.getPropertyByName('Foo'); -let Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1'); - +import {Foo, Foo1} from "./instantiated_js_obj_js" class A { num: number = 1; constructor() { } } -Foo.instantiate(ESObject.wrap(123)) -Foo.instantiate(ESObject.wrap('hello')) -Foo.instantiate(ESObject.wrap(new A())) +Foo.instantiate(ESValue.wrap(123)) +Foo.instantiate(ESValue.wrap('hello')) +Foo.instantiate(ESValue.wrap(new A())) let a: A = new A(); -Foo.instantiate(ESObject.wrap(a.num)) -Foo.instantiate(ESObject.wrap(a)) +Foo.instantiate(ESValue.wrap(a.num)) +Foo.instantiate(ESValue.wrap(a)) function test(): number { return 1; } -Foo.instantiate(ESObject.wrap(test())) -Foo1.instantiate(ESObject.wrap(123), ESObject.wrap('hello')) \ No newline at end of file +Foo.instantiate(ESValue.wrap(test())) +Foo1.instantiate(ESValue.wrap(123), 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 index bb4772469b1dd697d47aeb3159530442609ad076..8ae4b51b2e860913274a052ebd930922bdafa5cc 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json @@ -15,33 +15,13 @@ ], "result": [ { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 69, - "problem": "AnyType", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 51, + "problem": "InterOpImportJs", "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)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets b/ets2panda/linter/test/interop/interop_convert_import.ets old mode 100755 new mode 100644 index 296d7bb3ed6204c3e6836a9274e9afd1ad8dffe1..ea40300e23fda4510e7c8a7ce069925a782daf1c --- a/ets2panda/linter/test/interop/interop_convert_import.ets +++ b/ets2panda/linter/test/interop/interop_convert_import.ets @@ -14,9 +14,28 @@ */ 'use static' - import {foo, foo2, foo3, foo4} from "./interop_convert_import_js.js" + 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 a: boolean = foo2.bool as boolean - let a: string = foo3.str as string - let a: bigint = foo4.big as bigint" \ No newline at end of file + 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"); diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.args.json b/ets2panda/linter/test/interop/interop_convert_import.ets.args.json index 88d4f72683443a60125bfe1c47f15ca10daecbfc..b023016d6bc3b2713d4e02b6f765940828db476b 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.args.json +++ b/ets2panda/linter/test/interop/interop_convert_import.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 + } \ 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 old mode 100755 new mode 100644 index ffc1d767e80fd403f30da3fb8a254b5eef434a61..cbd68cf1d7d71f186c0ba92c6e5ddbf2afc2200f --- a/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json @@ -1,188 +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": 2, - "endLine": 17, - "endColumn": 70, - "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": 70, - "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": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 18, - "endLine": 19, - "endColumn": 25, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 19, - "endLine": 20, - "endColumn": 40, - "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": 19, - "endLine": 20, - "endColumn": 28, - "problem": "InteropObjectProperty", - "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 19, - "endLine": 20, - "endColumn": 28, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 19, - "endLine": 20, - "endColumn": 28, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 18, - "endLine": 21, - "endColumn": 37, - "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": 18, - "endLine": 21, - "endColumn": 26, - "problem": "InteropObjectProperty", - "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 18, - "endLine": 21, - "endColumn": 26, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 18, - "endLine": 21, - "endColumn": 26, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 18, - "endLine": 22, - "endColumn": 37, - "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": 18, - "endLine": 22, - "endColumn": 26, - "problem": "InteropObjectProperty", - "suggest": "", - "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 18, - "endLine": 22, - "endColumn": 26, - "problem": "InteropJsObjectUsage", - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 18, - "endLine": 22, - "endColumn": 26, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": 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": 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": 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": 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": 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": 48, + "endLine": 25, + "endColumn": 53, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "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": 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": 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..b2c74f81c890e63815aa167967df4cb65c677408 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json @@ -0,0 +1,266 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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", + "autofix": [ + { + "start": 761, + "end": 778, + "replacementText": "foo.getProperty(\"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.getProperty(\"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": 20, + "column": 20, + "endLine": 20, + "endColumn": 41, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 799, + "end": 820, + "replacementText": "foo2.getProperty(\"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.getProperty(\"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": 21, + "column": 19, + "endLine": 21, + "endColumn": 38, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 840, + "end": 859, + "replacementText": "foo3.getProperty(\"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.getProperty(\"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": 22, + "column": 19, + "endLine": 22, + "endColumn": 38, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 879, + "end": 898, + "replacementText": "foo4.getProperty(\"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.getProperty(\"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": 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": 48, + "endLine": 25, + "endColumn": 53, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "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": 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": 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 index 1d059f0d382adbf11dac846f30473a60ba3985a2..98f171cc3203712fa3d9467dd6c831dca2dcd64a 100755 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.json @@ -1,28 +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": 70, - "problem": "ImportAfterStatement", - "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", - "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": 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..9897079cdcf633c5a3d8e1d9ac2bfe78b7a847c4 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.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. + */ + 'use static' + + import {foo, foo2, foo3, foo4, array_val, null_val, undefined_val} from "./interop_convert_import_js.js" + + let a: number = foo.getProperty("num").toNumber() + let a1: boolean = foo2.getProperty("bool").toBoolean() + let a2: string = foo3.getProperty("str").toString() + let a3: bigint = foo4.getProperty("big").toBigInt() + +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"); diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a0ef85502122c5b96c3670e75428957e13c8003e --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.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": 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": 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": 48, + "endLine": 25, + "endColumn": 53, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "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": 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": 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_js.js b/ets2panda/linter/test/interop/interop_convert_import_js.js index f3895baaa7f2e4cf2d75b9c4ecfc5a1c50879481..cce72a8fb7f192f91addc00968c283556c0d205f 100755 --- a/ets2panda/linter/test/interop/interop_convert_import_js.js +++ b/ets2panda/linter/test/interop/interop_convert_import_js.js @@ -16,4 +16,7 @@ export let foo = {name: 123} export let foo2 = {bool: true} export let foo3 = {str: '123'} -export let foo4 = {big: 123n} \ No newline at end of file +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 index 7fe09978d32180c20921249f108ba7cdcd3eea11..aebc647fbe87aa5df306caab6e04767cdd39fc9a 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets @@ -13,9 +13,12 @@ * limitations under the License. */ -'use static' -import {a, b} from "./interop_equality_judgment_js" +import {a, b, c, d} from "./interop_equality_judgment_js" a == b a != b a === b -a !== b \ No newline at end of file +a !== b +c.num1 == d.num1 +c.num1 != d.num2 +c.num1 === d.num1 +c.num1 !== d.num2 diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json index 916e1b51ca421151b76bc22d2ee1aa9b32f60213..24b5949ab2d6c71157d92449926b4160fda4868e 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json @@ -14,65 +14,175 @@ "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 + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 58, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "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": 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": 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": 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": 17, + "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": 7, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 11, + "endLine": 21, + "endColumn": 17, + "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": 17, + "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": 22, + "column": 1, + "endLine": 22, + "endColumn": 7, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 17, + "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": 18, + "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": 23, + "column": 1, + "endLine": 23, + "endColumn": 7, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 12, + "endLine": 23, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 18, + "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": 24, + "column": 1, + "endLine": 24, + "endColumn": 7, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 12, + "endLine": 24, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json index 9c6a9f3e3157abecbaa3c562d1777b0aac24a1f1..73d6eea5c8064980fd5c71ce5995ccb80999269c 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json @@ -15,35 +15,34 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, - "endColumn": 52, - "problem": "ImportAfterStatement", + "endLine": 16, + "endColumn": 58, + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { "line": 17, "column": 1, "endLine": 17, - "endColumn": 52, - "problem": "InterOpImportJs", + "endColumn": 7, + "problem": "InteropEqualityJudgment", "autofix": [ { - "start": 618, - "end": 669, - "replacementText": "" - }, - { - "start": 669, + "start": 663, "end": 669, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_equality_judgment_js');\nlet a = GeneratedImportVar_1.getPropertyByName('a');\nlet b = GeneratedImportVar_1.getPropertyByName('b');\n" + "replacementText": "a.areEqual(b)", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 7 } ], "suggest": "", - "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" }, { @@ -56,7 +55,11 @@ { "start": 670, "end": 676, - "replacementText": "a.areEqual(b)" + "replacementText": "!a.areEqual(b)", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 7 } ], "suggest": "", @@ -67,13 +70,17 @@ "line": 19, "column": 1, "endLine": 19, - "endColumn": 7, + "endColumn": 8, "problem": "InteropEqualityJudgment", "autofix": [ { "start": 677, - "end": 683, - "replacementText": "!a.areEqual(b)" + "end": 684, + "replacementText": "a.areStrictlyEqual(b)", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 8 } ], "suggest": "", @@ -88,9 +95,13 @@ "problem": "InteropEqualityJudgment", "autofix": [ { - "start": 684, - "end": 691, - "replacementText": "a.areStrictlyEqual(b)" + "start": 685, + "end": 692, + "replacementText": "!a.areStrictlyEqual(b)", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 8 } ], "suggest": "", @@ -101,18 +112,253 @@ "line": 21, "column": 1, "endLine": 21, - "endColumn": 8, + "endColumn": 17, "problem": "InteropEqualityJudgment", "autofix": [ { - "start": 692, + "start": 693, + "end": 709, + "replacementText": "c.getProperty(\"num1\").areEqual(d.getProperty(\"num1\"))", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 17 + } + ], + "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": 7, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 693, "end": 699, - "replacementText": "!a.areStrictlyEqual(b)" + "replacementText": "c.getProperty(\"num1\")", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 11, + "endLine": 21, + "endColumn": 17, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 703, + "end": 709, + "replacementText": "d.getProperty(\"num1\")", + "line": 21, + "column": 11, + "endLine": 21, + "endColumn": 17 + } + ], + "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": 17, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 710, + "end": 726, + "replacementText": "!c.getProperty(\"num1\").areEqual(d.getProperty(\"num2\"))", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 17 } ], "suggest": "", "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 7, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 710, + "end": 716, + "replacementText": "c.getProperty(\"num1\")", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 17, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 720, + "end": 726, + "replacementText": "d.getProperty(\"num2\")", + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 17 + } + ], + "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": 18, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 727, + "end": 744, + "replacementText": "c.getProperty(\"num1\").areStrictlyEqual(d.getProperty(\"num1\"))", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 7, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 727, + "end": 733, + "replacementText": "c.getProperty(\"num1\")", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 12, + "endLine": 23, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 738, + "end": 744, + "replacementText": "d.getProperty(\"num1\")", + "line": 23, + "column": 12, + "endLine": 23, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 18, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 745, + "end": 762, + "replacementText": "!c.getProperty(\"num1\").areStrictlyEqual(d.getProperty(\"num2\"))", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 7, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 745, + "end": 751, + "replacementText": "c.getProperty(\"num1\")", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 12, + "endLine": 24, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 756, + "end": 762, + "replacementText": "d.getProperty(\"num2\")", + "line": 24, + "column": 12, + "endLine": 24, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "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 index e48cf9a99b2e3b05e8a7816bda0738a37d257d25..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 50a1b8457ac0eebf8bbde78aaffa49985affc818..f0bdc4e3ea0e54767723b86fac1a5582629d621b 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets @@ -13,12 +13,12 @@ * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./interop_equality_judgment_js'); -let a = GeneratedImportVar_1.getPropertyByName('a'); -let b = GeneratedImportVar_1.getPropertyByName('b'); - +import {a, b, c, d} from "./interop_equality_judgment_js" a.areEqual(b) !a.areEqual(b) a.areStrictlyEqual(b) -!a.areStrictlyEqual(b) \ No newline at end of file +!a.areStrictlyEqual(b) +c.getProperty("num1").areEqual(d.getProperty("num1")) +!c.getProperty("num1").areEqual(d.getProperty("num2")) +c.getProperty("num1").areStrictlyEqual(d.getProperty("num1")) +!c.getProperty("num1").areStrictlyEqual(d.getProperty("num2")) diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json index 543f81469d9239369a6e95092f0cf13270314eae..1f0874db0ddfe681b007ec3fd09c2c1d15cab099 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json @@ -14,34 +14,54 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 58, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, { "line": 17, - "column": 5, + "column": 12, "endLine": 17, - "endColumn": 75, - "problem": "AnyType", + "endColumn": 13, + "problem": "InteropJsObjectExpandStaticInstance", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", "severity": "ERROR" }, { "line": 18, - "column": 5, + "column": 13, "endLine": 18, - "endColumn": 52, - "problem": "AnyType", + "endColumn": 14, + "problem": "InteropJsObjectExpandStaticInstance", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", "severity": "ERROR" }, { "line": 19, - "column": 5, + "column": 20, "endLine": 19, - "endColumn": 52, - "problem": "AnyType", + "endColumn": 21, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 22, + "problem": "InteropJsObjectExpandStaticInstance", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_equality_judgment_js.js b/ets2panda/linter/test/interop/interop_equality_judgment_js.js index 6461191d6871a2e1ead802773ac1e5cc635fc707..036eb5a333ca70de6dc450533377ff0d91d3a657 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment_js.js +++ b/ets2panda/linter/test/interop/interop_equality_judgment_js.js @@ -15,4 +15,12 @@ class A {} export let a = new A() -export let b = new A() \ No newline at end of file +export let b = new A() +export let c = { + num1:1, + num2:2, +} +export let d = { + num1: 1, + num2: 2, +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets b/ets2panda/linter/test/interop/interop_export_js_rules.ets index 5c9355e6c8b262dadd4a3da48bfcb5c7c4b631a7..3ab29fe81d60c2c7ec9f7526c8a5a1cc9ec24a8a 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' import { ff1 } from "./interop_import_js_rules_js" @@ -20,6 +19,6 @@ 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 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 index 6958168fef2a70000342107f7d5f2b5805c14fae..66fb88f85945924e8be0e83d90123507033f4c5d 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json @@ -14,8 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2", - "migrate": "--arkts-2" + "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 index 8aafb129daa0d9e56a4e5f754740dc1c83957296..827762e0bfdba111f7f6cec42ebcce46dea84cef 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json @@ -15,19 +15,9 @@ ], "result": [ { - "line": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 51, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 1, - "endLine": 19, + "endLine": 18, "endColumn": 13, "problem": "InteropJsObjectExport", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 20, "column": 1, - "endLine": 21, + "endLine": 20, "endColumn": 51, "problem": "InteropJsObjectExport", "suggest": "", @@ -55,14 +45,14 @@ "severity": "ERROR" }, { - "line": 23, + "line": 24, "column": 1, - "endLine": 23, - "endColumn": 57, - "problem": "InteropArkTs1ObjectExport", + "endLine": 24, + "endColumn": 59, + "problem": "InteropJsObjectExport", "suggest": "", - "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.json index 91f5b61ed193b5db1f2d82123a53ba9fe017a31c..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets.json +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.json @@ -1,28 +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": [ - { - "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" - } - ] -} + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES 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/interop/interop_import_js.ets b/ets2panda/linter/test/interop/interop_import_js.ets old mode 100755 new mode 100644 index 3325f1bdd99c47feb42c89a27bb2d2255338121a..a4c0b8fea69eeb2c1cb904f44aac79c764e47804 --- a/ets2panda/linter/test/interop/interop_import_js.ets +++ b/ets2panda/linter/test/interop/interop_import_js.ets @@ -13,11 +13,10 @@ * 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 * as tjs from "./interop_import_js_js"; import { Wiki, Dog as Doge } from './interop_import_js_js' \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json index 17f26fd8dcbe4b296c8ad46a6dbf16de2323964d..f8dbfb7b6c507c635f7e41fd8c93a7b1ee20432a 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json @@ -15,13 +15,13 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 38, - "problem": "ImportAfterStatement", + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -38,17 +38,7 @@ "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, + "endColumn": 64, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -58,17 +48,7 @@ "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, + "endColumn": 44, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -78,17 +58,7 @@ "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, + "endColumn": 57, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -98,17 +68,7 @@ "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, + "endColumn": 47, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -118,36 +78,6 @@ "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": "", diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json index 947b0ed85ee44445966768577e0e4cbe2756915a..f8dbfb7b6c507c635f7e41fd8c93a7b1ee20432a 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json @@ -15,13 +15,13 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 38, - "problem": "ImportAfterStatement", + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { @@ -30,18 +30,6 @@ "endLine": 17, "endColumn": 38, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 619, - "end": 656, - "replacementText": "" - }, - { - "start": 971, - "end": 971, - "replacementText": "let GeneratedImportVar_1 = ESObject.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" @@ -50,30 +38,8 @@ "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, + "endColumn": 64, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 657, - "end": 694, - "replacementText": "" - }, - { - "start": 971, - "end": 971, - "replacementText": "let GeneratedImportVar_2 = ESObject.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" @@ -82,30 +48,8 @@ "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, + "endColumn": 44, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 695, - "end": 758, - "replacementText": "" - }, - { - "start": 971, - "end": 971, - "replacementText": "let GeneratedImportVar_3 = ESObject.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" @@ -114,30 +58,8 @@ "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, + "endColumn": 57, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 759, - "end": 802, - "replacementText": "" - }, - { - "start": 971, - "end": 971, - "replacementText": "let GeneratedImportVar_4 = ESObject.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" @@ -146,30 +68,8 @@ "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, + "endColumn": 47, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 803, - "end": 859, - "replacementText": "" - }, - { - "start": 971, - "end": 971, - "replacementText": "let GeneratedImportVar_5 = ESObject.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" @@ -178,62 +78,8 @@ "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 = ESObject.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 = ESObject.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" diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.json b/ets2panda/linter/test/interop/interop_import_js.ets.json index c75509e775c31d463f6997a7c8d8ac7ee81ec2bd..ca88f857e960b437dcf767c0ac40be998c8f1236 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.json @@ -13,76 +13,5 @@ "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": 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": 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": 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": 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": 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": 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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets index fb72fa188216462a9e6d92325927aa9fd925021d..a4c0b8fea69eeb2c1cb904f44aac79c764e47804 100644 --- a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets @@ -13,28 +13,10 @@ * limitations under the License. */ -'use static' - - - - - - -let GeneratedImportVar_7 = ESObject.load('./interop_import_js_js'); -let Wiki = GeneratedImportVar_7.getPropertyByName('Wiki'); -let Doge = GeneratedImportVar_7.getPropertyByName('Dog'); -let GeneratedImportVar_6 = ESObject.load('./interop_import_js_js'); -let GeneratedImportVar_5 = ESObject.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 = ESObject.load('./interop_import_js_js'); -let myAaa = GeneratedImportVar_4.getPropertyByName('aaa'); -let GeneratedImportVar_3 = ESObject.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 = ESObject.load('../main/js_lib'); -let fjs = GeneratedImportVar_2.getPropertyByName('fjs'); -let GeneratedImportVar_1 = ESObject.load('../main/js_lib'); -let Cjs = GeneratedImportVar_1.getPropertyByName('Cjs'); +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 tjs from "./interop_import_js_js"; +import { Wiki, Dog as Doge } from './interop_import_js_js' \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json index c1173895c427bbbe366e24b9412139837b44971c..f8dbfb7b6c507c635f7e41fd8c93a7b1ee20432a 100644 --- a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json @@ -15,183 +15,73 @@ ], "result": [ { - "line": 23, - "column": 5, - "endLine": 23, - "endColumn": 67, - "problem": "AnyType", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 38, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 58, - "problem": "AnyType", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 38, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "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": 67, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 67, - "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", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 64, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 31, - "column": 5, - "endLine": 31, - "endColumn": 67, - "problem": "AnyType", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 44, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "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": 72, - "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": 59, - "problem": "AnyType", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 57, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 38, - "column": 5, - "endLine": 38, - "endColumn": 56, - "problem": "AnyType", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 47, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 39, - "column": 5, - "endLine": 39, + "line": 22, + "column": 1, + "endLine": 22, "endColumn": 59, - "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", + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets b/ets2panda/linter/test/interop/interop_import_js_compare.ets index 496fe91c554cc5de1e7fafcb58c00041a11234a9..bc8146310144db009331d834e1601f295b703c2b 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets @@ -13,7 +13,6 @@ * limitations under the License. */ -'use static' import {foo, m, n} from "./interop_import_js_compare_js" let a = foo.a 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 index e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.args.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.args.json @@ -1,5 +1,5 @@ { - "copyright": [ + "copyright": [ "Copyright (c) 2025 Huawei Device Co., Ltd.", "Licensed under the Apache License, Version 2.0 (the 'License');", "you may not use this file except in compliance with the License.", @@ -12,8 +12,10 @@ "WITHOUT 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 + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} 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 index 083e145c479c1f2226dcfe5ac02503f6b50970de..4c85c90e8eb8edb1cad73bfd9bb54231fa50922c 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json @@ -15,19 +15,9 @@ ], "result": [ { - "line": 18, + "line": 17, "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, + "endLine": 17, "endColumn": 57, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 9, - "endLine": 19, + "endLine": 18, "endColumn": 14, "problem": "InteropObjectProperty", "suggest": "", @@ -49,26 +39,6 @@ "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": 19, - "column": 9, - "endLine": 19, - "endColumn": 14, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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)", @@ -76,22 +46,22 @@ }, { "line": 20, - "column": 9, + "column": 1, "endLine": 20, - "endColumn": 14, - "problem": "InteropJsObjectUsage", + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { "line": 20, - "column": 9, + "column": 5, "endLine": 20, - "endColumn": 14, - "problem": "BinaryOperations", + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", "severity": "ERROR" }, { @@ -126,9 +96,9 @@ }, { "line": 22, - "column": 5, + "column": 6, "endLine": 22, - "endColumn": 6, + "endColumn": 7, "problem": "InterOpImportJsDataCompare", "suggest": "", "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", @@ -155,29 +125,9 @@ "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": 27, + "line": 26, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 2, "problem": "InterOpImportJsDataCompare", "suggest": "", @@ -185,9 +135,9 @@ "severity": "ERROR" }, { - "line": 27, + "line": 26, "column": 5, - "endLine": 27, + "endLine": 26, "endColumn": 6, "problem": "InterOpImportJsDataCompare", "suggest": "", @@ -195,29 +145,9 @@ "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": 12, - "endLine": 30, - "endColumn": 17, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 36, + "line": 35, "column": 11, - "endLine": 36, + "endLine": 35, "endColumn": 12, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -225,29 +155,9 @@ "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, + "line": 43, "column": 1, - "endLine": 44, + "endLine": 43, "endColumn": 6, "problem": "InterOpImportJsDataCompare", "suggest": "", @@ -255,9 +165,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 43, "column": 9, - "endLine": 44, + "endLine": 43, "endColumn": 14, "problem": "InterOpImportJsDataCompare", "suggest": "", @@ -265,9 +175,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 43, "column": 1, - "endLine": 44, + "endLine": 43, "endColumn": 6, "problem": "InteropObjectProperty", "suggest": "", @@ -275,54 +185,14 @@ "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": 1, - "endLine": 44, - "endColumn": 6, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 44, + "line": 43, "column": 9, - "endLine": 44, + "endLine": 43, "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" - }, - { - "line": 44, - "column": 9, - "endLine": 44, - "endColumn": 14, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..9ce9d4639f544b23bf547652fe1904f88e86fbb3 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json @@ -0,0 +1,394 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 57, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 672, + "end": 677, + "replacementText": "foo.getProperty(\"a\")", + "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": 19, + "column": 9, + "endLine": 19, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 686, + "end": 691, + "replacementText": "foo.getProperty(\"b\")", + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 14 + } + ], + "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": 2, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 672, + "end": 677, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 686, + "end": 691, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6 + } + ], + "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": 1, + "endLine": 21, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 672, + "end": 677, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2 + } + ], + "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", + "autofix": [ + { + "start": 686, + "end": 691, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6 + } + ], + "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", + "autofix": [ + { + "start": 672, + "end": 677, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2 + } + ], + "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": 6, + "endLine": 22, + "endColumn": 7, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 686, + "end": 691, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 22, + "column": 6, + "endLine": 22, + "endColumn": 7 + } + ], + "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", + "autofix": [ + { + "start": 672, + "end": 677, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2 + } + ], + "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", + "autofix": [ + { + "start": 686, + "end": 691, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 725, + "end": 726, + "replacementText": "m.toNumber()", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 729, + "end": 730, + "replacementText": "n.toNumber()", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 787, + "end": 787, + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12 + }, + { + "start": 794, + "end": 794, + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 881, + "end": 886, + "replacementText": "foo.getProperty(\"a\").toNumber()", + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 889, + "end": 894, + "replacementText": "foo.getProperty(\"b\").toNumber()", + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 881, + "end": 886, + "replacementText": "foo.getProperty(\"a\")", + "line": 43, + "column": 1, + "endLine": 43, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 889, + "end": 894, + "replacementText": "foo.getProperty(\"b\")", + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.json index 25d2c46ecd313256af4ef2245da60133617674c2..e28baca176a2b17f328386775efec64717650b4b 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.json @@ -15,19 +15,9 @@ ], "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, + "line": 35, "column": 11, - "endLine": 36, + "endLine": 35, "endColumn": 12, "problem": "ObjectLiteralNoContextType", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7bf6ba9ea8ef1604545e098d73730a63f130a566 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.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 {foo, m, n} from "./interop_import_js_compare_js" +let a = foo.getProperty("a") +let b = foo.getProperty("b") +a > b +a < b +a >= b +a <= b +a = 1 + +m.toNumber() > n.toNumber() +m = 1 + +let x = 1, y = 2; +x > y; +x < y; +x >= y; +x <= y; + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +let bar: GeneratedObjectLiteralInterface_1 = { a: 1, b: 2 }; + +let x2 = bar.a, y2 = bar.b; +x2 > y2; +x2 < y2; +x2 >= y2; +x2 <= y2; + +foo.getProperty("a").toNumber() > foo.getProperty("b").toNumber(); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..27f3d3c0d454d71d6ad5c5d374f723aa58558f6b --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.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": 1, + "endLine": 17, + "endColumn": 57, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets b/ets2panda/linter/test/interop/interop_import_js_index.ets index daf1403ab2b8397e96835718602982113a32a281..411f8c70a656a3989c7a2b9a0e8eccd769fd48f0 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets @@ -12,9 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -'use static' +import { ff3 } from "./interop_import_js_rules_js" import {foo} from "./interop_import_js_index_js" let arr = foo.arr arr[1] -arr[3] = 4 \ No newline at end of file +arr[3] = 4 + +let arr1 = ff3.arr +let len = arr1.length as number +for (let i = 0; i < arr1.length; ++i) { + console.log(arr1[i]+''); //error + let x = arr1[i] //error + arr1[i] = 0 //error + console.log(arr1[i]+''); //error +} + +for (let element of arr1) { //error + if (element == 8) { + console.log("hi"); + } +} 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 index 8049b299332196ac2e744813b9281aab97d25fc5..95e55d3f56eebd1644dfc0c4b2b7d629becdd0d5 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json @@ -15,19 +15,19 @@ ], "result": [ { - "line": 17, + "line": 15, "column": 1, - "endLine": 17, - "endColumn": 49, - "problem": "ImportAfterStatement", + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 49, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 11, - "endLine": 18, + "endLine": 17, "endColumn": 18, "problem": "InteropObjectProperty", "suggest": "", @@ -46,22 +46,22 @@ }, { "line": 18, - "column": 11, + "column": 1, "endLine": 18, - "endColumn": 18, - "problem": "InteropJsObjectUsage", + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 18, - "column": 11, + "column": 1, "endLine": 18, - "endColumn": 18, - "problem": "BinaryOperations", + "endColumn": 7, + "problem": "InterOpImportJsIndex", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" }, { @@ -69,40 +69,140 @@ "column": 1, "endLine": 19, "endColumn": 7, - "problem": "InteropJsObjectTraverseJsInstance", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 19, "column": 1, "endLine": 19, - "endColumn": 7, + "endColumn": 11, "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, + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 19, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 22, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 32, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24, "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, + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24, "problem": "InterOpImportJsIndex", "suggest": "", "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" + }, + { + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 12, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 16, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 34, + "endColumn": 2, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json index 7b4806fa65d8cc800a8efdb074903ce9fd3d7e6d..9653a8ed9cca6c51a2e5c5abb62a40b978aaa60d 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json @@ -15,48 +15,40 @@ ], "result": [ { - "line": 17, + "line": 15, "column": 1, - "endLine": 17, - "endColumn": 49, - "problem": "ImportAfterStatement", + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 49, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 619, - "end": 667, - "replacementText": "" - }, - { - "start": 667, - "end": 667, - "replacementText": "let GeneratedImportVar_1 = ESObject.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, + "line": 17, "column": 11, - "endLine": 18, + "endLine": 17, "endColumn": 18, "problem": "InteropObjectProperty", "autofix": [ { - "start": 678, - "end": 685, - "replacementText": "foo.getPropertyByName(\"arr\")" + "start": 714, + "end": 721, + "replacementText": "foo.getProperty(\"arr\")", + "line": 17, + "column": 11, + "endLine": 17, + "endColumn": 18 } ], "suggest": "", @@ -65,42 +57,144 @@ }, { "line": 18, - "column": 11, + "column": 1, "endLine": 18, - "endColumn": 18, - "problem": "InteropJsObjectUsage", + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 7, + "problem": "InterOpImportJsIndex", "autofix": [ { - "replacementText": "foo.getPropertyByName('arr')", - "start": 678, - "end": 685 + "start": 722, + "end": 728, + "replacementText": "arr.getProperty(1)", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 7 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" }, { - "line": 18, - "column": 11, - "endLine": 18, - "endColumn": 18, - "problem": "BinaryOperations", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 19, "column": 1, "endLine": 19, - "endColumn": 7, + "endColumn": 11, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 729, + "end": 739, + "replacementText": "arr.setProperty(3, ESValue.wrap(4))", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 19, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 752, + "end": 759, + "replacementText": "ff3.getProperty(\"arr\")", + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 22, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 770, + "end": 781, + "replacementText": "arr1.getProperty(\"length\")", + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 32, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 812, + "end": 823, + "replacementText": "arr1.getProperty(\"length\")", + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24, "problem": "InteropJsObjectTraverseJsInstance", "autofix": [ { - "replacementText": "arr.getPropertyByIndex(1).toNumber()", - "start": 686, - "end": 692 + "replacementText": "arr1.getProperty(i).toNumber()", + "start": 848, + "end": 855, + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24 } ], "suggest": "", @@ -108,16 +202,20 @@ "severity": "ERROR" }, { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 7, + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24, "problem": "InterOpImportJsIndex", "autofix": [ { - "start": 686, - "end": 692, - "replacementText": "arr.getPropertyByIndex(1)" + "start": 848, + "end": 855, + "replacementText": "arr1.getProperty(i)", + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 24 } ], "suggest": "", @@ -125,16 +223,20 @@ "severity": "ERROR" }, { - "line": 20, - "column": 1, - "endLine": 20, - "endColumn": 7, + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20, "problem": "InteropJsObjectTraverseJsInstance", "autofix": [ { - "replacementText": "arr.setPropertyByIndex(3, ESObject.wrap(4))", - "start": 693, - "end": 703 + "replacementText": "arr1.getProperty(i).toNumber()", + "start": 882, + "end": 889, + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20 } ], "suggest": "", @@ -142,21 +244,139 @@ "severity": "ERROR" }, { - "line": 20, - "column": 1, - "endLine": 20, - "endColumn": 11, + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20, "problem": "InterOpImportJsIndex", "autofix": [ { - "start": 693, - "end": 703, - "replacementText": "arr.setPropertyByIndex(3, ESObject.wrap(4))" + "start": 882, + "end": 889, + "replacementText": "arr1.getProperty(i)", + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 20 } ], "suggest": "", "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 12, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr1.setProperty(i, ESValue.wrap(0 //error\n))", + "start": 903, + "end": 914, + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 16, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 903, + "end": 914, + "replacementText": "arr1.setProperty(i, ESValue.wrap(0))", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr1.getProperty(i).toNumber()", + "start": 940, + "end": 947, + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 940, + "end": 947, + "replacementText": "arr1.getProperty(i)", + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 34, + "endColumn": 2, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "start": 970, + "end": 989, + "replacementText": "let tmp_1 = 0; tmp_1 < arr1.getProperty('length').toNumber(); ++tmp_1", + "line": 30, + "column": 1, + "endLine": 34, + "endColumn": 2 + }, + { + "start": 1008, + "end": 1015, + "replacementText": "arr1.getProperty(tmp_1).toNumber()", + "line": 30, + "column": 1, + "endLine": 34, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.json index 5619e69d7898491f1269e2a8a45cc426ed25574a..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 17caa7fd96a19dc2e316f05696f01dbed39136ea..21a6214b87b3910c8e589fdfe92e3e655b374c40 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets @@ -12,11 +12,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -'use static' -let GeneratedImportVar_1 = ESObject.load('./interop_import_js_index_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); +import { ff3 } from "./interop_import_js_rules_js" +import {foo} from "./interop_import_js_index_js" +let arr = foo.getProperty("arr") +arr.getProperty(1) +arr.setProperty(3, ESValue.wrap(4)) -let arr = foo.getPropertyByName("arr") -arr.getPropertyByIndex(1).toNumber() -arr.setPropertyByIndex(3, ESObject.wrap(4)) \ No newline at end of file +let arr1 = ff3.getProperty("arr") +let len = arr1.getProperty("length") as number +for (let i = 0; i < arr1.getProperty("length"); ++i) { + console.log(arr1.getProperty(i).toNumber()+''); //error + let x = arr1.getProperty(i).toNumber() //error + arr1.setProperty(i, ESValue.wrap(0 //error +)) //error + console.log(arr1.getProperty(i).toNumber()+''); //error +} + +for (let tmp_1 = 0; tmp_1 < arr1.getProperty('length').toNumber(); ++tmp_1) { //error + if (arr1.getProperty(tmp_1).toNumber() == 8) { + console.log("hi"); + } +} diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json index a9df6f95e72b69ed5927226f9a9f737c7d9f0e21..bc5a9efda1c70321cd41c703b92a3ef695e946bd 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json @@ -14,31 +14,51 @@ "limitations under the License." ], "result": [ + { + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "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": 5, "endLine": 17, - "endColumn": 73, + "endColumn": 33, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 18, + "line": 21, "column": 5, - "endLine": 18, - "endColumn": 56, + "endLine": 21, + "endColumn": 34, "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, + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 43, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets b/ets2panda/linter/test/interop/interop_import_js_rules.ets index 3b88109fc29630d3e6a092967366596f836c6936..d4c110abcf06cbcf3e2626c2640c866038692d3e 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets @@ -27,6 +27,7 @@ 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) {} @@ -65,3 +66,27 @@ 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 +} + +for (let element of arr) { + if (element == 8) { + console.log("hi"); + } +} 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 index ad917d5f3cfba972a2aeed3dad9107fe63332924..d309c364fa6b671ae658163d94e7a6aa296e690c 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json @@ -1,498 +1,498 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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": 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": 31, - "column": 5, - "endLine": 31, - "endColumn": 15, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": 5, - "endLine": 33, - "endColumn": 11, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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": 49, - "column": 11, - "endLine": 49, - "endColumn": 18, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": 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": 63, - "column": 1, - "endLine": 63, - "endColumn": 13, - "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": 1, - "endLine": 64, - "endColumn": 15, - "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": 16, - "endLine": 66, - "endColumn": 21, - "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": 67, - "column": 1, - "endLine": 67, - "endColumn": 16, - "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" - } - ] -} + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 32, + "column": 5, + "endLine": 32, + "endColumn": 15, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "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": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 1, + "endLine": 42, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "ArkTS1.2 cannot catch a non Error instance thrown from JS code (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "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": 50, + "column": 11, + "endLine": 50, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 11, + "endLine": 51, + "endColumn": 21, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 8, + "endLine": 64, + "endColumn": 12, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "WARNING" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "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": 65, + "column": 8, + "endLine": 65, + "endColumn": 14, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "WARNING" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "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": 68, + "column": 8, + "endLine": 68, + "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": 68, + "column": 1, + "endLine": 68, + "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": 80, + "column": 8, + "endLine": 80, + "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": 80, + "column": 1, + "endLine": 80, + "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": 81, + "column": 8, + "endLine": 81, + "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": 81, + "column": 1, + "endLine": 81, + "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": 84, + "column": 5, + "endLine": 84, + "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": 84, + "column": 5, + "endLine": 84, + "endColumn": 24, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 92, + "endColumn": 2, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json index ec42a706b85a55d583c0ad8f58a4ffcb21484f78..2590e69b496176ca24aa3bb990b3ffd2bc78c303 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json @@ -1,823 +1,727 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_1 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_2 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_3 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_4 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_5 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_6 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_7 = ESObject.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": 1038, - "end": 1038, - "replacementText": "let GeneratedImportVar_8 = ESObject.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": 31, - "column": 5, - "endLine": 31, - "endColumn": 15, - "problem": "InteropObjectProperty", - "autofix": [ - { - "start": 1044, - "end": 1054, - "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": 1044, - "end": 1054, - "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": 31, - "column": 5, - "endLine": 31, - "endColumn": 15, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": 1064, - "end": 1070, - "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": 1064, - "end": 1070, - "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": 5, - "endLine": 33, - "endColumn": 11, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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", - "autofix": [ - { - "start": 1290, - "end": 1297, - "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": 1290, - "end": 1297, - "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": 49, - "column": 11, - "endLine": 49, - "endColumn": 18, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 11, - "endLine": 50, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "arr.getPropertyByName('length').toNumber()", - "start": 1308, - "end": 1328, - "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": 1338, - "end": 1343, - "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": 52, - "column": 11, - "endLine": 52, - "endColumn": 17, - "problem": "InteropJsObjectTraverseJsInstance", - "autofix": [ - { - "replacementText": "arr.getPropertyByIndex(i).toNumber()", - "start": 1371, - "end": 1377, - "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": 1371, - "end": 1377, - "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, ESObject.wrap(0))", - "start": 1380, - "end": 1390, - "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": 1380, - "end": 1390, - "replacementText": "arr.setPropertyByIndex(i, ESObject.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": 63, - "column": 1, - "endLine": 63, - "endColumn": 13, - "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": 1, - "endLine": 64, - "endColumn": 15, - "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", - "autofix": [ - { - "start": 1528, - "end": 1534, - "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": 16, - "endLine": 66, - "endColumn": 21, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1535, - "end": 1540, - "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": 22, - "endLine": 66, - "endColumn": 26, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1541, - "end": 1545, - "replacementText": "c: number = 3;", - "line": 66, - "column": 22, - "endLine": 66, - "endColumn": 26 + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 32, + "column": 5, + "endLine": 32, + "endColumn": 15, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1098, + "end": 1108, + "replacementText": "foo.getProperty(\"isGood\")", + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "foo.getProperty('isGood').toBoolean()", + "start": 1098, + "end": 1108, + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "InterOpImportJsDataCompare", + "autofix": [ + { + "start": 1118, + "end": 1124, + "replacementText": "ff1.getProperty(\"f1\").toNumber()", + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1118, + "end": 1124, + "replacementText": "ff1.getProperty(\"f1\")", + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "ff1.getProperty('f1').toNumber()", + "start": 1118, + "end": 1124, + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 1, + "endLine": 42, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "ArkTS1.2 cannot catch a non Error instance thrown from JS code (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 8, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1289, + "end": 1294, + "replacementText": "ff4.invoke()", + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1344, + "end": 1351, + "replacementText": "ff3.getProperty(\"arr\")", + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 11, + "endLine": 51, + "endColumn": 21, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1362, + "end": 1372, + "replacementText": "arr.getProperty(\"length\")", + "line": 51, + "column": 11, + "endLine": 51, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.getProperty(i).toNumber()", + "start": 1425, + "end": 1431, + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1425, + "end": 1431, + "replacementText": "arr.getProperty(i)", + "line": 53, + "column": 11, + "endLine": 53, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.setProperty(i, ESValue.wrap(0))", + "start": 1434, + "end": 1444, + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1434, + "end": 1444, + "replacementText": "arr.setProperty(i, ESValue.wrap(0))", + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 8, + "endLine": 64, + "endColumn": 12, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "WARNING" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 13, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1545, + "end": 1557, + "replacementText": "handle.invoke(ESValue.wrap(foo2))", + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 8, + "endLine": 65, + "endColumn": 14, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "WARNING" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 15, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1558, + "end": 1572, + "replacementText": "handle.invoke(ESValue.wrap(lambda))", + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 8, + "endLine": 68, + "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": 68, + "column": 1, + "endLine": 68, + "endColumn": 16, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1601, + "end": 1616, + "replacementText": "expand.invoke(ESValue.wrap(new X()))", + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 8, + "endLine": 80, + "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": 80, + "column": 1, + "endLine": 80, + "endColumn": 14, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1753, + "end": 1766, + "replacementText": "expand.invoke(ESValue.wrap(testY))", + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 8, + "endLine": 81, + "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": 81, + "column": 1, + "endLine": 81, + "endColumn": 39, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1768, + "end": 1806, + "replacementText": "expand.invoke(ESValue.wrap({x: '1', y: \"hello\", z: false}))", + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 32, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1831, + "end": 1858, + "replacementText": "orange.getProperty(\"isVegetable1\").areStrictlyEqual(123)", + "line": 84, + "column": 5, + "endLine": 84, + "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": 84, + "column": 5, + "endLine": 84, + "endColumn": 24, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1831, + "end": 1850, + "replacementText": "orange.getProperty(\"isVegetable1\")", + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 92, + "endColumn": 2, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "start": 1882, + "end": 1900, + "replacementText": "let tmp_1 = 0; tmp_1 < arr.getProperty('length').toNumber(); ++tmp_1", + "line": 88, + "column": 1, + "endLine": 92, + "endColumn": 2 + }, + { + "start": 1910, + "end": 1917, + "replacementText": "arr.getProperty(tmp_1).toNumber()", + "line": 88, + "column": 1, + "endLine": 92, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 1, - "endLine": 67, - "endColumn": 16, - "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" - } - ] -} + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json index a3db4edec87910df49c7a5933852334694aba188..ab212bc3f3999cd0aab878e852fd6fdaad9d1c5f 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json @@ -1,98 +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" - } - ] + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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 index 31951e24a4d58862665252d17ce37482eb8f45ac..cef219665e794ef06e76275a89ed5e52a93e67b3 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules_js.js +++ b/ets2panda/linter/test/interop/interop_import_js_rules_js.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-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 @@ -35,3 +35,9 @@ 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 old mode 100755 new mode 100644 index eeb6eba253a044d2b496febe2251a3a8f4a1e59d..b8941c7ac57d8a483e829d2f30ae7460555a8495 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets @@ -13,7 +13,6 @@ * 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'; @@ -36,16 +35,16 @@ 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 + 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); +const age = typeof person.setAge(111); let person2 = typeof person class Object { code: string = "www" 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 old mode 100755 new mode 100644 index fa257d85ca304283a7f1f0361ccd59565b5dc5d2..7c4e6a76500b9170a5ded8606c59fa8fa2624186 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json @@ -15,20 +15,20 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 69, - "problem": "ImportAfterStatement", + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { "line": 17, "column": 1, "endLine": 17, - "endColumn": 69, + "endColumn": 54, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -38,36 +38,6 @@ "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": "", @@ -75,9 +45,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 20, "column": 1, - "endLine": 21, + "endLine": 20, "endColumn": 15, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -86,38 +56,8 @@ }, { "line": 21, - "column": 8, - "endLine": 21, - "endColumn": 15, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 8, - "endLine": 21, - "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": 22, - "column": 11, - "endLine": 22, - "endColumn": 18, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 22, "column": 11, - "endLine": 22, + "endLine": 21, "endColumn": 18, "problem": "CallJSFunction", "suggest": "", @@ -125,9 +65,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 1, - "endLine": 24, + "endLine": 23, "endColumn": 11, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -135,9 +75,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 1, - "endLine": 25, + "endLine": 24, "endColumn": 19, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -145,9 +85,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 8, - "endLine": 25, + "endLine": 24, "endColumn": 19, "problem": "LimitedVoidType", "suggest": "", @@ -156,28 +96,8 @@ }, { "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", - "severity": "ERROR" - }, - { - "line": 26, "column": 1, - "endLine": 26, + "endLine": 25, "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -185,9 +105,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 25, "column": 8, - "endLine": 26, + "endLine": 25, "endColumn": 20, "problem": "LimitedVoidType", "suggest": "", @@ -196,28 +116,8 @@ }, { "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", - "severity": "ERROR" - }, - { - "line": 27, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -225,9 +125,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 1, - "endLine": 28, + "endLine": 27, "endColumn": 17, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -235,9 +135,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 8, - "endLine": 28, + "endLine": 27, "endColumn": 17, "problem": "InteropObjectProperty", "suggest": "", @@ -246,28 +146,8 @@ }, { "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": 28, - "column": 8, - "endLine": 28, - "endColumn": 17, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 29, "column": 1, - "endLine": 29, + "endLine": 28, "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -275,9 +155,9 @@ "severity": "ERROR" }, { - "line": 30, + "line": 29, "column": 11, - "endLine": 30, + "endLine": 29, "endColumn": 20, "problem": "InteropObjectProperty", "suggest": "", @@ -285,29 +165,9 @@ "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": 30, - "column": 11, - "endLine": 30, - "endColumn": 20, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 31, "column": 23, - "endLine": 32, + "endLine": 31, "endColumn": 35, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -315,9 +175,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 1, - "endLine": 33, + "endLine": 32, "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -325,9 +185,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 8, - "endLine": 33, + "endLine": 32, "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -335,9 +195,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 34, "column": 21, - "endLine": 35, + "endLine": 34, "endColumn": 33, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -345,9 +205,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 35, "column": 11, - "endLine": 36, + "endLine": 35, "endColumn": 22, "problem": "InteropObjectProperty", "suggest": "", @@ -355,9 +215,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 36, "column": 12, - "endLine": 37, + "endLine": 36, "endColumn": 28, "problem": "InteropCallObjectMethods", "suggest": "", @@ -365,59 +225,39 @@ "severity": "ERROR" }, { - "line": 40, - "column": 12, - "endLine": 40, + "line": 42, + "column": 10, + "endLine": 42, "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": 12, - "endLine": 43, - "endColumn": 30, "problem": "LimitedVoidType", "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 43, - "column": 12, - "endLine": 43, - "endColumn": 30, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 24, + "line": 44, + "column": 3, + "endLine": 44, + "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": 12, - "endLine": 45, - "endColumn": 24, + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 22, "problem": "InstantiatedJsOjbect", "suggest": "", "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", "severity": "ERROR" }, { - "line": 48, + "line": 47, "column": 21, - "endLine": 48, + "endLine": 47, "endColumn": 39, "problem": "LimitedVoidType", "suggest": "", @@ -425,19 +265,9 @@ "severity": "ERROR" }, { - "line": 48, - "column": 21, - "endLine": 48, - "endColumn": 39, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 50, + "line": 49, "column": 7, - "endLine": 50, + "endLine": 49, "endColumn": 13, "problem": "InvalidIdentifier", "suggest": "", @@ -445,9 +275,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 61, "column": 5, - "endLine": 62, + "endLine": 61, "endColumn": 21, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -455,9 +285,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 61, "column": 12, - "endLine": 62, + "endLine": 61, "endColumn": 21, "problem": "InteropObjectProperty", "suggest": "", @@ -465,29 +295,9 @@ "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": 62, - "column": 12, - "endLine": 62, - "endColumn": 21, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 66, + "line": 65, "column": 28, - "endLine": 66, + "endLine": 65, "endColumn": 47, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -495,9 +305,9 @@ "severity": "ERROR" }, { - "line": 66, + "line": 65, "column": 35, - "endLine": 66, + "endLine": 65, "endColumn": 47, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -505,9 +315,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 69, "column": 1, - "endLine": 70, + "endLine": 69, "endColumn": 13, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -515,9 +325,9 @@ "severity": "ERROR" }, { - "line": 71, + "line": 70, "column": 1, - "endLine": 71, + "endLine": 70, "endColumn": 25, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -525,9 +335,9 @@ "severity": "ERROR" }, { - "line": 71, + "line": 70, "column": 8, - "endLine": 71, + "endLine": 70, "endColumn": 25, "problem": "InteropObjectProperty", "suggest": "", @@ -535,19 +345,9 @@ "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, + "line": 70, "column": 8, - "endLine": 71, + "endLine": 70, "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -555,9 +355,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 71, "column": 1, - "endLine": 72, + "endLine": 71, "endColumn": 30, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -565,29 +365,9 @@ "severity": "ERROR" }, { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 72, + "line": 71, "column": 8, - "endLine": 72, + "endLine": 71, "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", @@ -595,9 +375,9 @@ "severity": "ERROR" }, { - "line": 73, + "line": 72, "column": 1, - "endLine": 73, + "endLine": 72, "endColumn": 31, "problem": "InterOpImportJsForTypeOf", "suggest": "", @@ -605,9 +385,9 @@ "severity": "ERROR" }, { - "line": 73, + "line": 72, "column": 8, - "endLine": 73, + "endLine": 72, "endColumn": 31, "problem": "LimitedVoidType", "suggest": "", @@ -615,29 +395,9 @@ "severity": "ERROR" }, { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 73, + "line": 72, "column": 8, - "endLine": 73, + "endLine": 72, "endColumn": 20, "problem": "InstantiatedJsOjbect", "suggest": "", 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 old mode 100755 new mode 100644 index 3f09bf75b91cb922131c688a58002cc28a5a6b5e..a8fcf908863dbe6ff4a1ed9216f1f7b0d609344c --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json @@ -15,33 +15,21 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 1, - "endLine": 17, + "endLine": 16, "endColumn": 69, - "problem": "ImportAfterStatement", + "problem": "InterOpImportJs", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { "line": 17, "column": 1, "endLine": 17, - "endColumn": 69, + "endColumn": 54, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 619, - "end": 687, - "replacementText": "" - }, - { - "start": 796, - "end": 796, - "replacementText": "let GeneratedImportVar_1 = ESObject.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" - } - ], "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" @@ -50,77 +38,27 @@ "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": 688, - "end": 741, - "replacementText": "" - }, - { - "start": 796, - "end": 796, - "replacementText": "let GeneratedImportVar_2 = ESObject.load('./interop_import_js_js');\nlet Doge = GeneratedImportVar_2.getPropertyByName('Dog');\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": 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": 742, - "end": 796, - "replacementText": "" - }, - { - "start": 796, - "end": 796, - "replacementText": "let GeneratedImportVar_3 = ESObject.load('./interop_import_js_js');\nlet wiki = GeneratedImportVar_3.getPropertyByName('Wiki');\n" - } - ], "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 21, + "line": 20, "column": 1, - "endLine": 21, + "endLine": 20, "endColumn": 15, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 798, - "end": 812, - "replacementText": "myAaa.invoke().typeOf()" + "start": 785, + "end": 799, + "replacementText": "myAaa.invoke().typeOf()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 15 } ], "suggest": "", @@ -129,55 +67,40 @@ }, { "line": 21, - "column": 8, - "endLine": 21, - "endColumn": 15, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 8, - "endLine": 21, - "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": 22, - "column": 11, - "endLine": 22, - "endColumn": 18, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 22, "column": 11, - "endLine": 22, + "endLine": 21, "endColumn": 18, "problem": "CallJSFunction", + "autofix": [ + { + "start": 819, + "end": 826, + "replacementText": "myAaa.invoke()", + "line": 21, + "column": 11, + "endLine": 21, + "endColumn": 18 + } + ], "suggest": "", "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 1, - "endLine": 24, + "endLine": 23, "endColumn": 11, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 853, - "end": 863, - "replacementText": "Dog.typeOf()" + "start": 840, + "end": 850, + "replacementText": "Dog.typeOf()", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11 } ], "suggest": "", @@ -185,16 +108,20 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 1, - "endLine": 25, + "endLine": 24, "endColumn": 19, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 873, - "end": 891, - "replacementText": "Dog.invoke(ESObject.wrap('doge')).typeOf()" + "start": 860, + "end": 878, + "replacementText": "Dog.invoke(ESValue.wrap('doge')).typeOf()", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 19 } ], "suggest": "", @@ -202,9 +129,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 24, "column": 8, - "endLine": 25, + "endLine": 24, "endColumn": 19, "problem": "LimitedVoidType", "suggest": "", @@ -213,35 +140,19 @@ }, { "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 8, - "endLine": 25, - "endColumn": 19, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", - "severity": "ERROR" - }, - { - "line": 26, "column": 1, - "endLine": 26, + "endLine": 25, "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 901, - "end": 920, - "replacementText": "Doge.invoke(ESObject.wrap('doge')).typeOf()" + "start": 888, + "end": 907, + "replacementText": "Doge.invoke(ESValue.wrap('doge')).typeOf()", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 20 } ], "suggest": "", @@ -249,9 +160,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 25, "column": 8, - "endLine": 26, + "endLine": 25, "endColumn": 20, "problem": "LimitedVoidType", "suggest": "", @@ -260,35 +171,19 @@ }, { "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 8, - "endLine": 26, - "endColumn": 20, - "problem": "CallJSFunction", - "suggest": "", - "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", - "severity": "ERROR" - }, - { - "line": 27, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 930, - "end": 941, - "replacementText": "Wiki.typeOf()" + "start": 917, + "end": 928, + "replacementText": "Wiki.typeOf()", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 12 } ], "suggest": "", @@ -296,16 +191,20 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 1, - "endLine": 28, + "endLine": 27, "endColumn": 17, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 950, - "end": 966, - "replacementText": "Wiki.getPropertyByName('name').typeOf()" + "start": 937, + "end": 953, + "replacementText": "Wiki.getProperty('name').typeOf()", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 17 } ], "suggest": "", @@ -313,16 +212,20 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 8, - "endLine": 28, + "endLine": 27, "endColumn": 17, "problem": "InteropObjectProperty", "autofix": [ { - "start": 957, - "end": 966, - "replacementText": "Wiki.getPropertyByName(\"name\")" + "start": 944, + "end": 953, + "replacementText": "Wiki.getProperty(\"name\")", + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 17 } ], "suggest": "", @@ -331,42 +234,19 @@ }, { "line": 28, - "column": 8, - "endLine": 28, - "endColumn": 17, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "Wiki.getPropertyByName('name').toString()", - "start": 957, - "end": 966 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 8, - "endLine": 28, - "endColumn": 17, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 29, "column": 1, - "endLine": 29, + "endLine": 28, "endColumn": 12, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 975, - "end": 986, - "replacementText": "wiki.typeOf()" + "start": 962, + "end": 973, + "replacementText": "wiki.typeOf()", + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 12 } ], "suggest": "", @@ -374,16 +254,20 @@ "severity": "ERROR" }, { - "line": 30, + "line": 29, "column": 11, - "endLine": 30, + "endLine": 29, "endColumn": 20, "problem": "InteropObjectProperty", "autofix": [ { - "start": 1005, - "end": 1014, - "replacementText": "wiki.getPropertyByName(\"name\")" + "start": 992, + "end": 1001, + "replacementText": "wiki.getProperty(\"name\")", + "line": 29, + "column": 11, + "endLine": 29, + "endColumn": 20 } ], "suggest": "", @@ -391,43 +275,20 @@ "severity": "ERROR" }, { - "line": 30, - "column": 11, - "endLine": 30, - "endColumn": 20, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "wiki.getPropertyByName('name').toString()", - "start": 1005, - "end": 1014 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 11, - "endLine": 30, - "endColumn": 20, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 31, "column": 23, - "endLine": 32, + "endLine": 31, "endColumn": 35, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1049, - "end": 1061, - "replacementText": "ClassA.instantiate()" + "start": 1036, + "end": 1048, + "replacementText": "ClassA.instantiate()", + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 35 } ], "suggest": "", @@ -435,16 +296,20 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 1, - "endLine": 33, + "endLine": 32, "endColumn": 20, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1062, - "end": 1081, - "replacementText": "ClassA.instantiate().typeOf()" + "start": 1049, + "end": 1068, + "replacementText": "ClassA.instantiate().typeOf()", + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 20 } ], "suggest": "", @@ -452,16 +317,20 @@ "severity": "ERROR" }, { - "line": 33, + "line": 32, "column": 8, - "endLine": 33, + "endLine": 32, "endColumn": 20, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1069, - "end": 1081, - "replacementText": "ClassA.instantiate()" + "start": 1056, + "end": 1068, + "replacementText": "ClassA.instantiate()", + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 20 } ], "suggest": "", @@ -469,16 +338,20 @@ "severity": "ERROR" }, { - "line": 35, + "line": 34, "column": 21, - "endLine": 35, + "endLine": 34, "endColumn": 33, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1125, - "end": 1137, - "replacementText": "Person.instantiate()" + "start": 1112, + "end": 1124, + "replacementText": "Person.instantiate()", + "line": 34, + "column": 21, + "endLine": 34, + "endColumn": 33 } ], "suggest": "", @@ -486,16 +359,20 @@ "severity": "ERROR" }, { - "line": 36, + "line": 35, "column": 11, - "endLine": 36, + "endLine": 35, "endColumn": 22, "problem": "InteropObjectProperty", "autofix": [ { - "start": 1149, - "end": 1160, - "replacementText": "person.getPropertyByName(\"name\")" + "start": 1136, + "end": 1147, + "replacementText": "person.getProperty(\"name\")", + "line": 35, + "column": 11, + "endLine": 35, + "endColumn": 22 } ], "suggest": "", @@ -503,56 +380,51 @@ "severity": "ERROR" }, { - "line": 37, + "line": 36, "column": 12, - "endLine": 37, + "endLine": 36, "endColumn": 28, "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1159, + "end": 1175, + "replacementText": "person.invokeMethod(\"getName\")", + "line": 36, + "column": 12, + "endLine": 36, + "endColumn": 28 + } + ], "suggest": "", "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 40, - "column": 12, - "endLine": 40, + "line": 42, + "column": 10, + "endLine": 42, "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": 12, - "endLine": 43, - "endColumn": 30, "problem": "LimitedVoidType", "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 43, - "column": 12, - "endLine": 43, - "endColumn": 30, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 24, + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 22, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1352, - "end": 1371, - "replacementText": "Person.instantiate().typeOf()" + "start": 1325, + "end": 1344, + "replacementText": "Person.instantiate().typeOf()", + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 22 } ], "suggest": "", @@ -560,16 +432,20 @@ "severity": "ERROR" }, { - "line": 45, - "column": 12, - "endLine": 45, - "endColumn": 24, + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 22, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1359, - "end": 1371, - "replacementText": "Person.instantiate()" + "start": 1332, + "end": 1344, + "replacementText": "Person.instantiate()", + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 22 } ], "suggest": "", @@ -577,9 +453,9 @@ "severity": "ERROR" }, { - "line": 48, + "line": 47, "column": 21, - "endLine": 48, + "endLine": 47, "endColumn": 39, "problem": "LimitedVoidType", "suggest": "", @@ -587,19 +463,9 @@ "severity": "ERROR" }, { - "line": 48, - "column": 21, - "endLine": 48, - "endColumn": 39, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 50, + "line": 49, "column": 7, - "endLine": 50, + "endLine": 49, "endColumn": 13, "problem": "InvalidIdentifier", "suggest": "", @@ -607,16 +473,20 @@ "severity": "ERROR" }, { - "line": 62, + "line": 61, "column": 5, - "endLine": 62, + "endLine": 61, "endColumn": 21, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1729, - "end": 1745, - "replacementText": "wiki.getPropertyByName('name').typeOf()" + "start": 1701, + "end": 1717, + "replacementText": "wiki.getProperty('name').typeOf()", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 21 } ], "suggest": "", @@ -624,16 +494,20 @@ "severity": "ERROR" }, { - "line": 62, + "line": 61, "column": 12, - "endLine": 62, + "endLine": 61, "endColumn": 21, "problem": "InteropObjectProperty", "autofix": [ { - "start": 1736, - "end": 1745, - "replacementText": "wiki.getPropertyByName(\"name\")" + "start": 1708, + "end": 1717, + "replacementText": "wiki.getProperty(\"name\")", + "line": 61, + "column": 12, + "endLine": 61, + "endColumn": 21 } ], "suggest": "", @@ -641,43 +515,20 @@ "severity": "ERROR" }, { - "line": 62, - "column": 12, - "endLine": 62, - "endColumn": 21, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "wiki.getPropertyByName('name').toString()", - "start": 1736, - "end": 1745 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 62, - "column": 12, - "endLine": 62, - "endColumn": 21, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 66, + "line": 65, "column": 28, - "endLine": 66, + "endLine": 65, "endColumn": 47, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1834, - "end": 1853, - "replacementText": "ClassA.instantiate().typeOf()" + "start": 1806, + "end": 1825, + "replacementText": "ClassA.instantiate().typeOf()", + "line": 65, + "column": 28, + "endLine": 65, + "endColumn": 47 } ], "suggest": "", @@ -685,16 +536,20 @@ "severity": "ERROR" }, { - "line": 66, + "line": 65, "column": 35, - "endLine": 66, + "endLine": 65, "endColumn": 47, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1841, - "end": 1853, - "replacementText": "ClassA.instantiate()" + "start": 1813, + "end": 1825, + "replacementText": "ClassA.instantiate()", + "line": 65, + "column": 35, + "endLine": 65, + "endColumn": 47 } ], "suggest": "", @@ -702,16 +557,20 @@ "severity": "ERROR" }, { - "line": 70, + "line": 69, "column": 1, - "endLine": 70, + "endLine": 69, "endColumn": 13, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1874, - "end": 1886, - "replacementText": "myAaa.typeOf()" + "start": 1846, + "end": 1858, + "replacementText": "myAaa.typeOf()", + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 13 } ], "suggest": "", @@ -719,16 +578,20 @@ "severity": "ERROR" }, { - "line": 71, + "line": 70, "column": 1, - "endLine": 71, + "endLine": 70, "endColumn": 25, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1896, - "end": 1920, - "replacementText": "Person.instantiate().getPropertyByName('name').typeOf()" + "start": 1868, + "end": 1892, + "replacementText": "Person.instantiate().getProperty('name').typeOf()", + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 25 } ], "suggest": "", @@ -736,16 +599,20 @@ "severity": "ERROR" }, { - "line": 71, + "line": 70, "column": 8, - "endLine": 71, + "endLine": 70, "endColumn": 25, "problem": "InteropObjectProperty", "autofix": [ { - "start": 1903, - "end": 1920, - "replacementText": "new Person().getPropertyByName(\"name\")" + "start": 1875, + "end": 1892, + "replacementText": "new Person().getProperty(\"name\")", + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 25 } ], "suggest": "", @@ -753,33 +620,20 @@ "severity": "ERROR" }, { - "line": 71, - "column": 8, - "endLine": 71, - "endColumn": 25, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "new Person().getPropertyByName('name').toString()", - "start": 1903, - "end": 1920 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 71, + "line": 70, "column": 8, - "endLine": 71, + "endLine": 70, "endColumn": 20, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1903, - "end": 1915, - "replacementText": "Person.instantiate()" + "start": 1875, + "end": 1887, + "replacementText": "Person.instantiate()", + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 20 } ], "suggest": "", @@ -787,16 +641,20 @@ "severity": "ERROR" }, { - "line": 72, + "line": 71, "column": 1, - "endLine": 72, + "endLine": 71, "endColumn": 30, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1930, - "end": 1959, - "replacementText": "Person.instantiate().getPropertyByName('getName').invoke().typeOf()" + "start": 1902, + "end": 1931, + "replacementText": "Person.instantiate().invokeMethod(\"getName\").typeOf()", + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 30 } ], "suggest": "", @@ -804,36 +662,20 @@ "severity": "ERROR" }, { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 8, - "endLine": 72, - "endColumn": 30, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 72, + "line": 71, "column": 8, - "endLine": 72, + "endLine": 71, "endColumn": 20, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1937, - "end": 1949, - "replacementText": "Person.instantiate()" + "start": 1909, + "end": 1921, + "replacementText": "Person.instantiate()", + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 20 } ], "suggest": "", @@ -841,16 +683,20 @@ "severity": "ERROR" }, { - "line": 73, + "line": 72, "column": 1, - "endLine": 73, + "endLine": 72, "endColumn": 31, "problem": "InterOpImportJsForTypeOf", "autofix": [ { - "start": 1968, - "end": 1998, - "replacementText": "Person.instantiate().getPropertyByName('setAge').invoke(ESObject.wrap(22)).typeOf()" + "start": 1940, + "end": 1970, + "replacementText": "Person.instantiate().invokeMethod(\"setAge\", ESValue.wrap(22)).typeOf()", + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 31 } ], "suggest": "", @@ -858,9 +704,9 @@ "severity": "ERROR" }, { - "line": 73, + "line": 72, "column": 8, - "endLine": 73, + "endLine": 72, "endColumn": 31, "problem": "LimitedVoidType", "suggest": "", @@ -868,36 +714,20 @@ "severity": "ERROR" }, { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 8, - "endLine": 73, - "endColumn": 31, - "problem": "InteropCallObjectMethods", - "suggest": "", - "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", - "severity": "ERROR" - }, - { - "line": 73, + "line": 72, "column": 8, - "endLine": 73, + "endLine": 72, "endColumn": 20, "problem": "InstantiatedJsOjbect", "autofix": [ { - "start": 1975, - "end": 1987, - "replacementText": "Person.instantiate()" + "start": 1947, + "end": 1959, + "replacementText": "Person.instantiate()", + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 20 } ], "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json index b61974a218a0379e953f24d569b9397beafd431a..ca88f857e960b437dcf767c0ac40be998c8f1236 100755 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json @@ -13,36 +13,5 @@ "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" - } - ] + "result": [] } \ 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 index 5914b7dfda835278185754ae30358b9017ec6e0d..7ea829c3823acc35811d2abb65cb1d99fdd4b1c6 100644 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets @@ -13,49 +13,38 @@ * limitations under the License. */ -'use static' - - -let GeneratedImportVar_3 = ESObject.load('./interop_import_js_js'); -let wiki = GeneratedImportVar_3.getPropertyByName('Wiki'); -let GeneratedImportVar_2 = ESObject.load('./interop_import_js_js'); -let Doge = GeneratedImportVar_2.getPropertyByName('Dog'); -let GeneratedImportVar_1 = ESObject.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'); - +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'; myAaa.invoke().typeOf(); //error -let fun = myAaa(); +let fun = myAaa.invoke(); typeof fun; Dog.typeOf(); //error -Dog.invoke(ESObject.wrap('doge')).typeOf(); //error -Doge.invoke(ESObject.wrap('doge')).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.getProperty('name').typeOf() //error wiki.typeOf() //error -let val = wiki.getPropertyByName("name") +let val = wiki.getProperty("name") typeof val; const aClass:ClassA = ClassA.instantiate() ClassA.instantiate().typeOf() //error typeof aClass; let person:Person = Person.instantiate(); -let name =person.getPropertyByName("name") -let name2 =person.getName() +let name =person.getProperty("name") +let name2 =person.invokeMethod("getName") function getPersonInfo(){ - typeof person; - typeof person.getName(); - typeof name2; - typeof name; - typeof person.setAge(111); - typeof person; - Person.instantiate().typeOf(); //error + typeof person; + typeof person.getName(); + typeof name2; + typeof name; + typeof person.setAge(111); + typeof person; + Person.instantiate().typeOf(); //error } -const age = typeof person.setAge(111); +const age = typeof person.setAge(111); let person2 = typeof person class Object { code: string = "www" @@ -69,7 +58,7 @@ class Object { typeof location; } tips(){ - wiki.getPropertyByName('name').typeOf(); //error + wiki.getProperty('name').typeOf(); //error typeof age; typeof person2; typeof fun; @@ -78,6 +67,6 @@ class Object { } myAaa.typeOf(); //error -Person.instantiate().getPropertyByName('name').typeOf() //error -Person.instantiate().getPropertyByName('getName').invoke().typeOf() //error -Person.instantiate().getPropertyByName('setAge').invoke(ESObject.wrap(22)).typeOf() //error +Person.instantiate().getProperty('name').typeOf() //error +Person.instantiate().invokeMethod("getName").typeOf() //error +Person.instantiate().invokeMethod("setAge", ESValue.wrap(22)).typeOf() //error diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json index a2ce72e9414506a158aa975a040c644c962ce5b6..aafe9cdd57485a00e96f10b3eab005888cb2bd6b 100644 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json @@ -15,149 +15,99 @@ ], "result": [ { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 67, - "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": 67, - "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": 67, - "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", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 69, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 25, - "column": 5, - "endLine": 25, - "endColumn": 62, - "problem": "AnyType", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 54, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 26, - "column": 5, - "endLine": 26, - "endColumn": 56, - "problem": "AnyType", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 55, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" }, { - "line": 27, + "line": 21, "column": 5, - "endLine": 27, - "endColumn": 62, + "endLine": 21, + "endColumn": 25, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 28, + "line": 29, "column": 5, - "endLine": 28, - "endColumn": 58, + "endLine": 29, + "endColumn": 35, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 32, + "line": 35, "column": 5, - "endLine": 32, - "endColumn": 18, + "endLine": 35, + "endColumn": 37, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 40, + "line": 36, "column": 5, - "endLine": 40, - "endColumn": 41, + "endLine": 36, + "endColumn": 42, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 46, - "column": 5, - "endLine": 46, - "endColumn": 43, - "problem": "AnyType", + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 28, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { "line": 47, - "column": 5, + "column": 21, "endLine": 47, - "endColumn": 28, - "problem": "AnyType", + "endColumn": 39, + "problem": "LimitedVoidType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, { - "line": 60, + "line": 49, "column": 7, - "endLine": 60, + "endLine": 49, "endColumn": 13, "problem": "InvalidIdentifier", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets old mode 100755 new mode 100644 index 70554e5a8f408495ef89c1f78df89a93c90820b2..3aa24611b1453b4efbe69a0875f4b5e7194d0deb --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets @@ -12,11 +12,52 @@ * 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" +'use static' +import { foo, person, TestHelper, Machine, User, Person, Employee } from "./interop_not_have_property_js" foo.name foo.name = "456" person.age = 23 -person.male = [2, 3] \ No newline at end of file +person.male = [2, 3] +foo.age = 12 +if (foo.name = "456") { print("true") } + +let a = new foo() +a.age = 12 + +let test_helper = new TestHelper("TEST_INSTANTIATE_JS_OBJECT"); +test_helper.test(() => { + let machine = new Machine(); + return machine.name === "machine"; // arkts-interop-js2s-access-js-prop +}, "machine.name === 'machine'"); + +test_helper.test(() => { + let user = new User("Bob"); + return user.id === "Bob"; // arkts-interop-js2s-access-js-prop +}, "user.id === 'Bob'"); + +test_helper.test(() => { +let user = new User(10); +return user.id === 10;// arkts-interop-js2s-access-js-prop +}, "user.id === 10"); + +test_helper.test(() => { + let user = new User(123n); + return user.id === 123n; // arkts-interop-js2s-access-js-prop +}, "user.id === 123n"); + +test_helper.test(() => { + let user = new User(true); + return user.id === true;// arkts-interop-js2s-access-js-prop +}, "user.id === true"); + +test_helper.test(() => { + let machine = new Person("John", 10); + return machine.name === "machine"; // arkts-interop-js2s-access-js-prop +}, "machine.name === 'machine'"); + +test_helper.test(() => { + let employee = new Employee(); + return employee.name === "employee"; // arkts-interop-js2s-access-js-prop +}, "employee.name === 'employee'"); \ 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 old mode 100755 new mode 100644 index 62322a01ef9933939311eff4bec680950d783656..1bf895ab171664ecd9a1b33fd050c6b8453c8a97 --- 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 @@ -18,7 +18,7 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 59, + "endColumn": 106, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", @@ -28,7 +28,7 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 59, + "endColumn": 106, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", @@ -45,113 +45,383 @@ "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 1, - "endLine": 19, - "endColumn": 9, - "problem": "InteropJsObjectUsage", + "endLine": 20, + "endColumn": 17, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 19, + "line": 21, "column": 1, - "endLine": 19, - "endColumn": 9, - "problem": "BinaryOperations", + "endLine": 21, + "endColumn": 16, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 20, + "line": 22, "column": 1, - "endLine": 20, - "endColumn": 17, + "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": 20, + "line": 23, "column": 1, - "endLine": 20, - "endColumn": 9, - "problem": "InteropJsObjectUsage", + "endLine": 23, + "endColumn": 13, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 21, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 13, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 18, + "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": 21, - "endColumn": 16, + "endLine": 27, + "endColumn": 11, "problem": "InteropObjectProperty", "suggest": "", "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 21, + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 63, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 30, "column": 1, - "endLine": 21, - "endColumn": 11, - "problem": "InteropJsObjectUsage", + "endLine": 33, + "endColumn": 33, + "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 21, + "line": 31, + "column": 19, + "endLine": 31, + "endColumn": 32, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 12, + "endLine": 32, + "endColumn": 38, + "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": 32, + "column": 12, + "endLine": 32, + "endColumn": 24, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 35, "column": 1, - "endLine": 21, - "endColumn": 11, - "problem": "BinaryOperations", + "endLine": 38, + "endColumn": 24, + "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 22, + "line": 36, + "column": 16, + "endLine": 36, + "endColumn": 31, + "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": 29, + "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": 37, + "column": 12, + "endLine": 37, + "endColumn": 19, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 40, "column": 1, - "endLine": 22, + "endLine": 43, "endColumn": 21, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 24, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 22, + "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": 42, + "column": 8, + "endLine": 42, + "endColumn": 15, "problem": "InteropObjectProperty", "suggest": "", "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 1, - "endLine": 22, - "endColumn": 12, - "problem": "InteropJsObjectUsage", + "endLine": 48, + "endColumn": 23, + "problem": "InteropCallObjectMethods", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 22, + "line": 46, + "column": 16, + "endLine": 46, + "endColumn": 30, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 28, + "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": 47, + "column": 12, + "endLine": 47, + "endColumn": 19, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 50, "column": 1, - "endLine": 22, - "endColumn": 12, - "problem": "BinaryOperations", + "endLine": 53, + "endColumn": 23, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 16, + "endLine": 51, + "endColumn": 30, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 12, + "endLine": 52, + "endColumn": 28, + "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": 52, + "column": 12, + "endLine": 52, + "endColumn": 19, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 1, + "endLine": 58, + "endColumn": 33, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 19, + "endLine": 56, + "endColumn": 41, + "problem": "InstantiatedJsOjbect", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 38, + "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": 57, + "column": 12, + "endLine": 57, + "endColumn": 24, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 1, + "endLine": 63, + "endColumn": 35, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 20, + "endLine": 61, + "endColumn": 34, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 40, + "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": 62, + "column": 12, + "endLine": 62, + "endColumn": 25, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" } ] 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 old mode 100755 new mode 100644 index f849dbbe047cb3f11eb136c7706f804f81e24688..6a6055373310508cc3a812d21e2ce825ee5e7578 --- 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 @@ -18,7 +18,7 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 59, + "endColumn": 106, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", @@ -28,20 +28,8 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 59, + "endColumn": 106, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 618, - "end": 676, - "replacementText": "" - }, - { - "start": 676, - "end": 676, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_not_have_property_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\nlet person = GeneratedImportVar_1.getPropertyByName('person');\n" - } - ], "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "severity": "ERROR" @@ -54,9 +42,13 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 678, - "end": 686, - "replacementText": "foo.getPropertyByName(\"name\")" + "start": 725, + "end": 733, + "replacementText": "foo.getProperty(\"name\")", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 } ], "suggest": "", @@ -64,43 +56,62 @@ "severity": "ERROR" }, { - "line": 19, + "line": 20, "column": 1, - "endLine": 19, - "endColumn": 9, - "problem": "InteropJsObjectUsage", + "endLine": 20, + "endColumn": 17, + "problem": "InteropObjectProperty", "autofix": [ { - "replacementText": "foo.getPropertyByName('name').toString()", - "start": 678, - "end": 686 + "start": 734, + "end": 750, + "replacementText": "foo.setProperty(\"name\", ESValue.wrap(\"456\"))", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 17 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 19, + "line": 21, "column": 1, - "endLine": 19, - "endColumn": 9, - "problem": "BinaryOperations", + "endLine": 21, + "endColumn": 16, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 751, + "end": 766, + "replacementText": "person.setProperty(\"age\", ESValue.wrap(23))", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 16 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 20, + "line": 22, "column": 1, - "endLine": 20, - "endColumn": 17, + "endLine": 22, + "endColumn": 21, "problem": "InteropObjectProperty", "autofix": [ { - "start": 687, - "end": 703, - "replacementText": "foo.setPropertyByName(\"name\", ESObject.wrap(\"456\"))" + "start": 767, + "end": 787, + "replacementText": "person.setProperty(\"male\", ESValue.wrap([2, 3]))", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 21 } ], "suggest": "", @@ -108,43 +119,114 @@ "severity": "ERROR" }, { - "line": 20, + "line": 23, "column": 1, - "endLine": 20, - "endColumn": 9, - "problem": "InteropJsObjectUsage", + "endLine": 23, + "endColumn": 13, + "problem": "InteropObjectProperty", "autofix": [ { - "replacementText": "foo.getPropertyByName('name').toString()", - "start": 687, - "end": 695 + "start": 788, + "end": 800, + "replacementText": "foo.setProperty(\"age\", ESValue.wrap(12))", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "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": "BinaryOperations", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 805, + "end": 821, + "replacementText": "foo.setProperty(\"name\", ESValue.wrap(\"456\"))", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 21, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 13, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "foo.getProperty('name').toString()", + "start": 805, + "end": 813, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 18, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 850, + "end": 859, + "replacementText": "foo.instantiate()", + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 27, "column": 1, - "endLine": 21, - "endColumn": 16, + "endLine": 27, + "endColumn": 11, "problem": "InteropObjectProperty", "autofix": [ { - "start": 704, - "end": 719, - "replacementText": "person.setPropertyByName(\"age\", ESObject.wrap(23))" + "start": 860, + "end": 870, + "replacementText": "a.setProperty(\"age\", ESValue.wrap(12))", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 11 } ], "suggest": "", @@ -152,43 +234,272 @@ "severity": "ERROR" }, { - "line": 21, + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 63, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 890, + "end": 934, + "replacementText": "TestHelper.instantiate(ESValue.wrap(\"TEST_INSTANTIATE_JS_OBJECT\"))", + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 30, "column": 1, - "endLine": 21, - "endColumn": 11, - "problem": "InteropJsObjectUsage", + "endLine": 33, + "endColumn": 33, + "problem": "InteropCallObjectMethods", "autofix": [ { - "replacementText": "person.getPropertyByName('age').toNumber()", - "start": 704, - "end": 714 + "start": 936, + "end": 1102, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let machine = new Machine();\n return machine.name === \"machine\"; // arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"machine.name === 'machine'\"))", + "line": 30, + "column": 1, + "endLine": 33, + "endColumn": 33 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 21, + "line": 31, + "column": 19, + "endLine": 31, + "endColumn": 32, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 979, + "end": 992, + "replacementText": "Machine.instantiate()", + "line": 31, + "column": 19, + "endLine": 31, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 12, + "endLine": 32, + "endColumn": 38, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1005, + "end": 1031, + "replacementText": "machine.getProperty(\"name\").areStrictlyEqual(\"machine\")", + "line": 32, + "column": 12, + "endLine": 32, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 12, + "endLine": 32, + "endColumn": 24, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1005, + "end": 1017, + "replacementText": "machine.getProperty(\"name\")", + "line": 32, + "column": 12, + "endLine": 32, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 35, "column": 1, - "endLine": 21, - "endColumn": 11, - "problem": "BinaryOperations", + "endLine": 38, + "endColumn": 24, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1105, + "end": 1252, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let user = new User(\"Bob\");\n return user.id === \"Bob\"; // arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"user.id === 'Bob'\"))", + "line": 35, + "column": 1, + "endLine": 38, + "endColumn": 24 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 22, + "line": 36, + "column": 16, + "endLine": 36, + "endColumn": 31, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1145, + "end": 1160, + "replacementText": "User.instantiate(ESValue.wrap(\"Bob\"))", + "line": 36, + "column": 16, + "endLine": 36, + "endColumn": 31 + } + ], + "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": 29, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1173, + "end": 1190, + "replacementText": "user.getProperty(\"id\").areStrictlyEqual(\"Bob\")", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 19, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1173, + "end": 1180, + "replacementText": "user.getProperty(\"id\")", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 40, "column": 1, - "endLine": 22, + "endLine": 43, "endColumn": 21, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1255, + "end": 1384, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\nlet user = new User(10);\nreturn user.id === 10;// arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"user.id === 10\"))", + "line": 40, + "column": 1, + "endLine": 43, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 24, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1291, + "end": 1303, + "replacementText": "User.instantiate(ESValue.wrap(10))", + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 22, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1312, + "end": 1326, + "replacementText": "user.getProperty(\"id\").areStrictlyEqual(10)", + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 15, "problem": "InteropObjectProperty", "autofix": [ { - "start": 720, - "end": 740, - "replacementText": "person.setPropertyByName(\"male\", ESObject.wrap([2, 3]))" + "start": 1312, + "end": 1319, + "replacementText": "user.getProperty(\"id\")", + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 15 } ], "suggest": "", @@ -196,30 +507,339 @@ "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 1, - "endLine": 22, - "endColumn": 12, - "problem": "InteropJsObjectUsage", + "endLine": 48, + "endColumn": 23, + "problem": "InteropCallObjectMethods", "autofix": [ { - "replacementText": "person.getPropertyByName('male')", - "start": 720, - "end": 731 + "start": 1387, + "end": 1531, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let user = new User(123n);\n return user.id === 123n; // arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"user.id === 123n\"))", + "line": 45, + "column": 1, + "endLine": 48, + "endColumn": 23 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", "severity": "ERROR" }, { - "line": 22, + "line": 46, + "column": 16, + "endLine": 46, + "endColumn": 30, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1427, + "end": 1441, + "replacementText": "User.instantiate(ESValue.wrap(123n))", + "line": 46, + "column": 16, + "endLine": 46, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 28, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1454, + "end": 1470, + "replacementText": "user.getProperty(\"id\").areStrictlyEqual(123n)", + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 19, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1454, + "end": 1461, + "replacementText": "user.getProperty(\"id\")", + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 50, "column": 1, - "endLine": 22, - "endColumn": 12, - "problem": "BinaryOperations", + "endLine": 53, + "endColumn": 23, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1534, + "end": 1677, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let user = new User(true);\n return user.id === true;// arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"user.id === true\"))", + "line": 50, + "column": 1, + "endLine": 53, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 16, + "endLine": 51, + "endColumn": 30, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1574, + "end": 1588, + "replacementText": "User.instantiate(ESValue.wrap(true))", + "line": 51, + "column": 16, + "endLine": 51, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 12, + "endLine": 52, + "endColumn": 28, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1601, + "end": 1617, + "replacementText": "user.getProperty(\"id\").areStrictlyEqual(true)", + "line": 52, + "column": 12, + "endLine": 52, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 12, + "endLine": 52, + "endColumn": 19, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1601, + "end": 1608, + "replacementText": "user.getProperty(\"id\")", + "line": 52, + "column": 12, + "endLine": 52, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 1, + "endLine": 58, + "endColumn": 33, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1680, + "end": 1855, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let machine = new Person(\"John\", 10);\n return machine.name === \"machine\"; // arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"machine.name === 'machine'\"))", + "line": 55, + "column": 1, + "endLine": 58, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 19, + "endLine": 56, + "endColumn": 41, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1723, + "end": 1745, + "replacementText": "Person.instantiate(ESValue.wrap(\"John\"), ESValue.wrap(10))", + "line": 56, + "column": 19, + "endLine": 56, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 38, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1758, + "end": 1784, + "replacementText": "machine.getProperty(\"name\").areStrictlyEqual(\"machine\")", + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 24, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1758, + "end": 1770, + "replacementText": "machine.getProperty(\"name\")", + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 1, + "endLine": 63, + "endColumn": 35, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1858, + "end": 2030, + "replacementText": "test_helper.invokeMethod(\"test\", ESValue.wrap(() => {\n let employee = new Employee();\n return employee.name === \"employee\"; // arkts-interop-js2s-access-js-prop\n}), ESValue.wrap(\"employee.name === 'employee'\"))", + "line": 60, + "column": 1, + "endLine": 63, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 20, + "endLine": 61, + "endColumn": 34, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1902, + "end": 1916, + "replacementText": "Employee.instantiate()", + "line": 61, + "column": 20, + "endLine": 61, + "endColumn": 34 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 40, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1929, + "end": 1957, + "replacementText": "employee.getProperty(\"name\").areStrictlyEqual(\"employee\")", + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 40 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 25, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1929, + "end": 1942, + "replacementText": "employee.getProperty(\"name\")", + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" } ] 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 index 838a0500a51da618680219ad2074df304e1eff66..e96c8ee4d27b5de8fd471382863075ddee071158 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.json @@ -18,11 +18,21 @@ "line": 17, "column": 1, "endLine": 17, - "endColumn": 59, + "endColumn": 106, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "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/interop/interop_not_have_property_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets index a96b2c80b70af6dac3fd39241a88ef028068a10f..4d4628b40215d8d2067e88460bd5e34918981172 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets @@ -12,14 +12,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + 'use static' +import { foo, person, TestHelper, Machine, User, Person, Employee } from "./interop_not_have_property_js" + +foo.getProperty("name") +foo.setProperty("name", ESValue.wrap("456")) +person.setProperty("age", ESValue.wrap(23)) +person.setProperty("male", ESValue.wrap([2, 3])) +foo.setProperty("age", ESValue.wrap(12)) +if (foo.setProperty("name", ESValue.wrap("456"))) { print("true") } + +let a = foo.instantiate() +a.setProperty("age", ESValue.wrap(12)) + +let test_helper = TestHelper.instantiate(ESValue.wrap("TEST_INSTANTIATE_JS_OBJECT")); +test_helper.invokeMethod("test", ESValue.wrap(() => { + let machine = Machine.instantiate(); + return machine.getProperty("name").areStrictlyEqual("machine"); // arkts-interop-js2s-access-js-prop +}), ESValue.wrap("machine.name === 'machine'")); + +test_helper.invokeMethod("test", ESValue.wrap(() => { + let user = User.instantiate(ESValue.wrap("Bob")); + return user.getProperty("id").areStrictlyEqual("Bob"); // arkts-interop-js2s-access-js-prop +}), ESValue.wrap("user.id === 'Bob'")); + +test_helper.invokeMethod("test", ESValue.wrap(() => { +let user = User.instantiate(ESValue.wrap(10)); +return user.getProperty("id").areStrictlyEqual(10);// arkts-interop-js2s-access-js-prop +}), ESValue.wrap("user.id === 10")); + +test_helper.invokeMethod("test", ESValue.wrap(() => { + let user = User.instantiate(ESValue.wrap(123n)); + return user.getProperty("id").areStrictlyEqual(123n); // arkts-interop-js2s-access-js-prop +}), ESValue.wrap("user.id === 123n")); -let GeneratedImportVar_1 = ESObject.load('./interop_not_have_property_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); -let person = GeneratedImportVar_1.getPropertyByName('person'); +test_helper.invokeMethod("test", ESValue.wrap(() => { + let user = User.instantiate(ESValue.wrap(true)); + return user.getProperty("id").areStrictlyEqual(true);// arkts-interop-js2s-access-js-prop +}), ESValue.wrap("user.id === true")); +test_helper.invokeMethod("test", ESValue.wrap(() => { + let machine = Person.instantiate(ESValue.wrap("John"), ESValue.wrap(10)); + return machine.getProperty("name").areStrictlyEqual("machine"); // arkts-interop-js2s-access-js-prop +}), ESValue.wrap("machine.name === 'machine'")); -foo.getPropertyByName("name") -foo.setPropertyByName("name", ESObject.wrap("456")) -person.setPropertyByName("age", ESObject.wrap(23)) -person.setPropertyByName("male", ESObject.wrap([2, 3])) \ No newline at end of file +test_helper.invokeMethod("test", ESValue.wrap(() => { + let employee = Employee.instantiate(); + return employee.getProperty("name").areStrictlyEqual("employee"); // arkts-interop-js2s-access-js-prop +}), ESValue.wrap("employee.name === 'employee'")); \ 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 index bc6054f74509a028c9ba595ca75bc51475e33b01..6e6a87716f94a0cc73c53b3a5fd1ff147ed01401 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json @@ -16,29 +16,179 @@ "result": [ { "line": 17, - "column": 5, + "column": 1, + "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": 1, "endLine": 17, - "endColumn": 75, + "endColumn": 106, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 26, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 18, + "line": 29, "column": 5, - "endLine": 18, - "endColumn": 56, + "endLine": 29, + "endColumn": 85, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 47, + "endLine": 33, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 40, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 19, + "line": 35, + "column": 47, + "endLine": 38, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 9, + "endLine": 36, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 47, + "endLine": 43, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 41, "column": 5, - "endLine": 19, - "endColumn": 62, + "endLine": 41, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 47, + "endLine": 48, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 9, + "endLine": 46, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 47, + "endLine": 53, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 47, + "endLine": 58, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 9, + "endLine": 56, + "endColumn": 77, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 47, + "endLine": 63, + "endColumn": 2, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 9, + "endLine": 61, + "endColumn": 42, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/interop_not_have_property_js.js b/ets2panda/linter/test/interop/interop_not_have_property_js.js index cd3b2ad79c827240efb0dfeb83a5057f3238fb3d..45b2953a2cf654d08f72cf6f2811e3e7892f37d0 100755 --- a/ets2panda/linter/test/interop/interop_not_have_property_js.js +++ b/ets2panda/linter/test/interop/interop_not_have_property_js.js @@ -13,4 +13,61 @@ * limitations under the License. */ export let foo = {name: "123"} -export let person = {age: 12, male: [1, 2, 3]} \ No newline at end of file +export let person = {age: 12, male: [1, 2, 3]} +export class TestHelper { + constructor(testName) { + this.testName = testName; + this.passed = 0; + this.failed = 0; + } + + test(testFunction, description) { + const result = testFunction(); + if (result) { + this.passed++; + console.log(`[PASS] ${this.testName}: ${description}`); + } else { + this.failed++; + console.error(`[FAIL] ${this.testName}: ${description}`); + } + } + + getStats() { + return { + passed: this.passed, + failed: this.failed, + total: this.passed + this.failed + }; + } + + printSummary() { + const stats = this.getStats(); + } +} + +export class Machine { + name = "machine"; +} + +export class User { + id; + constructor(a){ + this.id = a; + } +} + +export class Person { + name; + age; + constructor(a, b){ + this.name = a; + this.age = b; + } +} + +export class Employee { + name; + constructor(a = "employee"){ + this.name = a; + } +} \ 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 old mode 100755 new mode 100644 index 1049aac0f00e701d6e1ad108fcc92ab88dcf7933..8c41ae41820260ad9b446e203c8ebc8c7c096e4e --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' import {foo} from "./interop_property_num_js" 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 old mode 100755 new mode 100644 index bf5ffbc331d6a8a85b7127b68cc4d7e8e575cdf3..ccb4943134ffca9cc6af97e2bdd741057074e0e4 --- 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 @@ -15,19 +15,9 @@ ], "result": [ { - "line": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 46, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 1, - "endLine": 19, + "endLine": 18, "endColumn": 9, "problem": "InteropNoHaveNum", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 2, - "endLine": 19, + "endLine": 18, "endColumn": 9, "problem": "InteropObjectProperty", "suggest": "", @@ -56,12 +46,12 @@ }, { "line": 19, - "column": 2, + "column": 1, "endLine": 19, "endColumn": 9, - "problem": "InteropJsObjectUsage", + "problem": "InteropNoHaveNum", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -69,9 +59,9 @@ "column": 2, "endLine": 19, "endColumn": 9, - "problem": "BinaryOperations", + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -94,26 +84,6 @@ "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": 20, - "column": 2, - "endLine": 20, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 21, "column": 1, @@ -134,31 +104,11 @@ "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": 21, - "column": 2, - "endLine": 21, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 22, "column": 1, "endLine": 22, - "endColumn": 9, + "endColumn": 11, "problem": "InteropNoHaveNum", "suggest": "", "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", @@ -166,34 +116,14 @@ }, { "line": 22, - "column": 2, + "column": 3, "endLine": 22, - "endColumn": 9, + "endColumn": 10, "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": 22, - "column": 2, - "endLine": 22, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 23, "column": 1, @@ -214,26 +144,6 @@ "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": 23, - "column": 3, - "endLine": 23, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 24, "column": 1, @@ -254,26 +164,6 @@ "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": 24, - "column": 3, - "endLine": 24, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 25, "column": 1, @@ -293,66 +183,6 @@ "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": 25, - "column": 3, - "endLine": 25, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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" - }, - { - "line": 26, - "column": 3, - "endLine": 26, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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 old mode 100755 new mode 100644 index a5900c6c1f29aab112c270a972e80e81e9781ed1..5a00e93e85d4b302625e82ef5b3bfe8a8e648fe2 --- 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 @@ -15,48 +15,30 @@ ], "result": [ { - "line": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 46, "problem": "InterOpImportJs", - "autofix": [ - { - "start": 618, - "end": 663, - "replacementText": "" - }, - { - "start": 663, - "end": 663, - "replacementText": "let GeneratedImportVar_1 = ESObject.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, + "line": 18, "column": 1, - "endLine": 19, + "endLine": 18, "endColumn": 9, "problem": "InteropNoHaveNum", "autofix": [ { - "start": 666, - "end": 673, - "replacementText": "foo.getPropertyByName(\"num\").toNumber()" + "start": 653, + "end": 660, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 9 } ], "suggest": "", @@ -64,16 +46,20 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 2, - "endLine": 19, + "endLine": 18, "endColumn": 9, "problem": "InteropObjectProperty", "autofix": [ { - "start": 666, - "end": 673, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 653, + "end": 660, + "replacementText": "foo.getProperty(\"num\")", + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 9 } ], "suggest": "", @@ -82,19 +68,23 @@ }, { "line": 19, - "column": 2, + "column": 1, "endLine": 19, "endColumn": 9, - "problem": "InteropJsObjectUsage", + "problem": "InteropNoHaveNum", "autofix": [ { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 666, - "end": 673 + "start": 663, + "end": 670, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -102,9 +92,20 @@ "column": 2, "endLine": 19, "endColumn": 9, - "problem": "BinaryOperations", + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 663, + "end": 670, + "replacementText": "foo.getProperty(\"num\")", + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9 + } + ], "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { @@ -115,9 +116,13 @@ "problem": "InteropNoHaveNum", "autofix": [ { - "start": 676, - "end": 683, - "replacementText": "foo.getPropertyByName(\"num\").toNumber()" + "start": 673, + "end": 680, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9 } ], "suggest": "", @@ -132,42 +137,19 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 676, - "end": 683, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 673, + "end": 680, + "replacementText": "foo.getProperty(\"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 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 2, - "endLine": 20, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 21, "column": 1, @@ -176,9 +158,13 @@ "problem": "InteropNoHaveNum", "autofix": [ { - "start": 686, - "end": 693, - "replacementText": "foo.getPropertyByName(\"num\").toNumber()" + "start": 683, + "end": 690, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9 } ], "suggest": "", @@ -193,53 +179,34 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 686, - "end": 693, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 683, + "end": 690, + "replacementText": "foo.getProperty(\"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 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 2, - "endLine": 21, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 22, "column": 1, "endLine": 22, - "endColumn": 9, + "endColumn": 11, "problem": "InteropNoHaveNum", "autofix": [ { - "start": 696, - "end": 703, - "replacementText": "foo.getPropertyByName(\"num\").toNumber()" + "start": 693, + "end": 702, + "replacementText": "(foo.getProperty(\"num\").toNumber())", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 11 } ], "suggest": "", @@ -248,48 +215,25 @@ }, { "line": 22, - "column": 2, + "column": 3, "endLine": 22, - "endColumn": 9, + "endColumn": 10, "problem": "InteropObjectProperty", "autofix": [ { - "start": 696, - "end": 703, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 694, + "end": 701, + "replacementText": "foo.getProperty(\"num\")", + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 10 } ], "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 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 2, - "endLine": 22, - "endColumn": 9, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 23, "column": 1, @@ -298,9 +242,13 @@ "problem": "InteropNoHaveNum", "autofix": [ { - "start": 706, - "end": 715, - "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + "start": 705, + "end": 714, + "replacementText": "(foo.getProperty(\"num\").toNumber())", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11 } ], "suggest": "", @@ -315,42 +263,19 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 707, - "end": 714, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 706, + "end": 713, + "replacementText": "foo.getProperty(\"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 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 3, - "endLine": 23, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 24, "column": 1, @@ -359,9 +284,13 @@ "problem": "InteropNoHaveNum", "autofix": [ { - "start": 718, - "end": 727, - "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" + "start": 717, + "end": 726, + "replacementText": "(foo.getProperty(\"num\").toNumber())", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11 } ], "suggest": "", @@ -376,42 +305,19 @@ "problem": "InteropObjectProperty", "autofix": [ { - "start": 719, - "end": 726, - "replacementText": "foo.getPropertyByName(\"num\")" + "start": 718, + "end": 725, + "replacementText": "foo.getProperty(\"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 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 3, - "endLine": 24, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, { "line": 25, "column": 1, @@ -420,47 +326,17 @@ "problem": "InteropNoHaveNum", "autofix": [ { - "start": 730, - "end": 739, - "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" - } - ], - "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, + "start": 729, "end": 738, - "replacementText": "foo.getPropertyByName(\"num\")" - } - ], - "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 + "replacementText": "(foo.getProperty(\"num\").toNumber())", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11 } ], "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", "severity": "ERROR" }, { @@ -468,71 +344,21 @@ "column": 3, "endLine": 25, "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 1, - "endLine": 26, - "endColumn": 11, - "problem": "InteropNoHaveNum", - "autofix": [ - { - "start": 742, - "end": 751, - "replacementText": "(foo.getPropertyByName(\"num\").toNumber())" - } - ], - "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\")" + "start": 730, + "end": 737, + "replacementText": "foo.getProperty(\"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": 26, - "column": 3, - "endLine": 26, - "endColumn": 10, - "problem": "InteropJsObjectUsage", - "autofix": [ - { - "replacementText": "foo.getPropertyByName('num').toNumber()", - "start": 743, - "end": 750 - } - ], - "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 3, - "endLine": 26, - "endColumn": 10, - "problem": "BinaryOperations", - "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", - "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 index 456612d680838522a6a4843c38b2df4fa326df96..ca88f857e960b437dcf767c0ac40be998c8f1236 100755 --- 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 @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets index ade780f491a275359f6f19ecae923ba66131e287..397d49f4e68017f85604eb52118a48973d74f8f1 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets @@ -12,17 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' -let GeneratedImportVar_1 = ESObject.load('./interop_property_num_js'); -let foo = GeneratedImportVar_1.getPropertyByName('foo'); +import {foo} from "./interop_property_num_js" - -+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 ++foo.getProperty("num").toNumber(); +-foo.getProperty("num").toNumber(); +!foo.getProperty("num").toNumber(); +~foo.getProperty("num").toNumber(); ++(foo.getProperty("num").toNumber()); +-(foo.getProperty("num").toNumber()); +!(foo.getProperty("num").toNumber()); +~(foo.getProperty("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 index c3adb8622499be3bad0d9bd535b96794f5dae698..923652a6ed843e53643967940e9a49e35e5e2616 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json @@ -15,80 +15,70 @@ ], "result": [ { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 70, - "problem": "AnyType", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 46, + "problem": "InterOpImportJs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", "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, + "endLine": 18, + "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { - "line": 22, + "line": 19, "column": 1, - "endLine": 22, - "endColumn": 41, + "endLine": 19, + "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { - "line": 24, + "line": 21, "column": 1, - "endLine": 24, - "endColumn": 41, + "endLine": 21, + "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { - "line": 25, + "line": 22, "column": 1, - "endLine": 25, - "endColumn": 43, + "endLine": 22, + "endColumn": 37, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { - "line": 26, + "line": 23, "column": 1, - "endLine": 26, - "endColumn": 43, + "endLine": 23, + "endColumn": 37, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { - "line": 28, + "line": 25, "column": 1, - "endLine": 28, - "endColumn": 43, + "endLine": 25, + "endColumn": 37, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets b/ets2panda/linter/test/interop/no_await_js_promise.ets old mode 100755 new mode 100644 index 9247c363b44ed65bb043a4311584031f31e6d8fd..124f7b4daba7134bcd6d05ab95a36653ec7cfd43 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets @@ -1,65 +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. - */ -'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()); +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 index 66fb88f85945924e8be0e83d90123507033f4c5d..6958168fef2a70000342107f7d5f2b5805c14fae 100755 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.args.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.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/interop/no_await_js_promise.ets.arkts2.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json old mode 100755 new mode 100644 index 54dff3eb9234b3f09d0902f6ebbac8ea91691542..13cd6170a9d06c8a69cbf75fe8f5d7207f3d3e86 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json @@ -1,33 +1,9 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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, + "line": 16, "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, + "endLine": 16, "endColumn": 89, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +11,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 19, "column": 10, - "endLine": 20, + "endLine": 19, "endColumn": 17, "problem": "NoAwaitJsPromise", "suggest": "", @@ -45,9 +21,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 23, "column": 10, - "endLine": 24, + "endLine": 23, "endColumn": 21, "problem": "NoAwaitJsPromise", "suggest": "", @@ -55,29 +31,9 @@ "severity": "ERROR" }, { - "line": 24, - "column": 16, - "endLine": 24, - "endColumn": 21, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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, + "line": 27, "column": 10, - "endLine": 28, + "endLine": 27, "endColumn": 25, "problem": "NoAwaitJsPromise", "suggest": "", @@ -85,39 +41,9 @@ "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": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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, + "line": 35, "column": 10, - "endLine": 36, + "endLine": 35, "endColumn": 26, "problem": "NoAwaitJsPromise", "suggest": "", @@ -125,9 +51,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 12, - "endLine": 41, + "endLine": 40, "endColumn": 19, "problem": "NoAwaitJsPromise", "suggest": "", @@ -135,9 +61,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 44, "column": 12, - "endLine": 45, + "endLine": 44, "endColumn": 27, "problem": "NoAwaitJsPromise", "suggest": "", @@ -145,9 +71,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 48, "column": 20, - "endLine": 49, + "endLine": 48, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -155,9 +81,9 @@ "severity": "ERROR" }, { - "line": 50, + "line": 49, "column": 3, - "endLine": 52, + "endLine": 51, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", @@ -165,9 +91,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 50, "column": 12, - "endLine": 51, + "endLine": 50, "endColumn": 28, "problem": "NoAwaitJsPromise", "suggest": "", @@ -175,9 +101,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 54, "column": 12, - "endLine": 55, + "endLine": 54, "endColumn": 23, "problem": "NoAwaitJsPromise", "suggest": "", @@ -185,29 +111,9 @@ "severity": "ERROR" }, { - "line": 55, - "column": 18, - "endLine": 55, - "endColumn": 23, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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, + "line": 58, "column": 2, - "endLine": 61, + "endLine": 60, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", @@ -215,44 +121,14 @@ "severity": "ERROR" }, { - "line": 60, + "line": 59, "column": 31, - "endLine": 60, + "endLine": 59, "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": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "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.autofix.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..10055bdbb3c857fb01df06afa1e8b1b764f15480 --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json @@ -0,0 +1,258 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 89, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 17, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 742, + "end": 743, + "replacementText": "p.toPromise()", + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 21, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 800, + "end": 805, + "replacementText": "foo.invoke().toPromise()", + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 10, + "endLine": 27, + "endColumn": 25, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 860, + "end": 869, + "replacementText": "pFuncCall.toPromise()", + "line": 27, + "column": 10, + "endLine": 27, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 10, + "endLine": 35, + "endColumn": 26, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 990, + "end": 1000, + "replacementText": "pArrowCall.toPromise()", + "line": 35, + "column": 10, + "endLine": 35, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 12, + "endLine": 40, + "endColumn": 19, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 1067, + "end": 1068, + "replacementText": "p.toPromise()", + "line": 40, + "column": 12, + "endLine": 40, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 12, + "endLine": 44, + "endColumn": 27, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 1118, + "end": 1127, + "replacementText": "pFuncCall.toPromise()", + "line": 44, + "column": 12, + "endLine": 44, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 20, + "endLine": 48, + "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": 49, + "column": 3, + "endLine": 51, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 12, + "endLine": 50, + "endColumn": 28, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 1197, + "end": 1207, + "replacementText": "pArrowCall.toPromise()", + "line": 50, + "column": 12, + "endLine": 50, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 12, + "endLine": 54, + "endColumn": 23, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 1262, + "end": 1267, + "replacementText": "foo.invoke().toPromise()", + "line": 54, + "column": 12, + "endLine": 54, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 2, + "endLine": 60, + "endColumn": 2, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 1278, + "end": 1338, + "replacementText": "async () => {\n console.log(\"IIFE result:\", await p);\n}", + "line": 58, + "column": 2, + "endLine": 60, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 31, + "endLine": 59, + "endColumn": 38, + "problem": "NoAwaitJsPromise", + "autofix": [ + { + "start": 1333, + "end": 1334, + "replacementText": "p.toPromise()", + "line": 59, + "column": 31, + "endLine": 59, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "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 index 5285bc41f634a1abbb69521c2609a6c4aebd006d..02889dfd82b7eb15ba30b481cd8ee682c9a19ea9 100755 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.json @@ -15,19 +15,9 @@ ], "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, + "line": 48, "column": 20, - "endLine": 49, + "endLine": 48, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 58, "column": 2, - "endLine": 61, + "endLine": 60, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..63fd6e25e811a3538b264edb96e5d30366412a2c --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets @@ -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 { p, foo, pFuncCall, arrowFunc, pArrowCall } from "./no_await_js_promise_export"; + +async function awaitPromise() { + return await p.toPromise(); +} + +async function awaitFunctionCall() { + return await foo.invoke().toPromise(); +} + +async function awaitFuncResult() { + return await pFuncCall.toPromise(); +} + +async function awaitArrowCall() { + return await arrowFunc(); +} + +async function awaitArrowResult() { + return await pArrowCall.toPromise(); +} + +class ExampleClass { + async classMethod() { + return await p.toPromise(); + } + + handler = async () => { + return await pFuncCall.toPromise(); + }; +} + +const exampleObj = { + async objMethod() { + return await pArrowCall.toPromise(); + }, + + arrowHandler: async () => { + return await foo.invoke().toPromise(); + } +}; + +(async () => { + console.log("IIFE result:", await p.toPromise()); +})(); + +(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.migrate.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e83601dd74cdf19e93132d4109945addda867301 --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.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": 1, + "endLine": 16, + "endColumn": 89, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 16, + "endLine": 18, + "endColumn": 28, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 33, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 31, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 16, + "endLine": 34, + "endColumn": 32, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 9, + "endLine": 39, + "endColumn": 20, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 45, + "endColumn": 4, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 20, + "endLine": 48, + "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": 49, + "column": 3, + "endLine": 51, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 9, + "endLine": 49, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 17, + "endLine": 55, + "endColumn": 4, + "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/interop/no_js_instanceof.ets b/ets2panda/linter/test/interop/no_js_instanceof.ets old mode 100755 new mode 100644 index f3e57eeee88a4fecf7bfddc410314089fdd77036..9c7c1b645398c89753dbdb8fdf9af53f2f160a57 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets @@ -12,7 +12,6 @@ * 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" diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.args.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.args.json index 3ef4496a819a201892114d1c90f78ae32053c334..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100755 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.args.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.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/interop/no_js_instanceof.ets.arkts2.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json old mode 100755 new mode 100644 index 38edbb018939e1ec137b90fb20851cbb1f89a667..59a5952e82033106e5c59cfc1ba268bb606f5254 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json @@ -1,33 +1,23 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT 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": 17, + "line": 16, "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, + "endLine": 16, "endColumn": 88, "problem": "InterOpImportJs", "suggest": "", @@ -35,9 +25,9 @@ "severity": "ERROR" }, { - "line": 27, + "line": 26, "column": 4, - "endLine": 27, + "endLine": 26, "endColumn": 22, "problem": "InteropJsInstanceof", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 30, "column": 4, - "endLine": 31, + "endLine": 30, "endColumn": 23, "problem": "InteropJsInstanceof", "suggest": "", @@ -55,9 +45,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 34, "column": 4, - "endLine": 35, + "endLine": 34, "endColumn": 23, "problem": "InteropJsInstanceof", "suggest": "", @@ -65,19 +55,9 @@ "severity": "ERROR" }, { - "line": 39, - "column": 28, - "endLine": 39, - "endColumn": 50, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 39, + "line": 38, "column": 28, - "endLine": 39, + "endLine": 38, "endColumn": 50, "problem": "CallJSFunction", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 40, "column": 4, - "endLine": 41, + "endLine": 40, "endColumn": 34, "problem": "InteropJsInstanceof", "suggest": "", @@ -95,9 +75,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 45, "column": 8, - "endLine": 46, + "endLine": 45, "endColumn": 38, "problem": "InteropJsInstanceof", "suggest": "", @@ -105,9 +85,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 51, "column": 8, - "endLine": 52, + "endLine": 51, "endColumn": 38, "problem": "InteropJsInstanceof", "suggest": "", @@ -115,9 +95,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 58, "column": 12, - "endLine": 59, + "endLine": 58, "endColumn": 42, "problem": "InteropJsInstanceof", "suggest": "", @@ -125,9 +105,9 @@ "severity": "ERROR" }, { - "line": 65, + "line": 64, "column": 4, - "endLine": 65, + "endLine": 64, "endColumn": 22, "problem": "InteropJsInstanceof", "suggest": "", @@ -135,9 +115,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 68, "column": 4, - "endLine": 69, + "endLine": 68, "endColumn": 24, "problem": "InteropJsInstanceof", "suggest": "", @@ -145,19 +125,9 @@ "severity": "ERROR" }, { - "line": 69, - "column": 4, - "endLine": 69, - "endColumn": 7, - "problem": "InteropJsObjectCallStaticFunc", - "suggest": "", - "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", - "severity": "ERROR" - }, - { - "line": 69, + "line": 68, "column": 4, - "endLine": 69, + "endLine": 68, "endColumn": 7, "problem": "CallJSFunction", "suggest": "", @@ -165,9 +135,9 @@ "severity": "ERROR" }, { - "line": 73, + "line": 72, "column": 36, - "endLine": 73, + "endLine": 72, "endColumn": 51, "problem": "DynamicCtorCall", "suggest": "", @@ -175,29 +145,19 @@ "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": 73, + "line": 72, "column": 36, - "endLine": 73, + "endLine": 72, "endColumn": 51, - "problem": "BinaryOperations", + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 75, + "line": 74, "column": 5, - "endLine": 75, + "endLine": 74, "endColumn": 37, "problem": "InteropJsInstanceof", "suggest": "", @@ -205,23 +165,23 @@ "severity": "ERROR" }, { - "line": 75, + "line": 74, "column": 22, - "endLine": 75, + "endLine": 74, "endColumn": 37, - "problem": "InteropJsObjectConditionJudgment", + "problem": "InteropObjectProperty", "suggest": "", - "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", "severity": "ERROR" }, { - "line": 75, + "line": 74, "column": 22, - "endLine": 75, + "endLine": 74, "endColumn": 37, - "problem": "BinaryOperations", + "problem": "InteropJsObjectConditionJudgment", "suggest": "", - "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..b45c2e403764162652bc67d21c9e3aaed29eaf11 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json @@ -0,0 +1,353 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 88, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 22, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "foo.isInstanceOf(Foo)", + "start": 766, + "end": 784, + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 23, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "foo1.isInstanceOf(Foo)", + "start": 799, + "end": 818, + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 23, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "foo.isInstanceOf(Foo1)", + "start": 829, + "end": 848, + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 28, + "endLine": 38, + "endColumn": 50, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 883, + "end": 905, + "replacementText": "CreatePerson.invoke(ESValue.wrap('xc'), ESValue.wrap(18))", + "line": 38, + "column": 28, + "endLine": 38, + "endColumn": 50 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 4, + "endLine": 40, + "endColumn": 34, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "person.isInstanceOf(CreatePerson)", + "start": 910, + "end": 940, + "line": 40, + "column": 4, + "endLine": 40, + "endColumn": 34 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 8, + "endLine": 45, + "endColumn": 38, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "person.isInstanceOf(CreatePerson)", + "start": 980, + "end": 1010, + "line": 45, + "column": 8, + "endLine": 45, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 38, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "person.isInstanceOf(CreatePerson)", + "start": 1059, + "end": 1089, + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 12, + "endLine": 58, + "endColumn": 42, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "person.isInstanceOf(CreatePerson)", + "start": 1147, + "end": 1177, + "line": 58, + "column": 12, + "endLine": 58, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 4, + "endLine": 64, + "endColumn": 22, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "a.isInstanceOf(Array)", + "start": 1204, + "end": 1222, + "line": 64, + "column": 4, + "endLine": 64, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 4, + "endLine": 68, + "endColumn": 24, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "b().isInstanceOf(Array)", + "start": 1233, + "end": 1253, + "line": 68, + "column": 4, + "endLine": 68, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 4, + "endLine": 68, + "endColumn": 7, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1233, + "end": 1236, + "replacementText": "b.invoke()", + "line": 68, + "column": 4, + "endLine": 68, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 36, + "endLine": 72, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 36, + "endLine": 72, + "endColumn": 51, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1296, + "end": 1311, + "replacementText": "MyNamespace.getProperty(\"Dog\")", + "line": 72, + "column": 36, + "endLine": 72, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 37, + "problem": "InteropJsInstanceof", + "autofix": [ + { + "replacementText": "myDog.isInstanceOf(MyNamespace.Dog)", + "start": 1327, + "end": 1359, + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 37, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1344, + "end": 1359, + "replacementText": "MyNamespace.getProperty(\"Dog\")", + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 37, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "MyNamespace.getProperty('Dog')", + "start": 1344, + "end": 1359, + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 37 + } + ], + "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 index e6955adae6bac5e78b91f1b2779d27117f1fde2f..ca88f857e960b437dcf767c0ac40be998c8f1236 100755 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.json @@ -1,29 +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": [ - { - "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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ed59da3516194853648a1c788e83857f22016d02 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.isInstanceOf(Foo)) { + +} + +if(foo1.isInstanceOf(Foo)) { + +} + +if(foo.isInstanceOf(Foo1)) { + +} + +let person: CreatePerson = CreatePerson.invoke(ESValue.wrap('xc'), ESValue.wrap(18)) + +if(person.isInstanceOf(CreatePerson)) { + +} + +function test1(): void { + if(person.isInstanceOf(CreatePerson)) { + + } +} + +const test2 = (): void => { + if(person.isInstanceOf(CreatePerson)) { + + } +} + +class Test3 { + init(): void { + if(person.isInstanceOf(CreatePerson)) { + + } + } +} + +if(a.isInstanceOf(Array)) { + +} + +if(b.invoke().isInstanceOf(Array)) { + +} + +const myDog: MyNamespace.Dog = new MyNamespace.getProperty("getProperty")("getProperty")("getProperty")("getProperty")("getProperty")("getProperty")("getProperty")("getProperty")("getProperty")("Dog")('Buddy'); + +if (myDog.isInstanceOf(MyNamespace.getProperty("Dog"))) { + console.log("This is a Dog!"); +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..614491fbff0302bbd0e855eec4d722ef2d6c5c68 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.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": 1, + "endLine": 16, + "endColumn": 88, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 19, + "endLine": 64, + "endColumn": 24, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 19, + "endLine": 64, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 28, + "endLine": 68, + "endColumn": 33, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 28, + "endLine": 68, + "endColumn": 33, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 36, + "endLine": 72, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 36, + "endLine": 72, + "endColumn": 59, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + } + ] +} \ 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 7797930ffdc48c71b861f8f690b58f811efd2319..3b9dceea070850349fa8069ac8cbd14471aa78c6 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets +++ b/ets2panda/linter/test/interop/object_built_in.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' + import { X } from "./oh_modules/object_built_in" @@ -25,3 +25,11 @@ export function foo(prx: Object) { } foo(new X()); // Illegal + +export function shouldPass() { + const bar = JSON.parse('{}'); + console.log(Object.keys(bar).length); +} + +shouldPass() + diff --git a/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json index 0e40297d99c1d7cc0071bcbd6b59f080a270cae5..1c34bb456b52af408822f508663c0effd173cfda 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json @@ -15,16 +15,6 @@ ], "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, @@ -44,6 +34,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 12, + "endLine": 23, + "endColumn": 18, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, { "line": 24, "column": 9, @@ -58,12 +68,21 @@ "line": 27, "column": 1, "endLine": 27, - "endColumn": 13, + "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" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "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 582a700d940a62a7f8b6fae343ed7bf79d4da05e..1918dfda6716ab4f49dc866eb6b247a24a5ee221 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.json @@ -14,16 +14,6 @@ "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": 5, @@ -53,6 +43,16 @@ "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets b/ets2panda/linter/test/interop/object_literal_constructor.ets index c60cfdf0ebf7df10bd76b9e9c2f29dbc04971c69..c66bdfabca6b8b748cc4c5f004e3f5a32b7521ff 100644 --- a/ets2panda/linter/test/interop/object_literal_constructor.ets +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets @@ -1,4 +1,3 @@ -'use static' /* * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +13,70 @@ * limitations under the License. */ -import { User, Person, Fruit, Apple } from "./oh_modules/object_literal_constructor" +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" } -let apple: Apple = { name: "apple", color: "green" } \ No newline at end of file +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/object_literal_constructor.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json index 1891f69fe39ff675c02949bfb1721d1906cd48a9..a9680f6f23acabb1287f0678008c8eb614b548d7 100644 --- a/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json @@ -13,20 +13,10 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 85, - "problem": "ImportAfterStatement", - "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", - "severity": "ERROR" - }, + "result": [ { "line": 19, - "column": 5, + "column": 18, "endLine": 19, "endColumn": 27, "problem": "InteropObjectLiteralClass", @@ -36,7 +26,7 @@ }, { "line": 23, - "column": 5, + "column": 22, "endLine": 23, "endColumn": 51, "problem": "InteropObjectLiteralClass", @@ -46,9 +36,119 @@ }, { "line": 25, - "column": 5, + "column": 14, "endLine": 25, - "endColumn": 53, + "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": 26, + "column": 14, + "endLine": 26, + "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": 26, + "column": 16, + "endLine": 26, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 16, + "endLine": 26, + "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": 29, + "column": 5, + "endLine": 29, + "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": 35, + "column": 12, + "endLine": 35, + "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": 48, + "column": 15, + "endLine": 48, + "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": 56, + "column": 11, + "endLine": 56, + "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": 62, + "column": 30, + "endLine": 62, + "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": 69, + "column": 5, + "endLine": 72, + "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": 78, + "column": 5, + "endLine": 78, + "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": 79, + "column": 5, + "endLine": 79, + "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)", diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.json index c57b713f15e0606479b9a1eab3f083468ad780f2..b242a6c5b974b13690bc5e6c8b116ae383f40ff7 100644 --- a/ets2panda/linter/test/interop/object_literal_constructor.ets.json +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.json @@ -15,13 +15,23 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 85, - "problem": "ImportAfterStatement", + "line": 25, + "column": 14, + "endLine": 25, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "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": 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" } ] diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets b/ets2panda/linter/test/interop/object_literal_union_type.ets index f57fd51379483dadc616f4982de7a53d521c2656..403b45935861d995d1acd0d4a479512da91863a4 100644 --- a/ets2panda/linter/test/interop/object_literal_union_type.ets +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets @@ -1,4 +1,3 @@ -'use static' /* * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,4 +25,6 @@ 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 +let y: X | Y = { name: "hello" } as Y; // legal + +let res: Record | object[] = {} \ No newline at end of file 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 index 5c02f0cb4d9911bc2709610266b70dc0caf4d404..d65993bf6342bb03a32481645d0f26e1b5155ac4 100644 --- a/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json @@ -15,29 +15,39 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 63, - "problem": "ImportAfterStatement", + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 31, + "problem": "ObjectLiteralUnionNeedsCast", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", "severity": "ERROR" }, { - "line": 19, - "column": 1, - "endLine": 19, - "endColumn": 67, - "problem": "ImportAfterStatement", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 31, + "problem": "InteropObjectLiteralAmbiguity", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", "severity": "ERROR" }, { - "line": 21, + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 31, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 22, "column": 5, - "endLine": 21, + "endLine": 22, "endColumn": 31, "problem": "InteropObjectLiteralAmbiguity", "suggest": "", @@ -45,20 +55,40 @@ "severity": "ERROR" }, { - "line": 23, + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 37, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 24, "column": 5, - "endLine": 23, - "endColumn": 31, + "endLine": 24, + "endColumn": 37, "problem": "InteropObjectLiteralAmbiguity", "suggest": "", "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", "severity": "ERROR" }, { - "line": 25, + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 26, "column": 5, - "endLine": 25, - "endColumn": 37, + "endLine": 26, + "endColumn": 34, "problem": "InteropObjectLiteralAmbiguity", "suggest": "", "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.json index 25154ac0c6605dd88492da69d54ca7d7a2cda0d5..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/object_literal_union_type.ets.json +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.json @@ -13,26 +13,5 @@ "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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets index 3ffe607d9d0b85dbe0dd9abd6d8a5573df035d68..f1f0a6f8e8589a99637d0dbc049ec3a105909001 100644 --- a/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets @@ -40,3 +40,14 @@ export class Apple extends Fruit { 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_arkts2.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets index dad32c88bac85147e6236659ba62ac53ecb691ea..81c8a334d4028ca4afe793d13a1cdae8e730ac59 100644 --- 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 @@ -12,7 +12,6 @@ * 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 4fd2894dd8489f827482c493f3d1782ef57e0d1a..5bfb75a30158144e237625107f8896eed1276e9c 100644 --- a/ets2panda/linter/test/interop/oh_modules/reflect_export.ets +++ b/ets2panda/linter/test/interop/oh_modules/reflect_export.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' export function foo(prx: Object) { Reflect.get(prx, 'a') // 'hello' @@ -28,3 +27,37 @@ export class X { a: string = 'hello' getName() { return this.a } } + +export class Reflect1 { + a: string = 'hello' + getName() { return this.a } +} +export let obj_Reflect1 = new Reflect1(); + +interface Iface { + a:number +} +export let objInter:Iface = {a:1} + +export function reflect_method1(prx: ESObject) { + Reflect.ownKeys(prx) // ['a'] + Reflect.set(prx, 'a', 7) // true + Reflect.get(prx, 'a') // true + Reflect.has(prx, 'a') // true +} + +export function reflect_method1_set(prx: ESObject) { + Reflect.set(prx, 'a', 7) // true +} + +export function reflect_method1_get(prx: ESObject) { + Reflect.get(prx, 'a') // true +} + +export function reflect_method1_ownKeys(prx: ESObject) { + Reflect.ownKeys(prx) // ['a'] +} + +export function reflect_method1_has(prx: ESObject) { + Reflect.has(prx, 'a') // true +} 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 index 2191e0197101822d16e3f3af4bc71f7162305b9b..540539ec6b9b475b6a7adcff5c4da0e6fb871e43 100644 --- a/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets +++ b/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' export class X { name: string = '' } diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets b/ets2panda/linter/test/interop/reflect_built_in.ets index 96b0800185e89fcc3bdf12c6ce9ac7dfd106ec0e..90b377fc15ded3c6fd2617cfedbe2c12d2adbc67 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets +++ b/ets2panda/linter/test/interop/reflect_built_in.ets @@ -12,8 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' - import { X } from "./oh_modules/reflect_export" export function foo(prx: Object) { @@ -29,3 +27,34 @@ export function bar(obj: Object) { foo(new X()); //illegal bar(new X()); //illegal + +import {Reflect1} from "./oh_modules/reflect_export" +import {obj_Reflect1} from "./oh_modules/reflect_export" +import {objInter} from "./oh_modules/reflect_export" + +function reflect_method2(prx: Object) { + Reflect.get(prx, 'a') // 'hello' + Reflect.set(prx, 'a', 'world') // true + Reflect.ownKeys(prx) // ['a'] +} + +reflect_method2(new Reflect1()); +Reflect.get(new Reflect1(), 'a') +Reflect.set(new Reflect1(), 'a', 'world') +Reflect.ownKeys(new Reflect1()) +let obj = new Reflect1() +reflect_method2(obj); +Reflect.get(obj, 'a') +Reflect.set(obj, 'a', 'world') +Reflect.ownKeys(obj) + +reflect_method2(obj_Reflect1); +Reflect.get(obj_Reflect1, 'a') +Reflect.set(obj_Reflect1, 'a', 'world') +Reflect.ownKeys(obj_Reflect1) + +reflect_method2(objInter); +Reflect.get(objInter, 'a') +Reflect.set(objInter, 'a', 'world') +Reflect.ownKeys(objInter) + diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json index 851c3577e750d6777b04cffa069e4da5ab2cb2f2..77b9d8ee5c57c4f5de8311e5c943730b8af5ff46 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json @@ -15,23 +15,73 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 48, - "problem": "ImportAfterStatement", + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 23, + "problem": "InteropCallReflect", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "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": 29, + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 32, + "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": 20, + "column": 2, + "endLine": 20, + "endColumn": 22, + "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": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 37, + "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": 24, + "column": 20, + "endLine": 24, + "endColumn": 23, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 27, "column": 1, - "endLine": 29, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endLine": 27, + "endColumn": 14, + "problem": "InteropCallReflect", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "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" }, { @@ -48,21 +98,271 @@ "line": 31, "column": 1, "endLine": 31, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endColumn": 53, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 31, + "line": 32, "column": 1, - "endLine": 31, - "endColumn": 14, + "endLine": 32, + "endColumn": 57, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 53, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 26, + "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": 37, + "column": 5, + "endLine": 37, + "endColumn": 35, + "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": 38, + "column": 5, + "endLine": 38, + "endColumn": 25, + "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": 38, + "column": 13, + "endLine": 38, + "endColumn": 20, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 33, + "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": 42, + "column": 1, + "endLine": 42, + "endColumn": 33, + "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": 43, + "column": 1, + "endLine": 43, + "endColumn": 42, + "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": 44, + "column": 1, + "endLine": 44, + "endColumn": 32, + "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": 44, + "column": 9, + "endLine": 44, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 1, + "endLine": 46, + "endColumn": 22, + "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": 47, + "column": 1, + "endLine": 47, + "endColumn": 22, + "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": 48, + "column": 1, + "endLine": 48, + "endColumn": 31, + "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": 49, + "column": 1, + "endLine": 49, + "endColumn": 21, "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": 49, + "column": 9, + "endLine": 49, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 1, + "endLine": 51, + "endColumn": 31, + "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": 52, + "column": 1, + "endLine": 52, + "endColumn": 31, + "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": 53, + "column": 1, + "endLine": 53, + "endColumn": 40, + "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": 54, + "column": 1, + "endLine": 54, + "endColumn": 30, + "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": 54, + "column": 9, + "endLine": 54, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 27, + "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": 57, + "column": 1, + "endLine": 57, + "endColumn": 27, + "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": 58, + "column": 1, + "endLine": 58, + "endColumn": 36, + "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": 59, + "column": 1, + "endLine": 59, + "endColumn": 26, + "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": 59, + "column": 9, + "endLine": 59, + "endColumn": 16, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.json b/ets2panda/linter/test/interop/reflect_built_in.ets.json index 0ee87e87fb38c2290a997111c093fa85d4809a32..ef3d440bfb53a748252176bfbf1bb6926a8b1fc4 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.json @@ -15,14 +15,224 @@ ], "result": [ { - "line": 17, + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 23, + "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": 19, + "column": 2, + "endLine": 19, + "endColumn": 32, + "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": 20, + "column": 2, + "endLine": 20, + "endColumn": 22, + "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": 24, + "column": 5, + "endLine": 24, + "endColumn": 37, + "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": 53, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 32, "column": 1, - "endLine": 17, - "endColumn": 48, + "endLine": 32, + "endColumn": 57, "problem": "ImportAfterStatement", "suggest": "", "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 53, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 26, + "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": 37, + "column": 5, + "endLine": 37, + "endColumn": 35, + "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": 38, + "column": 5, + "endLine": 38, + "endColumn": 25, + "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": 42, + "column": 1, + "endLine": 42, + "endColumn": 33, + "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": 43, + "column": 1, + "endLine": 43, + "endColumn": 42, + "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": 44, + "column": 1, + "endLine": 44, + "endColumn": 32, + "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": 47, + "column": 1, + "endLine": 47, + "endColumn": 22, + "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": 48, + "column": 1, + "endLine": 48, + "endColumn": 31, + "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": 49, + "column": 1, + "endLine": 49, + "endColumn": 21, + "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": 52, + "column": 1, + "endLine": 52, + "endColumn": 31, + "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": 53, + "column": 1, + "endLine": 53, + "endColumn": 40, + "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": 54, + "column": 1, + "endLine": 54, + "endColumn": 30, + "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": 57, + "column": 1, + "endLine": 57, + "endColumn": 27, + "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": 58, + "column": 1, + "endLine": 58, + "endColumn": 36, + "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": 59, + "column": 1, + "endLine": 59, + "endColumn": 26, + "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/static_dynamic_import.ets b/ets2panda/linter/test/interop/static_dynamic_import.ets index 2e2c993747bc431db12fcf5270cafc3ce7f20974..7eec28c4196a920c4c209ae4e9daf2ffaea7f188 100644 --- a/ets2panda/linter/test/interop/static_dynamic_import.ets +++ b/ets2panda/linter/test/interop/static_dynamic_import.ets @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' let arkTsMod = await import('./test_files/dummy_arkts1_file'); let tsModule = await import('./test_files/dummy_ts_file'); diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json b/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json index 3b87fbdb1f540ab4bde448b1dbc5fb9749cd30d7..dc7f9e0521f966339a23226da90cd2184faf4677 100644 --- a/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json +++ b/ets2panda/linter/test/interop/static_dynamic_import.ets.arkts2.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 17, + "line": 16, "column": 16, - "endLine": 17, + "endLine": 16, "endColumn": 62, "problem": "InteropDynamicImport", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 17, + "line": 16, "column": 22, - "endLine": 17, + "endLine": 16, "endColumn": 62, "problem": "DynamicImport", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 17, - "endLine": 18, + "endLine": 17, "endColumn": 59, "problem": "InteropDynamicImportTs", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 23, - "endLine": 18, + "endLine": 17, "endColumn": 59, "problem": "DynamicImport", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 16, - "endLine": 19, + "endLine": 18, "endColumn": 58, "problem": "InteropDynamicImportJs", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 22, - "endLine": 19, + "endLine": 18, "endColumn": 58, "problem": "DynamicImport", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 21, "column": 3, - "endLine": 22, + "endLine": 21, "endColumn": 44, "problem": "InteropDynamicImportTs", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 21, "column": 3, - "endLine": 22, + "endLine": 21, "endColumn": 39, "problem": "DynamicImport", "suggest": "", @@ -95,4 +95,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets.json b/ets2panda/linter/test/interop/static_dynamic_import.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..999000f1d0ecd378bb5189265cc4d871ecc8d227 100644 --- a/ets2panda/linter/test/interop/static_dynamic_import.ets.json +++ b/ets2panda/linter/test/interop/static_dynamic_import.ets.json @@ -13,5 +13,46 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 59, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 46, + "endLine": 21, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/static_object_literals.ets.json b/ets2panda/linter/test/interop/static_object_literals.ets.json index 12d46c0860e9c1e8e2b8ea429ab13cae1448e3da..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/interop/static_object_literals.ets.json +++ b/ets2panda/linter/test/interop/static_object_literals.ets.json @@ -13,66 +13,5 @@ "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" - } - ] + "result": [] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets b/ets2panda/linter/test/interop/unary_operation_js_obj.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6d66fee062a7f2ee2f4822230e873f306f7e903 --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.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 {foo} from "./unary_operation_js_obj_js.js" + ++foo.num; +-foo.num; +!foo.num; +~foo.num; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.args.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..a89d885810708ad03d96e3e14bb6590efd1a7547 --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.args.json @@ -0,0 +1,21 @@ +{ + "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." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..13a3e19d15ee7fea3b3f88f509ec22e8b06a9f6c --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.arkts2.json @@ -0,0 +1,94 @@ +{ + "result": [ + { + "line": 15, + "column": 1, + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "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": "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": 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" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..a619d83610fe29ef5e2427badbd66e433ea96bcf --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json @@ -0,0 +1,196 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 1, + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 657, + "end": 664, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 657, + "end": 664, + "replacementText": "foo.getProperty(\"num\")", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 667, + "end": 674, + "replacementText": "foo.getProperty(\"num\").toNumber()", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 667, + "end": 674, + "replacementText": "foo.getProperty(\"num\")", + "line": 18, + "column": 2, + "endLine": 18, + "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": "InteropNoHaveNum", + "autofix": [ + { + "start": 677, + "end": 684, + "replacementText": "foo.getProperty(\"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": 677, + "end": 684, + "replacementText": "foo.getProperty(\"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": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 687, + "end": 694, + "replacementText": "foo.getProperty(\"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": 687, + "end": 694, + "replacementText": "foo.getProperty(\"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" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..43cb4a27bcc78710d4aa5130c22ee053f66c3fbc --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.json @@ -0,0 +1,3 @@ +{ + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7fef071bd036dd04adf66fec6acb429e207bbd37 --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.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 {foo} from "./unary_operation_js_obj_js.js" + ++foo.getProperty("num").toNumber(); +-foo.getProperty("num").toNumber(); +!foo.getProperty("num").toNumber(); +~foo.getProperty("num").toNumber(); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0a055b7965f1bf8ab53fa19829d87d9a4e8491bc --- /dev/null +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.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": 15, + "column": 1, + "endLine": 15, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 35, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 35, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 35, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/test_files/dummy_ts_file.ts b/ets2panda/linter/test/interop/unary_operation_js_obj_js.js similarity index 95% rename from ets2panda/linter/test/interop/test_files/dummy_ts_file.ts rename to ets2panda/linter/test/interop/unary_operation_js_obj_js.js index e2f4a0e44b486d7a8c9ba88bb4c7d9dd933145be..6787c967843fb9f771355c300ca676850b9bd3f6 100644 --- a/ets2panda/linter/test/interop/test_files/dummy_ts_file.ts +++ b/ets2panda/linter/test/interop/unary_operation_js_obj_js.js @@ -13,4 +13,4 @@ * limitations under the License. */ -export module tsModule {} +export let foo = {num: 0}; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets b/ets2panda/linter/test/interop/unique_types.ets index 35f8bae39116bc89fb0ff43ffec5b8c810c399a3..10b1d97c338a97888b0f6c285c7a389aafef6285 100644 --- a/ets2panda/linter/test/interop/unique_types.ets +++ b/ets2panda/linter/test/interop/unique_types.ets @@ -12,25 +12,391 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' import { - objectLiteralType, - intersectionType, - tsFunction, - stringType, - enumType + any_var, + unknown_var, + symbol_var, + function_var, + enum_var, + A, + B, + TestHelper, + throw_number, + throw_string, + throw_boolean, + throw_bigint, + throw_obj, + throw_error, + throwErrorSubClass, + SubError, + throwRangeError, + ObjectLiteralClass, + ObjectLiteralInter, + MyClassDecorator, + propertyDecorator, + methodDecorator, + parameterDecorator, + accessorDecorator, + readonly1, + num_boxed, + bool_boxed, + str_boxed, + bigint_boxed, + ts_object_method, + ts_object_method_getOwnPropertyDescriptor, + ts_object_method_getOwnPropertyDescriptors, + ts_object_method_getOwnPropertyNames, + ts_object_method_hasOwn, + ts_object_method_isExtensible, + ts_object_method_isFrozen, + ts_object_method_isSealed, + ts_object_method_keys, + ts_object_method_values, + interObj, + ts_reflect_method, + ts_reflect_method_apply, + ts_reflect_method_defineProperty, + ts_reflect_method_deleteProperty, + ts_reflect_method_getOwnPropertyDescriptor, + ts_reflect_method_ownKeys, + ts_reflect_method_isExtensible, + ts_reflect_method_set, + ts_reflect_method_setPrototypeOf } from "./ignore_files/unique_types"; -objectLiteralType.name = "test" -intersectionType.name = "test"; +typeof any_var === 'object'; +typeof unknown_var === 'number'; +typeof symbol_var === 'object'; +function_var() === true; +A.instance; +let obj: B = { name: "hello" }; +enum_var.a === 0; -try { -tsFunction(); -} catch (e) { +export function test_ts_non_standard_exception(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_NON_STANDARD_EXCEPTION"); + + test_helper.test(() => { + try { + throw_number(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as number === 123; + } + return false; + }, "e as number === 123"); + + test_helper.test(() => { + try { + throw_boolean(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as boolean === true; + } + return false; + }, "e as boolean === true"); + + test_helper.test(() => { + try { + throw_bigint(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as bigint === 111n; + } + return false; + }, "e as bigint === 111n"); + + test_helper.test(() => { + try { + throw_string(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as string === "error"; + } + return false; + }, "e as string === "error""); + + test_helper.test(() => { + try { + throw_obj(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e.name === "error"; + } + return false; + }, "e.name === "error""); + + test_helper.test(() => { + try { + throw_error(); + } catch (e) { + let errObj: Error = e as Error; + return errObj.name === "error"; + } + return false; + }, "errObj.name === "error""); + + test_helper.test(() => { + try { + throwErrorSubClass(); // arkts-interop-ts2s-ts-exception + } catch (e) { + let errObj = e as SubError; + return errObj.extraField === 123 && errObj.foo() === 456; + } + return false; + }, "errObj.extraField === 123 && errObj.foo() === 456"); + + test_helper.test(() => { + let flag = false + try { + throwRangeError(); // arkts-interop-ts2s-ts-exception + } catch (e) { + let errObj: RangeError = e as RangeError; + return errObj instanceof RangeError; + } + return flag; + }, "Throw: throwRangeError"); + + testCaseRet.push(test_helper.done()); +} + +export function test_object_literal(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_OBJECT_LITERAL"); + + test_helper.test(() => { + let obj: ObjectLiteralClass = { name: "hello" }; // arkts-obj-literal-generate-class-instance + return obj.name === "hello" && obj instanceof ObjectLiteralClass; + }, "obj.name === "hello""); + + test_helper.test(() => { + let obj: ObjectLiteralInter = { name: "hello" }; // arkts-obj-literal-generate-class-instance + return obj.name === "hello" && obj instanceof ObjectLiteralInter; + }, "obj.name === "hello""); + + testCaseRet.push(test_helper.done()); +} + +// 1 ArkTS使用TS装饰器 +// 规则名 arkts-interop-ts2s-no-ts-decorator +// case 1 类装饰器 top level +@MyClassDecorator // arkts-no-ts-decorators + arkts-interop-ts2s-no-ts-decorator +class K {} + +//case 2 类属性装饰器 +class MyClass { + @propertyDecorator// arkts-no-ts-decorators + myProperty: string; +} + +//case 3 方法装饰器 +class MathFunctions { + @methodDecorator// arkts-no-ts-decorators + double1(value: number): number { + return value; + } +} + +//case 4 方法装饰器 +class MyClass1 { + log(value: string, @parameterDecorator metadata: any) {// arkts-no-ts-decorators + console.log(Logged: ${value}); + } +} + +//case 5 访问器装饰器 +class Person { + private _name: string; + @accessorDecorator// arkts-no-ts-decorators + get name(): string { + return this._name; + } + set name(value: string) { + this._name = value; + } +} + +//case 6 访问器工厂 +class Person1 { + private _age: number; + @readonly(true)// arkts-no-ts-decorators + get age(): number { + return this._age; + } + set age(value: number) { + this._age = value; + } +} + +namespace NS{ + // case 7 类装饰器 top level + @MyClassDecorator// arkts-no-ts-decorators + arkts-interop-ts2s-no-ts-decorator + class K {} + + //case 8 类属性装饰器 + class MyClass { + @propertyDecorator// arkts-no-ts-decorators + myProperty: string; + } + + //case 9 方法装饰器 + class MathFunctions { + @methodDecorator// arkts-no-ts-decorators + double1(value: number): number { + return value; + } + } + + //case 10 方法装饰器 + class MyClass1 { + log(value: string, @parameterDecorator metadata: any) {// arkts-no-ts-decorators + console.log(Logged: ${value}); + } + } + + //case 11 访问器装饰器 + class Person { + private _name: string; + constructor(name: string) { + this._name = name; + } + @accessorDecorator// arkts-no-ts-decorators + get name(): string { + return this._name; + } + set name(value: string) { + this._name = value; + } + } + + //case 12 访问器工厂 + class Person1 { + private _age: number; + constructor(age: number) { + this._age = age; + } + @readonly1(true)// arkts-no-ts-decorators + get age(): number { + return this._age; + } + set age(value: number) { + this._age = value; + } + } +} + +export function test_ts_boxed_type(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_BOXED_TYPE"); + + test_helper.test(() => { + return typeof num_boxed === object; + }, "typeof num_boxed === object"); + + test_helper.test(() => { + return typeof bool_boxed === object; + }, "typeof bool_boxed === object"); + + test_helper.test(() => { + return typeof str_boxed === object; + }, "typeof str_boxed === object"); + + test_helper.test(() => { + return typeof bigint_boxed === object; + }, "typeof bigint_boxed === object"); + testCaseRet.push(test_helper.done()); +} + +export function test_ts_object_method(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_OBJECT_METHOD"); + + test_helper.test(() => { + ts_object_method(new Object2()) + ts_object_method_getOwnPropertyDescriptor(new Object2()) + ts_object_method_getOwnPropertyDescriptors(new Object2()) + ts_object_method_getOwnPropertyNames(new Object2()) + ts_object_method_hasOwn(new Object2()) + ts_object_method_isExtensible(new Object2()) + ts_object_method_isFrozen(new Object2()) + ts_object_method_isSealed(new Object2()) + ts_object_method_keys(new Object2()) + ts_object_method_keys(new Object2()) + ts_object_method_values(new Object2()) + return true; + }, "true"); + + test_helper.test(() => { + interface Iface { + a:number + } + let a1:Iface = {a:1} + ts_object_method(a1) + ts_object_method_getOwnPropertyDescriptor(a1) + ts_object_method_getOwnPropertyDescriptors(a1) + ts_object_method_getOwnPropertyNames(a1) + ts_object_method_hasOwn(a1) + ts_object_method_isExtensible(a1) + ts_object_method_isFrozen(a1) + ts_object_method_isSealed(a1) + ts_object_method_keys(a1) + ts_object_method_keys(a1) + ts_object_method_values(a1) + return true; + }, "true"); + + test_helper.test(() => { + ts_object_method(interObj) + return true; + }, "false"); + + testCaseRet.push(test_helper.done()); +} + +class Reflect2 { + a: string = 'hello' + getName() { return this.a } } -stringType = "test" //should pass +// 5 Object内置方法作用在ArkTS对象 +// 规则名 arkts-interop-ts2s-ts-object-on-static-instance +export function test_ts_reflect_method(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_REFLECT_METHOD"); + test_helper.test(() => { + ts_reflect_method(new Reflect2()) + ts_reflect_method_apply(new Reflect2()) + ts_reflect_method_defineProperty(new Reflect2()) + ts_reflect_method_deleteProperty(new Reflect2()) + ts_reflect_method_getOwnPropertyDescriptor(new Reflect2()) + ts_reflect_method_ownKeys(new Reflect2()) + ts_reflect_method_isExtensible(new Reflect2()) + ts_reflect_method_set(new Reflect2()) + ts_reflect_method_setPrototypeOf(new Reflect2()) + return true; + }, "reflect class 1.2 "); + + test_helper.test(() => { + interface Iface { + a:number + } + let a1:Iface = {a:1} + ts_reflect_method(a1) + ts_reflect_method_apply(a1) + ts_reflect_method_defineProperty(a1) + ts_reflect_method_deleteProperty(a1) + ts_reflect_method_getOwnPropertyDescriptor(a1) + ts_reflect_method_ownKeys(a1) + ts_reflect_method_isExtensible(a1) + ts_reflect_method_set(a1) + ts_reflect_method_setPrototypeOf(a1) + return true; + }, "reflect interface 1.2"); + + test_helper.test(() => { + ts_reflect_method(interObj) + ts_reflect_method_apply(interObj) + ts_reflect_method_defineProperty(interObj) + ts_reflect_method_deleteProperty(interObj) + ts_reflect_method_getOwnPropertyDescriptor(interObj) + ts_reflect_method_ownKeys(interObj) + ts_reflect_method_isExtensible(interObj) + ts_reflect_method_set(interObj) + ts_reflect_method_setPrototypeOf(interObj) + return true; + }, "reflect interObj 1.0 "); -enumType = "A"; //should fail + testCaseRet.push(test_helper.done()); +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json index 30f972d7571aad394d08a4d6866d4215b01f1090..aba8201c3cd00cb5da7f6057c99400e396f8b02c 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json +++ b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json @@ -15,63 +15,523 @@ ], "result": [ { - "line": 17, + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 15, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 19, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 18, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 72, "column": 1, - "endLine": 23, - "endColumn": 38, - "problem": "ImportAfterStatement", + "endLine": 72, + "endColumn": 13, + "problem": "ExplicitFunctionType", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 25, + "line": 72, "column": 1, - "endLine": 25, - "endColumn": 23, + "endLine": 72, + "endColumn": 13, "problem": "InteropDirectAccessToTSTypes", "suggest": "", "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 27, + "line": 75, "column": 1, - "endLine": 27, - "endColumn": 22, + "endLine": 75, + "endColumn": 9, "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, + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 25, + "endLine": 78, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 7, + "endLine": 82, + "endColumn": 21, "problem": "InteropTSFunctionInvoke", "suggest": "", "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" }, { - "line": 31, - "column": 3, - "endLine": 32, - "endColumn": 2, - "problem": "TsLikeCatchType", + "line": 91, + "column": 7, + "endLine": 91, + "endColumn": 22, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 7, + "endLine": 118, + "endColumn": 18, + "problem": "InteropTSFunctionInvoke", "suggest": "", - "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 7, + "endLine": 160, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 25, + "endLine": 160, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 34, + "line": 178, "column": 1, - "endLine": 34, + "endLine": 178, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 183, + "column": 3, + "endLine": 183, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 3, + "endLine": 189, + "endColumn": 19, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 22, + "endLine": 197, + "endColumn": 41, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 52, + "endLine": 197, + "endColumn": 55, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 3, + "endLine": 205, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 3, + "endLine": 217, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 3, + "endLine": 228, "endColumn": 20, - "problem": "InteropDirectAccessToTSTypes", + "problem": "DecoratorsNotSupported", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 5, + "endLine": 233, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 239, + "column": 5, + "endLine": 239, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 24, + "endLine": 247, + "endColumn": 43, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 54, + "endLine": 247, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 5, + "endLine": 258, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 5, + "endLine": 273, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 7, + "endLine": 284, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 25, + "endLine": 284, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 7, + "endLine": 305, + "endColumn": 60, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 25, + "endLine": 305, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 308, + "column": 26, + "endLine": 308, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 309, + "column": 51, + "endLine": 309, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 52, + "endLine": 310, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 311, + "column": 46, + "endLine": 311, + "endColumn": 53, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 312, + "column": 33, + "endLine": 312, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 39, + "endLine": 313, + "endColumn": 46, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 35, + "endLine": 314, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 315, + "column": 35, + "endLine": 315, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 31, + "endLine": 316, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 317, + "column": 31, + "endLine": 317, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 33, + "endLine": 318, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 7, + "endLine": 357, + "endColumn": 61, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 25, + "endLine": 357, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 3, + "endLine": 184, + "endColumn": 13, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 204, + "column": 11, + "endLine": 204, + "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": 216, + "column": 11, + "endLine": 216, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 234, + "column": 5, + "endLine": 234, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/unique_types.ets.autofix.json b/ets2panda/linter/test/interop/unique_types.ets.autofix.json index 14ba376badc88d5a1c4fc33670e5cd5e32c3b821..a15230739cb9029e8404475cf17292778f5d99e6 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.autofix.json +++ b/ets2panda/linter/test/interop/unique_types.ets.autofix.json @@ -15,85 +15,534 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 23, - "endColumn": 38, - "problem": "ImportAfterStatement", + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 15, + "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 25, - "column": 1, - "endLine": 25, - "endColumn": 23, + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 19, "problem": "InteropDirectAccessToTSTypes", - "autofix": [ - { - "start": 744, - "end": 775, - "replacementText": "objectLiteralType.setPropertyByName('name',ESObject.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, + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 18, "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 13, + "problem": "ExplicitFunctionType", "autofix": [ { - "start": 777, - "end": 807, - "replacementText": "intersectionType.setPropertyByName('name',ESObject.wrap(\"test\"))", - "line": 27, + "start": 1778, + "end": 1790, + "replacementText": "function_var.unsafeCall", + "line": 72, "column": 1, - "endLine": 27, - "endColumn": 22 + "endLine": 72, + "endColumn": 13 } ], "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { - "line": 30, + "line": 72, "column": 1, - "endLine": 30, + "endLine": 72, "endColumn": 13, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 9, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 25, + "endLine": 78, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 7, + "endLine": 82, + "endColumn": 21, "problem": "InteropTSFunctionInvoke", "suggest": "", "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" }, { - "line": 31, - "column": 3, - "endLine": 32, - "endColumn": 2, - "problem": "TsLikeCatchType", + "line": 91, + "column": 7, + "endLine": 91, + "endColumn": 22, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", "suggest": "", - "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" }, { - "line": 34, + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 7, + "endLine": 118, + "endColumn": 18, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 7, + "endLine": 160, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 25, + "endLine": 160, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 178, "column": 1, - "endLine": 34, + "endLine": 178, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 183, + "column": 3, + "endLine": 183, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 3, + "endLine": 189, + "endColumn": 19, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 22, + "endLine": 197, + "endColumn": 41, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 52, + "endLine": 197, + "endColumn": 55, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 3, + "endLine": 205, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 3, + "endLine": 217, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 3, + "endLine": 228, "endColumn": 20, - "problem": "InteropDirectAccessToTSTypes", + "problem": "DecoratorsNotSupported", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 5, + "endLine": 233, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 239, + "column": 5, + "endLine": 239, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 24, + "endLine": 247, + "endColumn": 43, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 54, + "endLine": 247, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 5, + "endLine": 258, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 5, + "endLine": 273, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 7, + "endLine": 284, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 25, + "endLine": 284, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 7, + "endLine": 305, + "endColumn": 60, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 25, + "endLine": 305, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 308, + "column": 26, + "endLine": 308, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 309, + "column": 51, + "endLine": 309, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 52, + "endLine": 310, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 311, + "column": 46, + "endLine": 311, + "endColumn": 53, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 312, + "column": 33, + "endLine": 312, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 39, + "endLine": 313, + "endColumn": 46, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 35, + "endLine": 314, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 315, + "column": 35, + "endLine": 315, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 31, + "endLine": 316, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 317, + "column": 31, + "endLine": 317, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 33, + "endLine": 318, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 7, + "endLine": 357, + "endColumn": 61, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 25, + "endLine": 357, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 3, + "endLine": 184, + "endColumn": 13, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 204, + "column": 11, + "endLine": 204, + "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": 216, + "column": 11, + "endLine": 216, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 234, + "column": 5, + "endLine": 234, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/unique_types.ets.json b/ets2panda/linter/test/interop/unique_types.ets.json index 3e8e488310b0cc25d757e85c0dad6e55c2c622c1..b8a27de8736fc9b9090ab6e4c9dbea95a025445f 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.json +++ b/ets2panda/linter/test/interop/unique_types.ets.json @@ -1,13 +1,127 @@ { + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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", + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 69, + "problem": "AnyType", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 7, + "endLine": 160, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 52, + "endLine": 197, + "endColumn": 55, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 54, + "endLine": 247, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 7, + "endLine": 284, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 7, + "endLine": 305, + "endColumn": 60, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 7, + "endLine": 357, + "endColumn": 61, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 3, + "endLine": 184, + "endColumn": 13, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 204, + "column": 11, + "endLine": 204, + "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": 216, + "column": 11, + "endLine": 216, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 234, + "column": 5, + "endLine": 234, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.ets b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets index 76dc6876ccb1e82d96fcc00a1e7f99d74ce192f2..07010c3c658a1f9076025d5a0b88d14d1f4ea968 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.migrate.ets +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets @@ -12,25 +12,391 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use static' import { - objectLiteralType, - intersectionType, - tsFunction, - stringType, - enumType + any_var, + unknown_var, + symbol_var, + function_var, + enum_var, + A, + B, + TestHelper, + throw_number, + throw_string, + throw_boolean, + throw_bigint, + throw_obj, + throw_error, + throwErrorSubClass, + SubError, + throwRangeError, + ObjectLiteralClass, + ObjectLiteralInter, + MyClassDecorator, + propertyDecorator, + methodDecorator, + parameterDecorator, + accessorDecorator, + readonly1, + num_boxed, + bool_boxed, + str_boxed, + bigint_boxed, + ts_object_method, + ts_object_method_getOwnPropertyDescriptor, + ts_object_method_getOwnPropertyDescriptors, + ts_object_method_getOwnPropertyNames, + ts_object_method_hasOwn, + ts_object_method_isExtensible, + ts_object_method_isFrozen, + ts_object_method_isSealed, + ts_object_method_keys, + ts_object_method_values, + interObj, + ts_reflect_method, + ts_reflect_method_apply, + ts_reflect_method_defineProperty, + ts_reflect_method_deleteProperty, + ts_reflect_method_getOwnPropertyDescriptor, + ts_reflect_method_ownKeys, + ts_reflect_method_isExtensible, + ts_reflect_method_set, + ts_reflect_method_setPrototypeOf } from "./ignore_files/unique_types"; -objectLiteralType.setPropertyByName('name',ESObject.wrap("test")) -intersectionType.setPropertyByName('name',ESObject.wrap("test")); +typeof any_var === 'object'; +typeof unknown_var === 'number'; +typeof symbol_var === 'object'; +function_var.unsafeCall() === true; +A.instance; +let obj: B = { name: "hello" }; +enum_var.a === 0; -try { -tsFunction(); -} catch (e) { +export function test_ts_non_standard_exception(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_NON_STANDARD_EXCEPTION"); + + test_helper.test(() => { + try { + throw_number(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as number === 123; + } + return false; + }, "e as number === 123"); + + test_helper.test(() => { + try { + throw_boolean(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as boolean === true; + } + return false; + }, "e as boolean === true"); + + test_helper.test(() => { + try { + throw_bigint(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as bigint === 111n; + } + return false; + }, "e as bigint === 111n"); + + test_helper.test(() => { + try { + throw_string(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e as string === "error"; + } + return false; + }, "e as string === "error""); + + test_helper.test(() => { + try { + throw_obj(); // arkts-interop-ts2s-ts-exception + } catch (e) { + return e.name === "error"; + } + return false; + }, "e.name === "error""); + + test_helper.test(() => { + try { + throw_error(); + } catch (e) { + let errObj: Error = e as Error; + return errObj.name === "error"; + } + return false; + }, "errObj.name === "error""); + + test_helper.test(() => { + try { + throwErrorSubClass(); // arkts-interop-ts2s-ts-exception + } catch (e) { + let errObj = e as SubError; + return errObj.extraField === 123 && errObj.foo() === 456; + } + return false; + }, "errObj.extraField === 123 && errObj.foo() === 456"); + + test_helper.test(() => { + let flag = false + try { + throwRangeError(); // arkts-interop-ts2s-ts-exception + } catch (e) { + let errObj: RangeError = e as RangeError; + return errObj instanceof RangeError; + } + return flag; + }, "Throw: throwRangeError"); + + testCaseRet.push(test_helper.done()); +} + +export function test_object_literal(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_OBJECT_LITERAL"); + + test_helper.test(() => { + let obj: ObjectLiteralClass = { name: "hello" }; // arkts-obj-literal-generate-class-instance + return obj.name === "hello" && obj instanceof ObjectLiteralClass; + }, "obj.name === "hello""); + + test_helper.test(() => { + let obj: ObjectLiteralInter = { name: "hello" }; // arkts-obj-literal-generate-class-instance + return obj.name === "hello" && obj instanceof ObjectLiteralInter; + }, "obj.name === "hello""); + + testCaseRet.push(test_helper.done()); +} + +// 1 ArkTS使用TS装饰器 +// 规则名 arkts-interop-ts2s-no-ts-decorator +// case 1 类装饰器 top level +@MyClassDecorator // arkts-no-ts-decorators + arkts-interop-ts2s-no-ts-decorator +class K {} + +//case 2 类属性装饰器 +class MyClass { + @propertyDecorator// arkts-no-ts-decorators + myProperty: string; +} + +//case 3 方法装饰器 +class MathFunctions { + @methodDecorator// arkts-no-ts-decorators + double1(value: number): number { + return value; + } +} + +//case 4 方法装饰器 +class MyClass1 { + log(value: string, @parameterDecorator metadata: any) {// arkts-no-ts-decorators + console.log(Logged: ${value}); + } +} + +//case 5 访问器装饰器 +class Person { + private _name: string; + @accessorDecorator// arkts-no-ts-decorators + get name(): string { + return this._name; + } + set name(value: string) { + this._name = value; + } +} + +//case 6 访问器工厂 +class Person1 { + private _age: number; + @readonly(true)// arkts-no-ts-decorators + get age(): number { + return this._age; + } + set age(value: number) { + this._age = value; + } +} + +namespace NS{ + // case 7 类装饰器 top level + @MyClassDecorator// arkts-no-ts-decorators + arkts-interop-ts2s-no-ts-decorator + class K {} + + //case 8 类属性装饰器 + class MyClass { + @propertyDecorator// arkts-no-ts-decorators + myProperty: string; + } + + //case 9 方法装饰器 + class MathFunctions { + @methodDecorator// arkts-no-ts-decorators + double1(value: number): number { + return value; + } + } + + //case 10 方法装饰器 + class MyClass1 { + log(value: string, @parameterDecorator metadata: any) {// arkts-no-ts-decorators + console.log(Logged: ${value}); + } + } + + //case 11 访问器装饰器 + class Person { + private _name: string; + constructor(name: string) { + this._name = name; + } + @accessorDecorator// arkts-no-ts-decorators + get name(): string { + return this._name; + } + set name(value: string) { + this._name = value; + } + } + + //case 12 访问器工厂 + class Person1 { + private _age: number; + constructor(age: number) { + this._age = age; + } + @readonly1(true)// arkts-no-ts-decorators + get age(): number { + return this._age; + } + set age(value: number) { + this._age = value; + } + } +} + +export function test_ts_boxed_type(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_BOXED_TYPE"); + + test_helper.test(() => { + return typeof num_boxed === object; + }, "typeof num_boxed === object"); + + test_helper.test(() => { + return typeof bool_boxed === object; + }, "typeof bool_boxed === object"); + + test_helper.test(() => { + return typeof str_boxed === object; + }, "typeof str_boxed === object"); + + test_helper.test(() => { + return typeof bigint_boxed === object; + }, "typeof bigint_boxed === object"); + testCaseRet.push(test_helper.done()); +} + +export function test_ts_object_method(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_OBJECT_METHOD"); + + test_helper.test(() => { + ts_object_method(new Object2()) + ts_object_method_getOwnPropertyDescriptor(new Object2()) + ts_object_method_getOwnPropertyDescriptors(new Object2()) + ts_object_method_getOwnPropertyNames(new Object2()) + ts_object_method_hasOwn(new Object2()) + ts_object_method_isExtensible(new Object2()) + ts_object_method_isFrozen(new Object2()) + ts_object_method_isSealed(new Object2()) + ts_object_method_keys(new Object2()) + ts_object_method_keys(new Object2()) + ts_object_method_values(new Object2()) + return true; + }, "true"); + + test_helper.test(() => { + interface Iface { + a:number + } + let a1:Iface = {a:1} + ts_object_method(a1) + ts_object_method_getOwnPropertyDescriptor(a1) + ts_object_method_getOwnPropertyDescriptors(a1) + ts_object_method_getOwnPropertyNames(a1) + ts_object_method_hasOwn(a1) + ts_object_method_isExtensible(a1) + ts_object_method_isFrozen(a1) + ts_object_method_isSealed(a1) + ts_object_method_keys(a1) + ts_object_method_keys(a1) + ts_object_method_values(a1) + return true; + }, "true"); + + test_helper.test(() => { + ts_object_method(interObj) + return true; + }, "false"); + + testCaseRet.push(test_helper.done()); +} + +class Reflect2 { + a: string = 'hello' + getName() { return this.a } } -stringType = "test" //should pass +// 5 Object内置方法作用在ArkTS对象 +// 规则名 arkts-interop-ts2s-ts-object-on-static-instance +export function test_ts_reflect_method(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_TS_REFLECT_METHOD"); + test_helper.test(() => { + ts_reflect_method(new Reflect2()) + ts_reflect_method_apply(new Reflect2()) + ts_reflect_method_defineProperty(new Reflect2()) + ts_reflect_method_deleteProperty(new Reflect2()) + ts_reflect_method_getOwnPropertyDescriptor(new Reflect2()) + ts_reflect_method_ownKeys(new Reflect2()) + ts_reflect_method_isExtensible(new Reflect2()) + ts_reflect_method_set(new Reflect2()) + ts_reflect_method_setPrototypeOf(new Reflect2()) + return true; + }, "reflect class 1.2 "); + + test_helper.test(() => { + interface Iface { + a:number + } + let a1:Iface = {a:1} + ts_reflect_method(a1) + ts_reflect_method_apply(a1) + ts_reflect_method_defineProperty(a1) + ts_reflect_method_deleteProperty(a1) + ts_reflect_method_getOwnPropertyDescriptor(a1) + ts_reflect_method_ownKeys(a1) + ts_reflect_method_isExtensible(a1) + ts_reflect_method_set(a1) + ts_reflect_method_setPrototypeOf(a1) + return true; + }, "reflect interface 1.2"); + + test_helper.test(() => { + ts_reflect_method(interObj) + ts_reflect_method_apply(interObj) + ts_reflect_method_defineProperty(interObj) + ts_reflect_method_deleteProperty(interObj) + ts_reflect_method_getOwnPropertyDescriptor(interObj) + ts_reflect_method_ownKeys(interObj) + ts_reflect_method_isExtensible(interObj) + ts_reflect_method_set(interObj) + ts_reflect_method_setPrototypeOf(interObj) + return true; + }, "reflect interObj 1.0 "); -enumType = "A"; //should fail + testCaseRet.push(test_helper.done()); +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.json b/ets2panda/linter/test/interop/unique_types.ets.migrate.json index 6e09d425c502ac388ee42e63dd94a6045ed3e8b4..28d850fbfbeed0a1df4c975c1c8ada1b701b39b6 100644 --- a/ets2panda/linter/test/interop/unique_types.ets.migrate.json +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.json @@ -15,44 +15,514 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 23, - "endColumn": 38, - "problem": "ImportAfterStatement", + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 15, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 19, + "problem": "InteropDirectAccessToTSTypes", "suggest": "", - "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", "severity": "ERROR" }, { - "line": 30, + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 18, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 72, "column": 1, - "endLine": 30, + "endLine": 72, "endColumn": 13, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 9, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 25, + "endLine": 78, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 7, + "endLine": 82, + "endColumn": 21, "problem": "InteropTSFunctionInvoke", "suggest": "", "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" }, { - "line": 31, - "column": 3, - "endLine": 32, - "endColumn": 2, - "problem": "TsLikeCatchType", + "line": 91, + "column": 7, + "endLine": 91, + "endColumn": 22, + "problem": "InteropTSFunctionInvoke", "suggest": "", - "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", "severity": "ERROR" }, { - "line": 34, + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 21, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 7, + "endLine": 118, + "endColumn": 18, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 7, + "endLine": 160, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 25, + "endLine": 160, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 178, "column": 1, - "endLine": 34, + "endLine": 178, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 183, + "column": 3, + "endLine": 183, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 3, + "endLine": 189, + "endColumn": 19, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 22, + "endLine": 197, + "endColumn": 41, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 52, + "endLine": 197, + "endColumn": 55, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 3, + "endLine": 205, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 3, + "endLine": 217, + "endColumn": 18, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 3, + "endLine": 228, "endColumn": 20, - "problem": "InteropDirectAccessToTSTypes", + "problem": "DecoratorsNotSupported", "suggest": "", - "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 5, + "endLine": 233, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 239, + "column": 5, + "endLine": 239, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 24, + "endLine": 247, + "endColumn": 43, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 247, + "column": 54, + "endLine": 247, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 5, + "endLine": 258, + "endColumn": 23, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 5, + "endLine": 273, + "endColumn": 21, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 7, + "endLine": 284, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 25, + "endLine": 284, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 7, + "endLine": 305, + "endColumn": 60, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 305, + "column": 25, + "endLine": 305, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 308, + "column": 26, + "endLine": 308, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 309, + "column": 51, + "endLine": 309, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 52, + "endLine": 310, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 311, + "column": 46, + "endLine": 311, + "endColumn": 53, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 312, + "column": 33, + "endLine": 312, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 39, + "endLine": 313, + "endColumn": 46, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 35, + "endLine": 314, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 315, + "column": 35, + "endLine": 315, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 31, + "endLine": 316, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 317, + "column": 31, + "endLine": 317, + "endColumn": 38, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 33, + "endLine": 318, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 325, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 7, + "endLine": 357, + "endColumn": 61, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 25, + "endLine": 357, + "endColumn": 35, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 5, + "endLine": 374, + "endColumn": 6, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 3, + "endLine": 184, + "endColumn": 13, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 204, + "column": 11, + "endLine": 204, + "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": 216, + "column": 11, + "endLine": 216, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '_age' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 234, + "column": 5, + "endLine": 234, + "endColumn": 15, + "problem": "StrictDiagnostic", + "suggest": "Property 'myProperty' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'myProperty' 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/interop/unique_types2.ets b/ets2panda/linter/test/interop/unique_types2.ets new file mode 100644 index 0000000000000000000000000000000000000000..245729ec2cf9007e5ad193d6de5ad53c30acb744 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types2.ets @@ -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. +*/ +import { + NameAndEmail, + WithoutEmail, + PrimaryColors, + PrimitiveValues, + CleanData, + AddParams, + PerParams, + UserType, + PointInstance, + identity, + thisParameterType, + WithoutThis, + ClassThisType, + ShoutGreeting, + QuietGreeting, + CapitalizedWord, + UncapitalizedWord, + getCapitalize +} from './ignore_files/unique_types2'; + +//tools +const res :ShoutGreeting = 'HELLO'; //error + +const withoutThis: WithoutThis = {name: 'aaa'}; //error +class AA{ + private email:WithoutEmail={name:'1',age:10}; //error + set(color:PrimaryColors){ //error + } + get():PrimitiveValues|undefined{ //error + this.email as thisParameterType //error + const cc:ClassThisType = {} //error + return ; + } +} +function test(user:UserType,point:PointInstance,per:PerParams){} //error*3 +@Entry +@Component +struct MyComponent { + // 1. Pick/Omit 示例 + @State user: NameAndEmail = { name: 'Alice', email: 'alice@example.com' }; //error + @State partialUser: WithoutEmail = { name: 'Bob', age: 30 }; //error + + // 2. Exclude/Extract 示例 + @State primaryColor: PrimaryColors = 'red'; //error + @State primitiveValue: PrimitiveValues = true; //error + + // 3. NonNullable 示例 + @State validData: CleanData = 'valid'; //error + + // 4. Parameters/ConstructorParameters 示例 + private handleParams = (params: AddParams) => { //error + } + + // 5. ReturnType/InstanceType 示例 + @State userData: UserType = { id: 1, name: 'Charlie' }; //error + private point: PointInstance = { x: 10, y: 20 }; //error + + // 6. NoInfer 示例 + private useIdentity = () => { + const numResult = identity(123, 456); //error + // const errorResult = identity(123, 'abc'); //error + console.log('Identity result:', numResult); + } + + // 7. ThisParameterType/OmitThisParameter 示例 + private thisContext: thisParameterType = { name: 'Context' }; //error + private noThisFunc: WithoutThis = (x) => { //error + console.log('Without this:', x); + } + + // 8. 字符串工具类型示例 + @State shout: ShoutGreeting = 'HELLO'; //error + @State quiet: QuietGreeting = 'hello'; //error + @State capitalized: CapitalizedWord = 'Hello'; //error + @State uncapitalized: UncapitalizedWord = 'hello'; //error + + // 9. getCapitalize 函数 + computedWord= getCapitalize(); //error + + build() { + Column() { + // 显示用户信息 + Text(`Name: ${this.user.name}`) + Text(`Email: ${this.user.email}`) + + // 显示颜色和值 + Text(`Primary Color: ${this.primaryColor}`) + Text(`Primitive Value: ${this.primitiveValue}`) + + // 显示字符串转换结果 + Text(`Shout: ${this.shout}`) + Text(`Quiet: ${this.quiet}`) + Text(`Capitalized: ${this.capitalized}`) + Text(`Computed: ${this.computedWord}`) + + // 按钮触发函数 + Button('Call Identity') + .onClick(this.useIdentity) + + Button('Submit Parameters') + .onClick(() => this.handleParams([123, 'test'])) + } + .width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types2.ets.args.json b/ets2panda/linter/test/interop/unique_types2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types2.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/unique_types2.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..fcdd5c1d783479db12bce84bcab3f335ca8c7c6e --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types2.ets.arkts2.json @@ -0,0 +1,578 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 25, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 20, + "endLine": 39, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 34, + "endLine": 39, + "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": 41, + "column": 19, + "endLine": 41, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 32, + "endLine": 41, + "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": 42, + "column": 15, + "endLine": 42, + "endColumn": 28, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 11, + "endLine": 44, + "endColumn": 26, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 21, + "endLine": 45, + "endColumn": 38, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 16, + "endLine": 46, + "endColumn": 29, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 20, + "endLine": 50, + "endColumn": 28, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 35, + "endLine": 50, + "endColumn": 48, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 53, + "endLine": 50, + "endColumn": 62, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 16, + "endLine": 55, + "endColumn": 28, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 31, + "endLine": 55, + "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": 56, + "column": 23, + "endLine": 56, + "endColumn": 35, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 38, + "endLine": 56, + "endColumn": 39, + "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": 24, + "endLine": 59, + "endColumn": 37, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 26, + "endLine": 60, + "endColumn": 41, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 21, + "endLine": 63, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 35, + "endLine": 66, + "endColumn": 44, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 20, + "endLine": 70, + "endColumn": 28, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 31, + "endLine": 70, + "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": 71, + "column": 18, + "endLine": 71, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 23, + "endLine": 75, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 24, + "endLine": 81, + "endColumn": 41, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 44, + "endLine": 81, + "endColumn": 45, + "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": 23, + "endLine": 82, + "endColumn": 34, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 17, + "endLine": 87, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 17, + "endLine": 88, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 23, + "endLine": 89, + "endColumn": 38, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 25, + "endLine": 90, + "endColumn": 42, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 17, + "endLine": 93, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 18, + "endLine": 116, + "endColumn": 56, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 2, + "endLine": 51, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 2, + "endLine": 52, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 4, + "endLine": 55, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 4, + "endLine": 56, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 4, + "endLine": 59, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 4, + "endLine": 60, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 4, + "endLine": 63, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 4, + "endLine": 70, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 4, + "endLine": 87, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 4, + "endLine": 88, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 4, + "endLine": 89, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 4, + "endLine": 90, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 5, + "endLine": 96, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 7, + "endLine": 98, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 7, + "endLine": 99, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 7, + "endLine": 102, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 7, + "endLine": 108, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 7, + "endLine": 112, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 7, + "endLine": 115, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types2.ets.json b/ets2panda/linter/test/interop/unique_types2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ee4603f669d4004aed50443f8205fcf73b955ba3 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types2.ets.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": 39, + "column": 34, + "endLine": 39, + "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": 41, + "column": 32, + "endLine": 41, + "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": 55, + "column": 31, + "endLine": 55, + "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": 56, + "column": 38, + "endLine": 56, + "endColumn": 39, + "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": 31, + "endLine": 70, + "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": 81, + "column": 44, + "endLine": 81, + "endColumn": 45, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 18, + "endLine": 116, + "endColumn": 56, + "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/interop/unique_types3.ets b/ets2panda/linter/test/interop/unique_types3.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e80761e144ed99290aa56d7c7bfa9ebce63aeee --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types3.ets @@ -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. +*/ +import { + any_var, + symbol_var, + user, + unknown_var, + function_var, + func_type2, + objectLiteral_var, + objectLiteral_var2, + objectLiteral_var3, + objectLiteral_var32, + objectLiteral_var4, + objectLiteral_var5, + objectLiteral_var51, + objectLiteral_var6, + enum_var, + func_type, + constructor_type, + objIndexSignature_var, + Intersection_obj, + KeyOf_Type, + de, + key, + keyFuns, + Keys, + SomeType, + Person, + Person1, + ElementType, + NameOrAddress, + getInfo, + IndexAccess, + UserValueTypes, + stringType, + NumbersOnly, + ReturnVal, + Num, + typeOf_type, + typeOf_type1, + templateLiteralType, + TemplateLiteralType, + NameChanged, + testTemplateLiteralType, + Test, + ReadonlyUser, + Partial, + OptionalUser, + Mapped, + sumType +} from "./ignore_files/unique_types2" + +class TestHelper { + test(arg0: () => boolean, arg1: string) { + throw new Error("Method not implemented."); + } + constructor(name: string) { + } +} +export function test_unique_type(testCaseRet: Array) { + let test_helper = new TestHelper("TEST_UNIQUE_TYPE"); + + test_helper.test(() => { + return typeof any_var === 'object' //error + }, "any_var ") + + test_helper.test(() => { + return typeof unknown_var === 'number' //error + }, "unknown_var ") + + test_helper.test(() => { + return typeof symbol_var === 'object' //error + }, "symbol_var ") + + test_helper.test(() => { + return function_var() === true //error + }, "function_var ") + + test_helper.test(() => { + return enum_var.a === 0 //error + }, "enum_var ") + + test_helper.test(() => { + const res = new objectLiteral_var6().set({}); //error + const res2 = new objectLiteral_var6().set1(true); //error + const res3 = new objectLiteral_var6().set2({},true); //error + const res3 = new objectLiteral_var6().set3(); + return typeof res === 'object' + }, "objectLiteral_var7 ") + + test_helper.test(() => { + const res = new objectLiteral_var6().get(); //error + const res2 = new objectLiteral_var6().get1(); //error + const res3 = new objectLiteral_var6().get2(); //error + const res4 = new objectLiteral_var6().get3(); //error + const res5 = new objectLiteral_var6().get4(); + return typeof res === 'object' + }, "objectLiteral_var6 ") + + test_helper.test(() => { + typeof objectLiteral_var2 === 'object' //error + typeof objectLiteral_var3 === 'object' + typeof objectLiteral_var32 === 'object' //error + typeof objectLiteral_var4 === 'object' //error + typeof objectLiteral_var5 === 'object' //error + typeof objectLiteral_var51 === 'object' //error + return typeof objectLiteral_var === 'object' //error + }, "objectLiteral_var ") + + test_helper.test(() => { + console.log(typeOf_type) + console.log(typeOf_type1+'') //error + return typeof user === 'object' //error + }, "typeof") + + test_helper.test(() => { + let fun: func_type = (arg: number) => { //error + return arg.toString(); + }; + let fun2: func_type2 = (arg: number) => { //error + }; + return fun2(1) === '111' + }, "func_type ") + + test_helper.test(() => { + return typeof user === 'object' //error + }, "user ") + + test_helper.test(() => { + // const aa = '' as SomeType; + return typeof ('object' as SomeType) === 'object' //error + }, "SomeType ") + + + test_helper.test(() => { + return objIndexSignature_var[0] === "zero" //error + }, "objIndexSignature_var ") + + test_helper.test(() => { + return Intersection_obj.a === 10 && Intersection_obj.b === 'hello' //error*2 + }, "Intersection_obj ") + + test_helper.test(() => { + let keyof_var1: KeyOf_Type = 'a'; //error + let kk = de; //error + console.log(key) //error + keyFuns(); //error + const keys = new Keys(); + keys.set(undefined); //error + new Keys().get(); //error + keys.get1(); //error + return keyof_var1 === 'a' + }, "KeyOf_Type ") + + test_helper.test(() => { + let a :Person= {name:'a',age:1}; //error + a=Person1; //error + const b = 'a' as ElementType; //error + getInfo(b) as NameOrAddress; //error*2 + typeof new IndexAccess().par; //error + const indexAcc = new IndexAccess(); + indexAcc.set('',''); //error + indexAcc.get(''); //error + let c = '' as UserValueTypes //error + return typeof a === 'object' + }, "indexed access type") + + test_helper.test(() => { + new Test().returnStr(); //error? + return typeof stringType === 'object' //error? + }, "stringType ") + + test_helper.test(() => { + const c:NumbersOnly|undefined = undefined; //error + let d:ReturnVal = c as Num; //error*2 + return typeof c === 'boolean' + }, "conditional types ") + + test_helper.test(() => { + const c:ReadonlyUser|OptionalUser|undefined = undefined; //error*2 + let d:Mapped|boolean = false; //error + let e : Partial; //error + return typeof c === 'boolean' + }, "mapped types ") + + test_helper.test(() => { + const res: NameChanged = testTemplateLiteralType(''); //error*2 + let b :TemplateLiteralType; //error + return typeof templateLiteralType !== "undefined" //error + }, "templateLiteralType ") + + test_helper.test(() => { + let instance = new constructor_type("Alice"); //error + return instance.name === 'Alice' + }, "constructor_type ") + + test_helper.test(() => { + return typeof sumType !== "undefined" //error + }, "sumType ") + +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types3.ets.args.json b/ets2panda/linter/test/interop/unique_types3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types3.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/unique_types3.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..88d820858d0642c2bd65fe561d5f034e00ed226f --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types3.ets.arkts2.json @@ -0,0 +1,698 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 77, + "column": 19, + "endLine": 77, + "endColumn": 26, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 19, + "endLine": 85, + "endColumn": 29, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 12, + "endLine": 89, + "endColumn": 24, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 12, + "endLine": 89, + "endColumn": 24, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 12, + "endLine": 93, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 17, + "endLine": 97, + "endColumn": 49, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 42, + "endLine": 97, + "endColumn": 45, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 46, + "endLine": 97, + "endColumn": 47, + "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": 18, + "endLine": 98, + "endColumn": 53, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 43, + "endLine": 98, + "endColumn": 47, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 18, + "endLine": 99, + "endColumn": 56, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 43, + "endLine": 99, + "endColumn": 47, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 48, + "endLine": 99, + "endColumn": 49, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 18, + "endLine": 100, + "endColumn": 49, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 42, + "endLine": 105, + "endColumn": 45, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 43, + "endLine": 106, + "endColumn": 47, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 43, + "endLine": 107, + "endColumn": 47, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 43, + "endLine": 108, + "endColumn": 47, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 12, + "endLine": 114, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 12, + "endLine": 116, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 12, + "endLine": 117, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 12, + "endLine": 118, + "endColumn": 30, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 12, + "endLine": 119, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 19, + "endLine": 120, + "endColumn": 36, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 17, + "endLine": 125, + "endColumn": 29, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 19, + "endLine": 126, + "endColumn": 23, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 14, + "endLine": 130, + "endColumn": 23, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 15, + "endLine": 133, + "endColumn": 25, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 19, + "endLine": 139, + "endColumn": 23, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 32, + "endLine": 144, + "endColumn": 40, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 12, + "endLine": 149, + "endColumn": 36, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 12, + "endLine": 149, + "endColumn": 33, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 12, + "endLine": 153, + "endColumn": 28, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 41, + "endLine": 153, + "endColumn": 57, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 21, + "endLine": 157, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 14, + "endLine": 158, + "endColumn": 16, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 17, + "endLine": 159, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 5, + "endLine": 160, + "endColumn": 12, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 10, + "endLine": 162, + "endColumn": 13, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 16, + "endLine": 163, + "endColumn": 19, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 10, + "endLine": 164, + "endColumn": 14, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 12, + "endLine": 169, + "endColumn": 18, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 20, + "endLine": 169, + "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": 170, + "column": 7, + "endLine": 170, + "endColumn": 14, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 22, + "endLine": 171, + "endColumn": 33, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 5, + "endLine": 172, + "endColumn": 12, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 19, + "endLine": 172, + "endColumn": 32, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 30, + "endLine": 173, + "endColumn": 33, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 14, + "endLine": 175, + "endColumn": 17, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 14, + "endLine": 176, + "endColumn": 17, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 19, + "endLine": 177, + "endColumn": 33, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 13, + "endLine": 187, + "endColumn": 24, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 188, + "column": 11, + "endLine": 188, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 188, + "column": 28, + "endLine": 188, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 13, + "endLine": 193, + "endColumn": 25, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 26, + "endLine": 193, + "endColumn": 38, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 11, + "endLine": 194, + "endColumn": 17, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 13, + "endLine": 195, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 16, + "endLine": 200, + "endColumn": 27, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 30, + "endLine": 200, + "endColumn": 57, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 30, + "endLine": 200, + "endColumn": 53, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 12, + "endLine": 201, + "endColumn": 31, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 202, + "column": 19, + "endLine": 202, + "endColumn": 38, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 24, + "endLine": 206, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 24, + "endLine": 206, + "endColumn": 40, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 19, + "endLine": 211, + "endColumn": 26, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 188, + "column": 23, + "endLine": 188, + "endColumn": 31, + "problem": "StrictDiagnostic", + "suggest": "Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.", + "rule": "Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types3.ets.json b/ets2panda/linter/test/interop/unique_types3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ba08ebc2873f575bc7978e7ac86eff69ea2a415b --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types3.ets.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": 97, + "column": 46, + "endLine": 97, + "endColumn": 47, + "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": 48, + "endLine": 99, + "endColumn": 49, + "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": 12, + "endLine": 149, + "endColumn": 36, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 20, + "endLine": 169, + "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": 188, + "column": 23, + "endLine": 188, + "endColumn": 31, + "problem": "StrictDiagnostic", + "suggest": "Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.", + "rule": "Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/@ohos.taskpool.ets b/ets2panda/linter/test/main/@ohos.taskpool.ets new file mode 100755 index 0000000000000000000000000000000000000000..eef90ba56a6623ce649296e031f578a85adbab32 --- /dev/null +++ b/ets2panda/linter/test/main/@ohos.taskpool.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 namespace taskpool{ + export function isConcurrent(param:func):boolean { + return true + } + export class Task { + constructor(func: Function, ...args: Object[]){} + setTransferList(transfer?: ArrayBuffer[]): void{} + setCloneList(cloneList: Object[] | ArrayBuffer[]): void{} + } +} +export namespace otherTaskPool{ + export function isConcurrent(param:func):boolean { + return true + } + + export class Task { + constructor(func: Function, ...args: Object[]){} + setTransferList(transfer?: ArrayBuffer[]): void{} + setCloneList(cloneList: Object[] | ArrayBuffer[]): void{} + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/@ohos.taskpool.ets.args.json b/ets2panda/linter/test/main/@ohos.taskpool.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..0adede204e309a92c8aac08d89f6af16d9c93f78 --- /dev/null +++ b/ets2panda/linter/test/main/@ohos.taskpool.ets.args.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." + ], + "mode": { + } +} diff --git a/ets2panda/linter/test/main/@ohos.taskpool.ets.json b/ets2panda/linter/test/main/@ohos.taskpool.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/@ohos.taskpool.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/animatable_extend_decorator_1.ets.arkts2.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.arkts2.json index 5734f269a9f52d90ced6725f98e61bd3b8a17b2d..dc35b3d86cc85c6bcd48c86219c68c2bd94edae5 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 @@ -31,7 +31,7 @@ "endColumn": 18, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AnimatableExtend\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 50, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 c75ea9c0cb450cbe73af73f0253edb30a6b7e17c..2fca3e3f3acaa5e6404fb8e9c8c4b4a48f693dfc 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,7 +24,11 @@ { "start": 605, "end": 688, - "replacementText": "@AnimatableExtend\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": "", @@ -41,11 +45,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AnimatableExtend\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Curve\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n TextAttribute,\n AnimatableExtend,\n Entry,\n Component,\n State,\n Column,\n Text,\n Curve,\n Button,\n} from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 1c0c40caa7491cddffb43f33ee27a0e153bab635..5c7ce3b76c6c0dce8f111756d79c1425f0a5ba8b 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets @@ -13,7 +13,17 @@ * limitations under the License. */ -import { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; +import { + TextAttribute, + AnimatableExtend, + Entry, + Component, + State, + Column, + Text, + Curve, + Button, +} from '@kit.ArkUI'; @AnimatableExtend function animatableWidth(this: TextAttribute, width: number): this { 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 index 32075de8acc822612c282834429443c8f3af2fbd..7ed822c1590f6f80ab5299df543c26d3c84054de 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 20, + "line": 30, "column": 5, - "endLine": 20, + "endLine": 30, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 31, "column": 12, - "endLine": 21, + "endLine": 31, "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 29, "column": 26, - "endLine": 19, + "endLine": 29, "endColumn": 30, "problem": "InvalidIdentifier", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 29, "column": 63, - "endLine": 19, + "endLine": 29, "endColumn": 67, "problem": "ThisType", "suggest": "", diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets b/ets2panda/linter/test/main/arkts-array-type-immutable.ets index 75a02116dd78aca7e564933a329955ca512e8641..3c018c68ab24c13ba22459b3696df7c95d28fe6c 100644 --- a/ets2panda/linter/test/main/arkts-array-type-immutable.ets +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets @@ -34,4 +34,139 @@ 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 +} + +let arrayTypeImmutableA2: [number] = [1]; +let arrayTypeImmutableB2: [number | string] = arrayTypeImmutableA2; // error + +class ArrayTypeImmutableA{ + arrayTypeImmutableA: number[] = [1]; + arrayTypeImmutableB: (number | string)[] = this.arrayTypeImmutableA; // error + arrayTypeImmutableB1: (number | string)[] = this.arrayTypeImmutableA; // error + + arrayTypeImmutableA2: [number] = [1]; + arrayTypeImmutableB2: [number | string] = arrayTypeImmutableA2; // error + arrayTypeImmutableB21: [number | string] = this.arrayTypeImmutableA2; // error +} + +interface IA { + ia: string; +} + +type TA = string | IA + +interface IB { + i: TA|TA[] +} + +class CA { + static fun(...a: IB[]): void{}; +} + +CA.fun({ + i: [ { ia: '1'}, { ia: '2'}, { ia: '3'}, ] as IA[] // error +} as IB) + + +class A { + a: number[] = [-11,0]; + arrayData: (number| string| boolean)[] = [1, 'hi'] + arrs: (number| boolean)[] = new A().a //error + val: (number|string|boolean) [] = new A().arrayData + A() { + const val1 = new A().a + let array2: (string | number | boolean)[] = val1 //error + } + aa(ss:(number| boolean)[]) { + ss = this.a //error + } + cc(): (boolean| number)[] { + return [true, 33]; + } + dd(): (boolean| string| A)[] { + return [true, 'hello', new A()]; + } + ee() { + let ccVal: (boolean | number | boolean)[] = this.cc() + return ccVal; + } + + ff() { + let array: (number| boolean|string)[] = newArr; //error + return array; + } + gg() { + return this.arrs; + } +} + +function test2():(string|number|boolean)[] { + return ['s', 3.14, true]; +} +function test3() { + let obj: A = new A() + return obj.dd(); +} + +let objA: A = new A() + +const newArr: (number| boolean)[] = [1, true] +const newArr1: (number|string|boolean)[] = [1, '3.14', true] +const array: (number | boolean|string)[] = newArr1 +const newArr2: (string|number|boolean)[] = ['s', 3.14, false] +const array1: (number | string | boolean)[] = newArr2 +const array2: (string | number | boolean)[] = newArr1 + +let tt: (boolean | number | boolean)[] = this.test2() //error +let gg: (boolean | number | boolean)[] = new A().ee() +let ff = new A().ff() +let hh: (boolean | number | string)[] =ff +let mm: (boolean | number | boolean)[] = objA.gg(); +let test: (boolean | A | string)[] = test3() + +let array13: (number|boolean|string)[] = newArr as (number|string)[] //error +let array14: (number|boolean|number)[] = [3.14, true] as (number|boolean)[] +let array15: (boolean|number)[] = array as (number|boolean)[] //error +let array16: (boolean | number | boolean)[] = objA.gg() as (boolean | number)[] +let tuple15: (number|boolean|string)[] = this.test2() as (string|number|boolean)[] +let tuple16: (number|boolean)[] = array as [number, number, boolean] +let array17: (number|string|boolean)[] = ['s', 3.14, true] as (number|string|boolean)[] +const array18 = Array.from({ length: 5 }, (_, index) => index % 2 === 0 ? index : index % 3 === 0); +let array19: (number|boolean)[] = array18 as (number)[] //error +const originalArray: number[] = [1, 2, 3, 4, 5]; +const array20 = originalArray.map((value) => value % 2 === 0 ? true : value * 2); +let array21: [number, boolean] = array20 as [number, boolean] +let array22: (number|string)[] = array20 as (number)[] //error +const array23: (number)[] = [1, 2, 3, 4, 5]; + +let aaa: number[] = [1] +let bbb: (number | string)[] = aaa //error +const fn29: Function[] = []; +function bar(): T[] { + return []; +} +let a: number[] = []; +let repairableArr: Array = new Array(); +repairableArr = new Array(3); +Reflect.apply(() => {}, objA, []); +if (handler.apply) handler.apply(objA, objA, []); + +let readonlyArr: ReadonlyArray = []; +let arr66 = new Array(); +readonlyArr = arr66; //error + +let stringArray: string[] = [] +let correctArr: (string | number)[] = [] + +const Foo = (): string[] => stringArray; + +const FooBar = (): (string | number)[] => stringArray; +const Baz = (): (string | number)[] => correctArr; + +async function Foo_a(): Promise<(string| number)[]> { + return stringArray; +} + +async function Foo_b(): Promise<(string| number)[]> { + return correctArr; +} 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 index 802ecf8492f3cd9b72db09b1e1bc5f30e6b318a4..8ef0297136e121f20ea195d5538589891b9259ce 100644 --- a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 31, "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 7, "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 9, "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, { @@ -51,7 +51,17 @@ "endColumn": 54, "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 35, + "endLine": 32, + "endColumn": 40, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -61,7 +71,377 @@ "endColumn": 8, "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 67, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 71, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 72, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 3, + "endLine": 48, + "endColumn": 66, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 3, + "endLine": 49, + "endColumn": 72, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 63, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 40, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 9, + "endLine": 78, + "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 16, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 9, + "endLine": 95, + "endColumn": 51, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 10, + "endLine": 106, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 5, + "endLine": 120, + "endColumn": 54, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 5, + "endLine": 122, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 69, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 42, + "endLine": 127, + "endColumn": 69, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 35, + "endLine": 129, + "endColumn": 62, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 5, + "endLine": 132, + "endColumn": 70, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 36, + "endLine": 132, + "endColumn": 70, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 17, + "endLine": 134, + "endColumn": 99, + "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": 45, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 5, + "endLine": 135, + "endColumn": 56, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 35, + "endLine": 135, + "endColumn": 56, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 34, + "endLine": 138, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 5, + "endLine": 139, + "endColumn": 55, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 34, + "endLine": 139, + "endColumn": 55, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 143, + "endColumn": 35, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 40, + "endLine": 149, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 36, + "endLine": 149, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 21, + "endLine": 150, + "endColumn": 26, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 17, + "endLine": 150, + "endColumn": 29, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 17, + "endLine": 150, + "endColumn": 29, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 151, + "column": 1, + "endLine": 151, + "endColumn": 54, + "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": 151, + "column": 9, + "endLine": 151, + "endColumn": 14, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 17, + "endLine": 155, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 1, + "endLine": 156, + "endColumn": 20, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 43, + "endLine": 163, + "endColumn": 54, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 5, + "endLine": 167, + "endColumn": 24, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..d8f6775c620327300157f3944a39ef32a7656cc6 100644 --- a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json @@ -13,5 +13,66 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 106, + "column": 10, + "endLine": 106, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 5, + "endLine": 122, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 17, + "endLine": 134, + "endColumn": 99, + "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": 45, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 1, + "endLine": 151, + "endColumn": 53, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 1, + "endLine": 151, + "endColumn": 54, + "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" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets new file mode 100644 index 0000000000000000000000000000000000000000..7d078220853c9ea86f8ea7149435f95af0748872 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.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. + */ + +-Infinity !== -1 ; ++Infinity !== -1 ; +Infinity !== -1 ; +~Infinity !== -1 ; diff --git a/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets.args.json b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.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/arkts-distinct-infinity-bitwise-inversion.ets.arkts2.json b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1a7e31f801c7fe8623b71db711009fa4f45fe3e9 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.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": 1, + "endLine": 19, + "endColumn": 10, + "problem": "PrefixUnaryInfinity", + "suggest": "", + "rule": "The bitwise inversion gives different result for \"Infinity\" (arkts-distinct-infinity-bitwise-inversion)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets.json b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/arkts-distinct-infinity-bitwise-inversion.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/arkts-limited-tuple-index-type.ets b/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b73f47073145dd72e9e8ca5fe83105805aad13b --- /dev/null +++ b/ets2panda/linter/test/main/arkts-limited-tuple-index-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. + */ + +let tuple: [number, number] = [1.0,2.0]; +tuple[-1]; +tuple[1]; +tuple[1.0]; +tuple[0.0]; +tuple[0]; +const a = 1; +tuple[a]; +tuple[-a]; +const b = -1; +tuple[b]; +tuple[-b]; +const c = 1.0; +tuple[c]; +tuple[-c]; + diff --git a/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets.args.json b/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/arkts-limited-tuple-index-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/arkts-limited-tuple-index-type.ets.arkts2.json b/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4c0e20620142affb03d661500c5306a9e40b77b9 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-limited-tuple-index-type.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": 10, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 11, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 11, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 9, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 9, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 10, + "problem": "TupleIndex", + "suggest": "", + "rule": "Index of tuple must be non-negative integer (arkts-limited-tuple-index-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets.json b/ets2panda/linter/test/main/arkts-limited-tuple-index-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/arkts-limited-tuple-index-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": [] +} diff --git a/ets2panda/linter/test/main/arkts-no-esobject-support.ets b/ets2panda/linter/test/main/arkts-no-esobject-support.ets new file mode 100644 index 0000000000000000000000000000000000000000..c206350d266aecdcecf09f0967c71eca41cb1fd8 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-esobject-support.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. + */ + +function test1(): ESObject { // error + return {} as ESObject; // error +} + +let a: ESObject = test1(); // error + +function test2(a: ESObject): void {} // error + +let b = {} as ESObject; // error + +type MyType = ESObject; // error + +interface I { + a: ESObject; // error +} + +class C { + a: ESObject = {}; // error +} + +class D { + getData(): ESObject { // error + return {} as ESObject; // error + } +} + +class E { + setData(data: ESObject): void {} // error +} + +function test3() { + let local: ESObject = {} as ESObject; // error +} + +let arr: ESObject[] = [ {} as ESObject ]; // error + +let tup: [number, ESObject] = [1, {} as ESObject]; // error + +type UnionType = string | ESObject; // error +let unionVar: UnionType = {} as ESObject; // error + +type IntersectType = { id: number } & ESObject; // error + +function generic(val: T): T { + return val; +} + +generic({}); // error + +let result = test1() as ESObject; // error + +interface Extended extends ESObject {} // error + +type FuncType = (val: ESObject) => void; // error + +declare class Wrapper { + value: ESObject; // error +} diff --git a/ets2panda/linter/test/main/arkts-no-esobject-support.ets.args.json b/ets2panda/linter/test/main/arkts-no-esobject-support.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-esobject-support.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-no-esobject-support.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-esobject-support.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8841d5f35f523a1c3938a7b61806fcaaccb6622f --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-esobject-support.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": 16, + "column": 19, + "endLine": 16, + "endColumn": 27, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 24, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 16, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 15, + "endLine": 24, + "endColumn": 23, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 15, + "endLine": 26, + "endColumn": 23, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 6, + "endLine": 29, + "endColumn": 14, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 6, + "endLine": 33, + "endColumn": 14, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 14, + "endLine": 37, + "endColumn": 22, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 18, + "endLine": 38, + "endColumn": 26, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 17, + "endLine": 43, + "endColumn": 25, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 14, + "endLine": 47, + "endColumn": 22, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 31, + "endLine": 47, + "endColumn": 39, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 18, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 31, + "endLine": 50, + "endColumn": 39, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 19, + "endLine": 52, + "endColumn": 27, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 41, + "endLine": 52, + "endColumn": 49, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 27, + "endLine": 54, + "endColumn": 35, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 33, + "endLine": 55, + "endColumn": 41, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 47, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 23, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 39, + "endLine": 57, + "endColumn": 47, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 9, + "endLine": 63, + "endColumn": 17, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 25, + "endLine": 65, + "endColumn": 33, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 23, + "endLine": 69, + "endColumn": 31, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 18, + "problem": "NoESObjectSupport", + "suggest": "", + "rule": "ESObject type cannot be used (arkts-no-esobject-support)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.json b/ets2panda/linter/test/main/arkts-no-esobject-support.ets.json similarity index 67% rename from ets2panda/linter/test/main/global_this.ets.migrate.json rename to ets2panda/linter/test/main/arkts-no-esobject-support.ets.json index cdc3cef837269d89e24bee549595845bda5cc72b..1672d138e235bcb3e844702476e3209a7bf6b3b8 100644 --- a/ets2panda/linter/test/main/global_this.ets.migrate.json +++ b/ets2panda/linter/test/main/arkts-no-esobject-support.ets.json @@ -14,44 +14,44 @@ "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, + "column": 5, "endLine": 24, - "endColumn": 20, + "endColumn": 23, "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", + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 47, + "problem": "IntersectionType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", "severity": "ERROR" }, { - "line": 32, - "column": 1, - "endLine": 32, - "endColumn": 7, - "problem": "DeleteOperator", + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 23, + "problem": "ObjectTypeLiteral", "suggest": "", - "rule": "\"delete\" operator is not supported (arkts-no-delete)", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/arkts-no-import-json-file.ets b/ets2panda/linter/test/main/arkts-no-import-json-file.ets new file mode 100644 index 0000000000000000000000000000000000000000..550f8734be6b6a460913f004c8cc96b7f09f4f36 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-import-json-file.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. + */ + +// Valid import (non-json) +import { config } from './config'; + +// Invalid import - should trigger arkts-no-import-json-file +import data from './data.json'; // error + +// Another invalid case +import something from "../assets/data/data.json"; // error + +// Still invalid even if aliased +import * as jsonData from "./mock.json"; // error + +// Valid ArkTS-style config object (as alternative) +export const jsonLikeConfig = { + port: 3000, + secure: true, + options: { + retry: false + } +}; + +// Usage of config object +const portNumber: number = jsonLikeConfig.port; diff --git a/ets2panda/linter/test/interop/static_dynamic_import.ets.args.json b/ets2panda/linter/test/main/arkts-no-import-json-file.ets.args.json similarity index 100% rename from ets2panda/linter/test/interop/static_dynamic_import.ets.args.json rename to ets2panda/linter/test/main/arkts-no-import-json-file.ets.args.json diff --git a/ets2panda/linter/test/main/arkts-no-import-json-file.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-import-json-file.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..3d944890e6158f262c2aa62b785bbe9a418937c3 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-import-json-file.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": 20, + "column": 18, + "endLine": 20, + "endColumn": 31, + "problem": "NoImportJsonFile", + "suggest": "", + "rule": "JSON files cannot be imported (arkts-no-import-json-file)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 23, + "endLine": 23, + "endColumn": 49, + "problem": "NoImportJsonFile", + "suggest": "", + "rule": "JSON files cannot be imported (arkts-no-import-json-file)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 27, + "endLine": 26, + "endColumn": 40, + "problem": "NoImportJsonFile", + "suggest": "", + "rule": "JSON files cannot be imported (arkts-no-import-json-file)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 31, + "endLine": 29, + "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": 32, + "column": 12, + "endLine": 32, + "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/main/arkts-no-import-json-file.ets.json b/ets2panda/linter/test/main/arkts-no-import-json-file.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..fc8e8a5f95de70396685642567b4b7961643683e --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-import-json-file.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": 29, + "column": 31, + "endLine": 29, + "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": 32, + "column": 12, + "endLine": 32, + "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/main/arkts-no-instanceof-func_negative.ets b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets new file mode 100644 index 0000000000000000000000000000000000000000..f18275a560f1416d54120b080815fd992f0c1f4e --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.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. + */ + + +import foo5 from './arkts-no-instanceof-func_positive' +import {foo3} from './arkts-no-instanceof-func_positive' +import {foo3 as foo6} from './arkts-no-instanceof-func_positive' +import {BB} from './arkts-no-instanceof-func_positive' +import {BB as CC} from './arkts-no-instanceof-func_positive' + +function foo1() { + +} + +console.log('' + ((new foo1()) instanceof foo1)) // report error for instanceof a function. + +let a = foo1; +console.log('' + ((new foo1()) instanceof a)) // report error for instanceof a function which is assigned to a. + +let b = a; +let c = b; +let d = c; +console.log('' + ((new a()) instanceof d)) // report error for instanceof a function which is assigned to a b c d. + +namespace AA { + export function foo2() {} +} + +console.log('' + ((new foo1()) instanceof AA.foo2)) // report error for instanceof a namespace export function. + +let e = AA.foo2; +console.log('' + ((new foo1()) instanceof e)) // report error for instanceof a function which is assigned to e. + + +console.log('' + ((new foo1()) instanceof foo5)) // report error for instanceof a function which is default import. + +console.log('' + ((new foo1()) instanceof foo3)) // report error for instanceof a function which is import. + +console.log('' + ((new foo1()) instanceof foo6)) // report error for instanceof a function which is alias import. + +let foo7 = foo5; +console.log('' + ((new foo1()) instanceof foo7)) // report error for instanceof a function which is import and assigned to foo7. + +let foo8 = foo3; +console.log('' + ((new foo1()) instanceof foo8)) // report error for instanceof a function which is import and assigned to foo8. + +let foo9 = foo6; +console.log('' + ((new foo1()) instanceof foo9)) // report error for instanceof a function which is alias import and assigned to foo9. + +let foo10 = foo9; +console.log('' + ((new foo1()) instanceof foo10)) // report error for instanceof a function which is import and assigned to foo9 and foo10. + +console.log('' + ((new foo1()) instanceof BB.foo11)) // report error for instanceof a function which is import from namespace. + +console.log('' + ((new foo1()) instanceof CC.foo11)) // report error for instanceof a function which is import from namespace. \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets.ets.args.json b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets.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-no-instanceof-func_negative.ets.json b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..29e330916dba9efa4f230ead3c100e31c32ff3c0 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_negative.ets.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": 27, + "column": 43, + "endLine": 27, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 43, + "endLine": 30, + "endColumn": 44, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 40, + "endLine": 35, + "endColumn": 41, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 43, + "endLine": 41, + "endColumn": 50, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 43, + "endLine": 44, + "endColumn": 44, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 43, + "endLine": 47, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 43, + "endLine": 49, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 43, + "endLine": 51, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 43, + "endLine": 54, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 43, + "endLine": 57, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 43, + "endLine": 60, + "endColumn": 47, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 43, + "endLine": 63, + "endColumn": 48, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 43, + "endLine": 65, + "endColumn": 51, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 43, + "endLine": 67, + "endColumn": 51, + "problem": "InstanceOfFunction", + "suggest": "", + "rule": "\"instanceof\" operator can't be applied to function (arkts-no-instanceof-func)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..988bc94ef6183c5988c71f54736ee9f5e6e49c0e --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function foo3() { + +} + +export default function foo4() { + +} + +export function foo7() { + +} + +export namespace BB { + export function foo11() { + + } +} + +class A { + +} + +let a: A = new A(); +console.log('' + (a instanceof A)); + +class Person {} +const john = new Person(); +console.log('' + (john instanceof Person)); + +class Student extends Person {} +const alice = new Student(); +console.log('' + (alice instanceof Person)); + +const arr = [1, 2, 3]; +console.log('' + (arr instanceof Array)); +console.log('' + (arr instanceof Object)); + +const regex = /abc/; +console.log('' + (regex instanceof RegExp)); + diff --git a/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets.ets.args.json b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets.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-no-instanceof-func_positive.ets.json b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-instanceof-func_positive.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-super-call-in-static-context-negative.ets b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets new file mode 100644 index 0000000000000000000000000000000000000000..9cb64f10753599a2ecfd5175b344e9cb2da30861 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.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 { + static foo() { + return 123; + } + static a: number = 1.0; +} + +class B extends A { + static x1: number = super.foo(); // report error for calling super class in static context. + static x2: number = super.a; // report error for calling super class in static context. + static foo() { + let x3: number = super.a; // report error for calling super class in static method. + return super.foo() + 456; // report error for calling super class in static method. + } + static { + let x4: number = super.a; // report error for calling super class in static code block. + super.foo(); // report error for calling super class in static code block. + } +} diff --git a/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets.args.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.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-no-super-call-in-static-context-negative.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4755c1876845bb5d1f38081f1c4e71cb0af5cddb --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.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": 30, + "column": 3, + "endLine": 33, + "endColumn": 4, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 23, + "endLine": 24, + "endColumn": 28, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 23, + "endLine": 25, + "endColumn": 28, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 22, + "endLine": 27, + "endColumn": 27, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 12, + "endLine": 28, + "endColumn": 17, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 27, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 10, + "problem": "SuperInStaticContext", + "suggest": "", + "rule": "Subclass can't call members of super class in static context (arkts-no-super-call-in-static-context)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-negative.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-super-call-in-static-context-positive.ets b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..4bd51f8c1a4d3ad05e97881b8bb1563d1959e3c0 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.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. + */ + +class A { + static foo() { + return 123; + } +} + +class B extends A { + static foo() { + return A.foo() + 456; + } + static { + console.log('asd'); + A.foo(); + } +} + +class Animal1 { + name: string; + constructor(name: string) { + this.name = name; + } +} +class Dog1 extends Animal1 { + breed: string; + constructor(name: string, breed: string) { + super(name); + this.breed = breed; + } +} + +class Animal2 { + move(): void { + console.log("Moving..."); + } +} +class Dog2 extends Animal2 { + move(): void { + super.move(); + console.log("Running..."); + } +} + +class Base1 { + greet(): void { + console.log("Hello, world!"); + } +} +class Derived1 extends Base1 { + greet(): void { + super.greet(); + console.log("Hello from Derived class!"); + } +} + +class Base2 { + value: number; + constructor() { + this.value = 100; + } +} +class Derived2 extends Base2 { + constructor() { + super(); + this.value += 50; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets.args.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.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-no-super-call-in-static-context-positive.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..65e7c7a06a97d629db327ae4590cbaf99cb639ef --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.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": 26, + "column": 3, + "endLine": 29, + "endColumn": 4, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets.json b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-super-call-in-static-context-positive.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-template-string-type.ets b/ets2panda/linter/test/main/arkts-no-template-string-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..151de4d06d7144f61b1ac0c125d24598b5be77bf --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-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. + */ + +type Action = "verify"; +type ContentMatch = "match"; +type Outcome = `${Action}_${ContentMatch}`; +type Outcome2 = `${Action}_match`; +type Outcome3 = `verify_${ContentMatch}`; + +type Foo = "Foo"; +type Bar = "Bar"; + +let template: `${Foo}_${Bar}`; +function foo(template: `${Foo}_${Bar}`): `${number}` {} diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets.args.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-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/arkts-no-template-string-type.ets.arkts2.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a09f343947433ef57db208477664b956b155c856 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-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": 16, + "endLine": 18, + "endColumn": 43, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 34, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 41, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 30, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 24, + "endLine": 26, + "endColumn": 39, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 42, + "endLine": 26, + "endColumn": 53, + "problem": "TemplateStringType", + "suggest": "", + "rule": "Template string type is not supported (arkts-no-template-string-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-no-template-string-type.ets.json b/ets2panda/linter/test/main/arkts-no-template-string-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/arkts-no-template-string-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": [] +} diff --git a/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets new file mode 100644 index 0000000000000000000000000000000000000000..5f1044a71a7f3e66af4523a8d1b639375bc69e30 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let p1: Promise = new Promise((resolve) => resolve("ok")); +let p2: Promise = new Promise((resolve) => resolve(1)); + +Promise.all<[Promise, Promise]>([p1, p2]); // error +Promise.any<[Promise, Promise]>([p1, p2]); // error +Promise.race<[Promise, Promise]>([p1, p2]); // error +Promise.allSettled<[Promise, Promise]>([p1, p2]); // error + +Promise.all([p1, p2]); // valid +Promise.any([p1, p2]); // valid diff --git a/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.args.json b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.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-not-support-tuple-generic-validation.ets.arkts2.json b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e61aa4ff7a944b75ca9e52a984286f90f80315d4 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.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": 16, + "column": 27, + "endLine": 16, + "endColumn": 66, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 27, + "endLine": 17, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 47, + "problem": "NotSupportTupleGenericValidation", + "suggest": "", + "rule": "Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 13, + "endLine": 20, + "endColumn": 47, + "problem": "NotSupportTupleGenericValidation", + "suggest": "", + "rule": "Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 48, + "problem": "NotSupportTupleGenericValidation", + "suggest": "", + "rule": "Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 54, + "problem": "NotSupportTupleGenericValidation", + "suggest": "", + "rule": "Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.json b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..895325b061c0fe9fa6b75bab6ed4259b5343c199 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-not-support-tuple-generic-validation.ets.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": [ + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets b/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..0079ae69de97af89494f2ec7d79b3c9e3e79ab39 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-obj-literal-key-type.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{ + public age:number = 1.0; +} + +class B{ + public name:string = "Joe"; + public age:number = 30; +} + +class C{ + public salary:number = 100; + public age:number = 30; +} + +let a: A = {"age": 30} + +let b: Record = { age: 30} + +let c: B = {"name" : "Annie", "age" : 25} + +let d: Record = {salary : 250, age: 30} + diff --git a/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets.args.json b/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-obj-literal-key-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/arkts-obj-literal-key-type.ets.arkts2.json b/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f60e39da2bdf900a710840139a1e6f4c161dc42f --- /dev/null +++ b/ets2panda/linter/test/main/arkts-obj-literal-key-type.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": 31, + "column": 13, + "endLine": 31, + "endColumn": 18, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 35, + "endLine": 33, + "endColumn": 38, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 33, + "endLine": 33, + "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": 35, + "column": 13, + "endLine": 35, + "endColumn": 19, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 31, + "endLine": 35, + "endColumn": 36, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 34, + "endLine": 37, + "endColumn": 40, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 48, + "endLine": 37, + "endColumn": 51, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 34, + "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/arkts-obj-literal-key-type.ets.json b/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..0ebd77f3e553fdaf5d3d372c8c805bdf315cdf36 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-obj-literal-key-type.ets.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": 31, + "column": 13, + "endLine": 31, + "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": 33, + "column": 33, + "endLine": 33, + "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": 35, + "column": 13, + "endLine": 35, + "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": 35, + "column": 31, + "endLine": 35, + "endColumn": 36, + "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": 33, + "endLine": 37, + "endColumn": 34, + "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/arkts-primitive-type-normalization.ets.arkts2.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json index 1b81953cde926b95f9f144bcb2c8500b78c402a8..517754f2cf1543d8cbbebd9f208dab30074c5d87 100644 --- a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json @@ -21,7 +21,17 @@ "endColumn": 21, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 12, + "endLine": 16, + "endColumn": 18, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -31,7 +41,17 @@ "endColumn": 14, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 11, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -41,7 +61,17 @@ "endColumn": 31, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 22, + "endLine": 17, + "endColumn": 28, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -51,7 +81,17 @@ "endColumn": 23, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 16, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -61,7 +101,17 @@ "endColumn": 26, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 19, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -71,7 +121,17 @@ "endColumn": 12, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -81,7 +141,17 @@ "endColumn": 11, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -91,7 +161,17 @@ "endColumn": 11, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/arkts-require-func-arg-type.ets b/ets2panda/linter/test/main/arkts-require-func-arg-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..fa688edec8041d27fc0065562f5df524dcef238c --- /dev/null +++ b/ets2panda/linter/test/main/arkts-require-func-arg-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. + */ + +function foo1(a = 2){} + +function foo2(a = 2, b:number = 3){} + +function foo3(a = 2, b = 3){} + +class Calculator { + // Method with parameters + add(a, b): number { + return a + b; + } + + multiply(x: number, y): number { + return x * y; + } +} diff --git a/ets2panda/linter/test/main/arkts-require-func-arg-type.ets.args.json b/ets2panda/linter/test/main/arkts-require-func-arg-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/arkts-require-func-arg-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/global_this.ets.autofix.json b/ets2panda/linter/test/main/arkts-require-func-arg-type.ets.arkts2.json old mode 100755 new mode 100644 similarity index 42% rename from ets2panda/linter/test/main/global_this.ets.autofix.json rename to ets2panda/linter/test/main/arkts-require-func-arg-type.ets.arkts2.json index 5d8cc4d2dee047bb9d926d44f590afd9775ccbb0..ebc344bf042adba547d39644180ea4607b231070 --- a/ets2panda/linter/test/main/global_this.ets.autofix.json +++ b/ets2panda/linter/test/main/arkts-require-func-arg-type.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -16,128 +16,103 @@ "result": [ { "line": 16, - "column": 7, + "column": 15, "endLine": 16, - "endColumn": 18, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 616, - "end": 627, - "replacementText": "pi: number = 3.1416" - } - ], + "endColumn": 20, + "problem": "ParameterType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { - "line": 19, - "column": 7, - "endLine": 19, - "endColumn": 17, - "problem": "GlobalThisError", + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 20, + "problem": "ParameterType", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { - "line": 21, - "column": 10, - "endLine": 21, - "endColumn": 23, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 700, - "end": 713, - "replacementText": "specialAutofixLib.globalThis.get(\"pi\")" - } - ], + "line": 20, + "column": 15, + "endLine": 20, + "endColumn": 20, + "problem": "ParameterType", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 22, + "endLine": 20, + "endColumn": 27, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { "line": 24, - "column": 17, + "column": 7, "endLine": 24, - "endColumn": 20, - "problem": "AnyType", + "endColumn": 8, + "problem": "ParameterType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { - "line": 28, - "column": 1, - "endLine": 28, - "endColumn": 21, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 779, - "end": 799, - "replacementText": "specialAutofixLib.globalThis.set(\"abc\", 200)" - } - ], + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11, + "problem": "ParameterType", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { - "line": 30, + "line": 24, "column": 7, - "endLine": 30, - "endColumn": 34, + "endLine": 24, + "endColumn": 8, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 30, - "column": 15, - "endLine": 30, - "endColumn": 29, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 816, - "end": 830, - "replacementText": "specialAutofixLib.globalThis.get(\"obj\")" - } - ], + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11, + "problem": "AnyType", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 32, - "column": 1, - "endLine": 32, - "endColumn": 7, - "problem": "DeleteOperator", + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24, + "problem": "ParameterType", "suggest": "", - "rule": "\"delete\" operator is not supported (arkts-no-delete)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "severity": "ERROR" }, { - "line": 32, - "column": 8, - "endLine": 32, - "endColumn": 27, - "problem": "GlobalThisError", - "autofix": [ - { - "start": 845, - "end": 864, - "replacementText": "specialAutofixLib.globalThis.get(\"property\")" - } - ], + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24, + "problem": "AnyType", "suggest": "", - "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "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/arkts-require-func-arg-type.ets.json b/ets2panda/linter/test/main/arkts-require-func-arg-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..e2df81fe91730df3834d19d02b08f5278fb98ff5 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-require-func-arg-type.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": 24, + "column": 7, + "endLine": 24, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets new file mode 100644 index 0000000000000000000000000000000000000000..2841e80f912c2d11041c2782305d6c250c523433 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.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 a = -123; +let b = 456; +let c = -789; + +let r1 = -123 >>> 0; // error +let r2 = a >>> 0; // error +let r3 = b >>> 0; // valid +let r4 = c >>> 0; // error + +let d = -1; +let r5 = d >>> 0; // error diff --git a/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.args.json b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.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-unsigned-shift-on-negative.ets.arkts2.json b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..3862e0bc0928be6ce993ce814a8bd801d7483b78 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.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": 20, + "column": 10, + "endLine": 20, + "endColumn": 20, + "problem": "NumericUnsignedShiftBehaviorChange", + "suggest": "", + "rule": "Unsigned right shift on negative number yields different results in ArkTS versions. (arkts-distinct-unsigned-right-shift-negative-number)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 17, + "problem": "NumericUnsignedShiftBehaviorChange", + "suggest": "", + "rule": "Unsigned right shift on negative number yields different results in ArkTS versions. (arkts-distinct-unsigned-right-shift-negative-number)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 17, + "problem": "NumericUnsignedShiftBehaviorChange", + "suggest": "", + "rule": "Unsigned right shift on negative number yields different results in ArkTS versions. (arkts-distinct-unsigned-right-shift-negative-number)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 17, + "problem": "NumericUnsignedShiftBehaviorChange", + "suggest": "", + "rule": "Unsigned right shift on negative number yields different results in ArkTS versions. (arkts-distinct-unsigned-right-shift-negative-number)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.json b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..895325b061c0fe9fa6b75bab6ed4259b5343c199 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-unsigned-shift-on-negative.ets.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": [ + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..c8771f9e4eb2a2a08b82507b0dab7b5cf6aafb81 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.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. + */ + +console.log(0xcafebabe) +const a : long = 3405691582; +const b = 3405691582; +const c : long = 2342343; +const d = 123; +const e = -2147483649; +const f : long = -2147483649; +const g = 0x0b101010; diff --git a/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets.args.json b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.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/arkts-use-long-for-large-numeric-literal.ets.arkts2.json b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..b6ac079e4bfeac5eb2d98fc77232234d5e4bdf49 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.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": 13, + "endLine": 16, + "endColumn": 23, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 21, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 22, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets.json b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/arkts-use-long-for-large-numeric-literal.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/arkts_class_no_signature_public_obj_api.ets b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets new file mode 100644 index 0000000000000000000000000000000000000000..b02afc3dcc5cd3da3d98c26d6860dac141cc00f5 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets @@ -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. + */ + +class A1 { + toString(): string { // valid + return "ok"; + } + + toLocaleString(): string { // valid + return "ok"; + } + + valueOf(): number { // error + return 789; + } + + hasOwnProperty(): boolean { // error + return false; + } + + isPrototypeOf(v: Object): boolean { // valid + return true; + } + + propertyIsEnumerable(v: PropertyKey): boolean { // valid + return false; + } +} + +class A2 { + customFunc(): void {} // valid + + toString(): number {return 123;} // error + + toLocaleString(): number { // error + return 456; + } + + valueOf(): Object { // valid + return {}; + } + + hasOwnProperty(v: PropertyKey): boolean { // valid + return true; + } + + isPrototypeOf(v: string): boolean { // error + return false; + } + + propertyIsEnumerable(v: PropertyKey): string { // error + return "not boolean"; + } +} + +class A3 { + toString(): string { return "ok"; } // valid + valueOf(): number { return 123; } // error +} + +class A4 { + customFunc(): void {} // valid + valueOf(): number { return 123; } // error + toString(): string { return "ok"; } // valid +} + +interface I1 { + toString(): string; // valid + toLocaleString(): number; // error + valueOf(): number; // error + customFunc(): boolean; // valid + hasOwnProperty(v: PropertyKey): boolean; // valid + isPrototypeOf(v: Object): boolean; // valid + propertyIsEnumerable(v: PropertyKey): boolean; // valid +} + +interface I2 { + toString(): boolean; // error + toLocaleString(): string; // valid + valueOf(): Object; // valid + hasOwnProperty(): boolean; // error + isPrototypeOf(v: string): boolean; // error + propertyIsEnumerable(v: PropertyKey): string; // error +} + +interface I3 { + toString(): string; // valid + valueOf(): number; // error +} + +interface I4 { + valueOf(): number; // error + toString(): string; // valid +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.args.json b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.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_class_no_signature_public_obj_api.ets.arkts2.json b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..45b2c202663e5f56cf7418b63277dfabf7ff2af3 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 25, + "column": 3, + "endLine": 27, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 27, + "endLine": 37, + "endColumn": 38, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 35, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 3, + "endLine": 49, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 61, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 3, + "endLine": 65, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 12, + "endLine": 52, + "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": 55, + "column": 21, + "endLine": 55, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 27, + "endLine": 63, + "endColumn": 38, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 36, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 3, + "endLine": 75, + "endColumn": 36, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 28, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 3, + "endLine": 82, + "endColumn": 21, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 21, + "endLine": 84, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 27, + "endLine": 86, + "endColumn": 38, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 3, + "endLine": 90, + "endColumn": 23, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 29, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 37, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 95, + "endColumn": 48, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 27, + "endLine": 95, + "endColumn": 38, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 3, + "endLine": 100, + "endColumn": 21, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 21, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.json b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..84b96b7788932300593bd70afba0c4fea845f3f0 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_class_no_signature_public_obj_api.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": 52, + "column": 12, + "endLine": 52, + "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/main/arkts_no_class_super_prop_readonly.ets b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8c9d694db662f0061ffd5c7f69f1dff31975541 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.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. + */ + +class A { + readonly x: number = 10; +} +class B extends A { + readonly x: number = 20; // legal +} + +class C { + readonly y: string = "base"; +} +class D extends C { + readonly y: string = "child"; // legal +} + +class E { + z: boolean = true; +} +class F extends E { + z: boolean = false; // legal +} + +class G { + readonly foo: number = 42; +} +class H extends G {} // legal + +class M1 { + data: number = 1; +} +class M2 extends M1 { + readonly data: number = 2; // error +} + +class M3 { + version: string = "1.0"; +} +class M4 extends M3 { + readonly version: "2.0" = "2.0"; // error +} + +class M5 { + isReady: boolean = false; +} +class M6 extends M5 { + readonly isReady: true = true; // error +} + +class A1 { + data: number = 1; +} + +class A2 extends A1 { +} + +class A3 extends A2 { + readonly data: number= 2; // error +} + +class B1 { + readonly data: number = 1; +} + +class B2 extends B1 { +} + +class B3 extends B2 { + readonly data: number= 2; // legal +} + +interface NonReadonly { + v: number +} + +class B4 extends NonReadonly { + readonly v: number = 0; // error +} + +interface Readonly { + readonly v: number; +} + +class B5 extends Readonly { + readonly v: number = 0; // legal +} diff --git a/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets.args.json b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.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/arkts_no_class_super_prop_readonly.ets.arkts2.json b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..45209a4cbf3e39508dec42e97f0a23d558205dc0 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.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": 46, + "column": 3, + "endLine": 46, + "endColumn": 29, + "problem": "NoClassSuperPropReadonly", + "suggest": "", + "rule": "Overriding with \"readonly\" field is not allowed when base field is not \"readonly\" (arkts-no-class-add-super-prop-with-readonly)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 12, + "endLine": 53, + "endColumn": 19, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 35, + "problem": "NoClassSuperPropReadonly", + "suggest": "", + "rule": "Overriding with \"readonly\" field is not allowed when base field is not \"readonly\" (arkts-no-class-add-super-prop-with-readonly)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 12, + "endLine": 60, + "endColumn": 19, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 33, + "problem": "NoClassSuperPropReadonly", + "suggest": "", + "rule": "Overriding with \"readonly\" field is not allowed when base field is not \"readonly\" (arkts-no-class-add-super-prop-with-readonly)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 21, + "endLine": 60, + "endColumn": 25, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 30, + "problem": "NoClassSuperPropReadonly", + "suggest": "", + "rule": "Overriding with \"readonly\" field is not allowed when base field is not \"readonly\" (arkts-no-class-add-super-prop-with-readonly)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 28, + "problem": "NoClassSuperPropReadonly", + "suggest": "", + "rule": "Overriding with \"readonly\" field is not allowed when base field is not \"readonly\" (arkts-no-class-add-super-prop-with-readonly)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets.json b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_no_class_super_prop_readonly.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_promise_need_void_resolve.ets b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets new file mode 100755 index 0000000000000000000000000000000000000000..54a185e6c9383827327124c88d06b1228ed218c1 --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.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 test(): Promise{ + return new Promise((resolve: () => void, reject) => { resolve() }) } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..b9d72da1744d61b8b6c738b008adb28a4b9bee3a --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.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_promise_need_void_resolve.ets.arkts2.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..83f403ba1f5ef5fd64ebbb44235a11c5ef6c754a --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.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": 40, + "endLine": 17, + "endColumn": 50, + "problem": "PromiseVoidNeedResolveArg", + "suggest": "", + "rule": "Promiseconstructor only supports using resolve (undefined) (arkts-promise-with-void-type-need-undefined-as-resolve-arg)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..127a98a334a7471028ae0d660051f086a7d261be --- /dev/null +++ b/ets2panda/linter/test/main/arkts_promise_need_void_resolve.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 b/ets2panda/linter/test/main/arktsutils_module.ets index 3bfeec6005331e400a16972a240767cc9f567293..a8fbe4b65e5e0ecc29045471c29da4584632c4af 100644 --- a/ets2panda/linter/test/main/arktsutils_module.ets +++ b/ets2panda/linter/test/main/arktsutils_module.ets @@ -12,7 +12,6 @@ * 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'; @@ -32,4 +31,10 @@ function tesCollectionsUsage() { const utils3 = kitArkTSUtils.ASON.stringify(1); const utils4: string = ArkTSUtilsAlias.ASON.stringify(1); -} \ No newline at end of file + + type CreatedType = ArkTSUtils.ASON.SomeType; + + const someType: CreatedType = ArkTSUtils.ASON.SomeType; + + const map: number = ArkTSUtils.ASON.ParseReturnType.map; +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json index 6f9939410a6a6da1809a944a1ab49f898c81de50..9fd9a68f13a535d09a0dc5b54b91c43c115afe99 100644 --- a/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json +++ b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json @@ -15,44 +15,74 @@ ], "result": [ { - "line": 28, - "column": 32, - "endLine": 28, - "endColumn": 36, + "line": 27, + "column": 26, + "endLine": 27, + "endColumn": 31, "problem": "LimitedStdLibNoASON", "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 30, - "column": 34, - "endLine": 30, - "endColumn": 38, + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33, "problem": "LimitedStdLibNoASON", "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 32, - "column": 32, - "endLine": 32, - "endColumn": 36, + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31, "problem": "LimitedStdLibNoASON", "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 34, - "column": 42, - "endLine": 34, - "endColumn": 46, + "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" + }, + { + "line": 39, + "column": 23, + "endLine": 39, + "endColumn": 33, "problem": "LimitedStdLibNoASON", "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json index 05eac65f01caa029cdbabccb62bd89eee356c906..d88f22656f9a537ddc865f0423de3b76585f371a 100644 --- a/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json +++ b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json @@ -15,72 +15,118 @@ ], "result": [ { - "line": 28, - "column": 32, - "endLine": 28, - "endColumn": 36, + "line": 27, + "column": 26, + "endLine": 27, + "endColumn": 31, "problem": "LimitedStdLibNoASON", - "suggest": "", "autofix": [ { - "start": 981, - "end": 991, - "replacementText": "JSON" + "start": 980, + "end": 990, + "replacementText": "JSON", + "line": 27, + "column": 26, + "endLine": 27, + "endColumn": 31 } ], + "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 30, - "column": 34, - "endLine": 30, - "endColumn": 38, + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33, "problem": "LimitedStdLibNoASON", - "suggest": "", "autofix": [ { - "start": 1024, - "end": 1044, - "replacementText": "JSON" + "start": 1023, + "end": 1043, + "replacementText": "JSON", + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33 } ], + "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 32, - "column": 32, - "endLine": 32, - "endColumn": 36, + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31, "problem": "LimitedStdLibNoASON", - "suggest": "", - "autofix": [ + "autofix": [ { - "start": 1077, - "end": 1095, - "replacementText": "JSON" + "start": 1076, + "end": 1094, + "replacementText": "JSON", + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31 } ], + "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" }, { - "line": 34, - "column": 42, - "endLine": 34, - "endColumn": 46, + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 41, "problem": "LimitedStdLibNoASON", - "suggest": "", "autofix": [ { - "start": 1136, - "end": 1156, - "replacementText": "JSON" + "start": 1135, + "end": 1155, + "replacementText": "JSON", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 41 } ], + "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" + }, + { + "line": 39, + "column": 23, + "endLine": 39, + "endColumn": 33, + "problem": "LimitedStdLibNoASON", + "suggest": "", "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", "severity": "ERROR" } ] -} +} \ 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 index c44acf5845a4f1c185a9a5c6c86a4032d4f7cd1e..abacfa435105d1790ffaac7e46789edb7d1787df 100644 --- a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets @@ -12,7 +12,6 @@ * 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'; @@ -32,4 +31,10 @@ function tesCollectionsUsage() { const utils3 = JSON.stringify(1); const utils4: string = JSON.stringify(1); -} \ No newline at end of file + + type CreatedType = ArkTSUtils.ASON.SomeType; + + const someType: CreatedType = ArkTSUtils.ASON.SomeType; + + const map: number = ArkTSUtils.ASON.ParseReturnType.map; +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json index 9f305c86d7ff705098b1e480818e125d5e6e3a4a..c48332a4e2db3e1e7bad7d88f8a636180c199a7d 100644 --- a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json @@ -13,5 +13,116 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 27, + "column": 31, + "endLine": 27, + "endColumn": 40, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 31, + "endLine": 27, + "endColumn": 40, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 32, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 32, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 32, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 31, + "endLine": 33, + "endColumn": 40, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 31, + "endLine": 33, + "endColumn": 40, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "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" + }, + { + "line": 39, + "column": 23, + "endLine": 39, + "endColumn": 33, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/main/arkui-select.ets b/ets2panda/linter/test/main/arkui-select.ets new file mode 100644 index 0000000000000000000000000000000000000000..92b8ccbde728e7ada1020b6e1326089b03805bf0 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.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. + */ + + @Component + export struct ConsumeDescendentComponent { + // 初始化一个颜色数组数据 + @State selectColors: ColorType[] = COLOR_SELECT_DATA; + // 和爷组件双向同步圆形颜色 + @Consume consumeCircleColor: Resource; + // 和爷组件双向同步Select的Index值 + @Consume currentSelectIndex: number; + private CONTEXT: common.UIAbilityContext = this.getUIContext()?.getHostContext() as common.UIAbilityContext;//修改 + + build() { + Column() { + // 点击查看源码 + ViewCodeText({ webSrc: $rawfile('ConsumeDescendentComponent.ets.html') }) + Row() { + Select(this.selectColors) + .selected(this.currentSelectIndex) + .value(getResourceString(this.CONTEXT, this.selectColors[this.currentSelectIndex as int].value)) //修改this.context + .fontColor($r('app.color.button_text_color')) + .font({ size: $r('app.float.tips_font_size') }) + .selectedOptionFont({ size: $r('app.float.tips_font_size') }) + .optionFont({ size: $r('app.float.tips_font_size') }) + .id('grandsonCompB') + .onSelect((index: number) => { + // 孙组件@Consume声明的数据页面更新,爷组件@Provide的数据页面同步更新 + this.currentSelectIndex = index; + this.consumeCircleColor = this.selectColors[index as int].color; + }) + Circle() + .size({ width: $r('app.float.circle_size'), height: $r('app.float.circle_size') }) + .fill(this.consumeCircleColor) + + }.justifyContent(FlexAlign.SpaceAround) + .width('100%') + .margin({ bottom: 6.0 }as Margin)//修改添加 as Margin + + Text($r('app.string.deepnest_descendent_titletwo')) + .fontColor($r('app.color.tips_font_color')) + .fontSize($r('app.float.button_text_size')) + .width('100%') + .textAlign(TextAlign.Center) + } + .padding(10.0) + .border({ radius: $r('app.float.component_radius'), color: Color.Red, width: $r('app.float.border_width') }) + } + } diff --git a/ets2panda/linter/test/main/arkui-select.ets.args.json b/ets2panda/linter/test/main/arkui-select.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..aac366be5e8658d7672f4da2855a3c4740c7bcd3 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.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/arkui-select.ets.arkts2.json b/ets2panda/linter/test/main/arkui-select.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..29b9095e7ea4d36e0b828f547895db37d6e5f346 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.ets.arkts2.json @@ -0,0 +1,288 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 35, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 3, + "endLine": 16, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 6, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 6, + "endLine": 21, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Consume\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Resource\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Consume\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 32, + "endLine": 29, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$rawfile\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 11, + "endLine": 31, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Select\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 24, + "endLine": 34, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 27, + "endLine": 35, + "endColumn": 29, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 41, + "endLine": 36, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 11, + "endLine": 44, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Circle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 28, + "endLine": 45, + "endColumn": 30, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 65, + "endLine": 45, + "endColumn": 67, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FlexAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 35, + "endLine": 50, + "endColumn": 41, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Margin\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 14, + "endLine": 52, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 22, + "endLine": 53, + "endColumn": 24, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 21, + "endLine": 54, + "endColumn": 23, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 22, + "endLine": 56, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextAlign\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 25, + "endLine": 59, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 66, + "endLine": 59, + "endColumn": 71, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 84, + "endLine": 59, + "endColumn": 86, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"$r\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkui-select.ets.json b/ets2panda/linter/test/main/arkui-select.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkui-select.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/array_index_expr_type.ets b/ets2panda/linter/test/main/array_index_expr_type.ets index fe370c16cdb5ee0ec55a04f685b25b665d6c4bb1..3d326b6f36709087f7c4aef0dda4339655e6f7a4 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets +++ b/ets2panda/linter/test/main/array_index_expr_type.ets @@ -83,3 +83,21 @@ arr[a] = 1; arr[b] = 1; arr[c] = 1; arr[d] = 1; + +let test = 1; +arr[1 as number]; +arr[test as number]; + +@Component +struct Test { + @Link testIndex: number; + + async cateMode(testIndex: number) { + emitter.on(innerEvent, (eventData) => { + if (this.testIndex == 0) { + let array = [1,2,3]; + array[this.testIndex]; + } + }) + } +} 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 5bf7d76719c3a74aedb85c6357fe83d323e30047..723d6e343d4979e100eca723dfdd929c8b8cdd10 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 @@ -14,24 +14,14 @@ "limitations under the License." ], "result": [ - { - "line": 17, - "column": 7, - "endLine": 17, - "endColumn": 25, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 18, - "column": 7, + "column": 11, "endLine": 18, "endColumn": 26, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -46,12 +36,12 @@ }, { "line": 19, - "column": 7, + "column": 12, "endLine": 19, "endColumn": 31, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -66,12 +56,12 @@ }, { "line": 20, - "column": 7, + "column": 12, "endLine": 20, "endColumn": 33, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -86,12 +76,12 @@ }, { "line": 21, - "column": 7, + "column": 11, "endLine": 21, "endColumn": 25, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -184,16 +174,6 @@ "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", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 26, "column": 20, @@ -206,12 +186,12 @@ }, { "line": 27, - "column": 7, + "column": 11, "endLine": 27, "endColumn": 24, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -226,12 +206,12 @@ }, { "line": 28, - "column": 7, + "column": 11, "endLine": 28, "endColumn": 25, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -246,22 +226,22 @@ }, { "line": 29, - "column": 7, + "column": 11, "endLine": 29, "endColumn": 22, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 30, - "column": 7, + "column": 11, "endLine": 30, "endColumn": 37, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -276,12 +256,12 @@ }, { "line": 31, - "column": 7, + "column": 11, "endLine": 31, "endColumn": 37, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -296,12 +276,12 @@ }, { "line": 32, - "column": 7, + "column": 11, "endLine": 32, "endColumn": 44, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -315,13 +295,13 @@ "severity": "ERROR" }, { - "line": 35, - "column": 5, - "endLine": 35, - "endColumn": 20, - "problem": "NumericSemantics", + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 15, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -334,6 +314,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 40, + "column": 1, + "endLine": 40, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 40, "column": 7, @@ -345,33 +335,43 @@ "severity": "ERROR" }, { - "line": 50, - "column": 5, - "endLine": 50, - "endColumn": 23, - "problem": "NumericSemantics", + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 15, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 45, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 51, - "column": 8, + "column": 1, "endLine": 51, - "endColumn": 18, - "problem": "ArrayIndexExprType", + "endColumn": 19, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 53, - "column": 5, - "endLine": 53, - "endColumn": 23, - "problem": "NumericSemantics", + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 18, + "problem": "ArrayIndexExprType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, { @@ -384,6 +384,16 @@ "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": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 67, "column": 6, @@ -394,6 +404,46 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 72, "column": 1, @@ -404,16 +454,46 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 73, "column": 6, "endLine": 73, - "endColumn": 9, + "endColumn": 19, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 18, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 81, "column": 5, @@ -423,6 +503,96 @@ "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 16, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 1, + "endLine": 89, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 19, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 29, + "endLine": 96, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 9, + "endLine": 99, + "endColumn": 30, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 15, + "endLine": 99, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 2, + "endLine": 91, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 4, + "endLine": 93, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Link\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json index e6e11862be7b395fe014aa219233b821b93a68ab..f4dd521cf08fa76dced361a04f66ee78c0bd59b9 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json @@ -14,38 +14,14 @@ "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]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 18, - "column": 7, + "column": 11, "endLine": 18, "endColumn": 26, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 664, - "end": 683, - "replacementText": "a: number = an_array[index]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -58,7 +34,11 @@ { "start": 677, "end": 682, - "replacementText": "index as int" + "replacementText": "index as int", + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 25 } ], "suggest": "", @@ -67,19 +47,12 @@ }, { "line": 19, - "column": 7, + "column": 12, "endLine": 19, "endColumn": 31, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 690, - "end": 714, - "replacementText": "a1: number = an_array[index + 1]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -92,7 +65,11 @@ { "start": 704, "end": 713, - "replacementText": "(index + 1) as int" + "replacementText": "(index + 1) as int", + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30 } ], "suggest": "", @@ -101,19 +78,12 @@ }, { "line": 20, - "column": 7, + "column": 12, "endLine": 20, "endColumn": 33, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 721, - "end": 747, - "replacementText": "a2: number = an_array[index + 1.1]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -126,7 +96,11 @@ { "start": 735, "end": 746, - "replacementText": "(index + 1.1) as int" + "replacementText": "(index + 1.1) as int", + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32 } ], "suggest": "", @@ -135,19 +109,12 @@ }, { "line": 21, - "column": 7, + "column": 11, "endLine": 21, "endColumn": 25, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 754, - "end": 772, - "replacementText": "b: number = an_array[1.23]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -160,7 +127,11 @@ { "start": 767, "end": 771, - "replacementText": "1.23 as int" + "replacementText": "1.23 as int", + "line": 21, + "column": 20, + "endLine": 21, + "endColumn": 24 } ], "suggest": "", @@ -247,23 +218,6 @@ "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[]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 26, "column": 20, @@ -276,19 +230,12 @@ }, { "line": 27, - "column": 7, + "column": 11, "endLine": 27, "endColumn": 24, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 908, - "end": 925, - "replacementText": "h: number = an_array[12.]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -301,7 +248,11 @@ { "start": 921, "end": 924, - "replacementText": "12. as int" + "replacementText": "12. as int", + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23 } ], "suggest": "", @@ -310,19 +261,12 @@ }, { "line": 28, - "column": 7, + "column": 11, "endLine": 28, "endColumn": 25, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 932, - "end": 950, - "replacementText": "i: number = an_array[12.0]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -335,7 +279,11 @@ { "start": 945, "end": 949, - "replacementText": "12.0 as int" + "replacementText": "12.0 as int", + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24 } ], "suggest": "", @@ -344,36 +292,22 @@ }, { "line": 29, - "column": 7, + "column": 11, "endLine": 29, "endColumn": 22, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 957, - "end": 972, - "replacementText": "j: number = an_array[0]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 30, - "column": 7, + "column": 11, "endLine": 30, "endColumn": 37, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 979, - "end": 1009, - "replacementText": "k: number = an_array[Number.MAX_VALUE]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -386,7 +320,11 @@ { "start": 992, "end": 1008, - "replacementText": "Number.MAX_VALUE as int" + "replacementText": "Number.MAX_VALUE as int", + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 36 } ], "suggest": "", @@ -395,19 +333,12 @@ }, { "line": 31, - "column": 7, + "column": 11, "endLine": 31, "endColumn": 37, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1016, - "end": 1046, - "replacementText": "l: number = an_array[Number.MIN_VALUE]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -420,7 +351,11 @@ { "start": 1029, "end": 1045, - "replacementText": "Number.MIN_VALUE as int" + "replacementText": "Number.MIN_VALUE as int", + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 36 } ], "suggest": "", @@ -429,19 +364,12 @@ }, { "line": 32, - "column": 7, + "column": 11, "endLine": 32, "endColumn": 44, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1053, - "end": 1090, - "replacementText": "m: number = an_array[Number.MAX_SAFE_INTEGER]" - } - ], + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -454,7 +382,11 @@ { "start": 1066, "end": 1089, - "replacementText": "Number.MAX_SAFE_INTEGER as int" + "replacementText": "Number.MAX_SAFE_INTEGER as int", + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 43 } ], "suggest": "", @@ -462,20 +394,13 @@ "severity": "ERROR" }, { - "line": 35, - "column": 5, - "endLine": 35, - "endColumn": 20, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1098, - "end": 1113, - "replacementText": "array: number[] = [1, 2, 3]" - } - ], + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 15, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -488,13 +413,27 @@ { "start": 1201, "end": 1208, - "replacementText": "index_1 as int" + "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": 1, + "endLine": 40, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 40, "column": 7, @@ -505,7 +444,11 @@ { "start": 1217, "end": 1224, - "replacementText": "index_2 as int" + "replacementText": "index_2 as int", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 14 } ], "suggest": "", @@ -513,20 +456,33 @@ "severity": "ERROR" }, { - "line": 50, - "column": 5, - "endLine": 50, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1391, - "end": 1409, - "replacementText": "array1: number[] = [1, 2, 3]" - } - ], + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 45, + "endColumn": 15, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 1, + "endLine": 51, + "endColumn": 19, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -539,30 +495,17 @@ { "start": 1418, "end": 1428, - "replacementText": "getIndex() as int" + "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]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 64, "column": 3, @@ -573,6 +516,16 @@ "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": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 67, "column": 6, @@ -583,13 +536,57 @@ { "start": 1678, "end": 1683, - "replacementText": "TE.AA as int" + "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": 68, + "column": 1, + "endLine": 68, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 72, "column": 1, @@ -600,23 +597,57 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 73, "column": 6, "endLine": 73, - "endColumn": 9, + "endColumn": 19, "problem": "ArrayIndexExprType", "autofix": [ { "start": 1744, "end": 1757, - "replacementText": "1.1 as int" + "replacementText": "1.1 as int", + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 19 } ], "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 18, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 81, "column": 5, @@ -626,6 +657,151 @@ "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 16, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1938, + "end": 1949, + "replacementText": "1 as int", + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 1, + "endLine": 89, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 19, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1956, + "end": 1970, + "replacementText": "test as int", + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 29, + "endLine": 96, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 9, + "endLine": 99, + "endColumn": 30, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 15, + "endLine": 99, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 2185, + "end": 2199, + "replacementText": "this.testIndex as int", + "line": 99, + "column": 15, + "endLine": 99, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 2, + "endLine": 91, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n Link,\n} from '@kit.ArkUI';", + "line": 93, + "column": 4, + "endLine": 93, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 4, + "endLine": 93, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n Link,\n} from '@kit.ArkUI';", + "line": 93, + "column": 4, + "endLine": 93, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Link\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.json b/ets2panda/linter/test/main/array_index_expr_type.ets.json index 7c6994fca35d92ffa2db91cfaa3ea41750ea162c..2302200e1df44c3fc2570b294e514e0f3637a980 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.json @@ -53,6 +53,16 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 96, + "column": 29, + "endLine": 96, + "endColumn": 38, + "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/array_index_expr_type.ets.migrate.ets b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets index 0d5918aee10e9088cb8068f335cd2d3fbf8f1a27..7152b5d560c0b1018fe867f1fc7533677ff082e4 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets @@ -13,26 +13,31 @@ * limitations under the License. */ +import { + Component, + Link, +} from '@kit.ArkUI'; + function foo(index:number){ - let an_array: number[] = [1, 2, 3] - 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 an_array = [1,2,3] + let a = an_array[index as int] + let a1 = an_array[(index + 1) as int] + let a2 = an_array[(index + 1.1) as int] + let b = 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 g = an_array[] + let h = an_array[12. as int] + let i = an_array[12.0 as int] + let j = an_array[0] + let k = an_array[Number.MAX_VALUE as int] + let l = an_array[Number.MIN_VALUE as int] + let m = an_array[Number.MAX_SAFE_INTEGER as int] } -let array: number[] = [1, 2, 3] +let array = [1,2,3] const index_1: number = 1.3; let index_2: number = 1.3; let index_3: number = 1; @@ -47,10 +52,10 @@ array[index_5]; function getIndex(): number { return Math.random() * 10; } -let array1: number[] = [1, 2, 3]; +let array1 = [1, 2, 3]; array1[getIndex() as int]; -let array2: number[] = [1, 2, 3]; +let array2 = [1, 2, 3]; for (let i: number = 0; i < array2.length; i++) { console.log(array2[i]); } @@ -83,3 +88,21 @@ arr[a] = 1; arr[b] = 1; arr[c] = 1; arr[d] = 1; + +let test = 1; +arr[1 as int]; +arr[test as int]; + +@Component +struct Test { + @Link testIndex: number; + + async cateMode(testIndex: number) { + emitter.on(innerEvent, (eventData) => { + if (this.testIndex == 0) { + let array = [1,2,3]; + array[this.testIndex as int]; + } + }) + } +} 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 index 8407a76e0f1a39a6b7313c0ba4b4143b441bb8ad..3ee4a7e174a0e425be6469311add39767c8e77bf 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 22, + "line": 27, "column": 7, - "endLine": 22, + "endLine": 27, "endColumn": 25, "problem": "AnyType", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 27, "column": 20, - "endLine": 22, + "endLine": 27, "endColumn": 24, "problem": "ArrayIndexExprType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 28, "column": 7, - "endLine": 23, + "endLine": 28, "endColumn": 28, "problem": "AnyType", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 28, "column": 20, - "endLine": 23, + "endLine": 28, "endColumn": 27, "problem": "ArrayIndexExprType", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 29, "column": 7, - "endLine": 24, + "endLine": 29, "endColumn": 30, "problem": "AnyType", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 29, "column": 20, - "endLine": 24, + "endLine": 29, "endColumn": 29, "problem": "ArrayIndexExprType", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 30, "column": 7, - "endLine": 25, + "endLine": 30, "endColumn": 25, "problem": "AnyType", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 30, "column": 20, - "endLine": 25, + "endLine": 30, "endColumn": 24, "problem": "ArrayIndexExprType", "suggest": "", @@ -95,19 +95,49 @@ "severity": "ERROR" }, { - "line": 26, - "column": 28, - "endLine": 26, - "endColumn": 28, + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 20, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, { - "line": 64, + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 22, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 1, + "endLine": 46, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 69, "column": 3, - "endLine": 64, + "endLine": 69, "endColumn": 12, "problem": "EnumMemberNonConstInit", "suggest": "", @@ -115,9 +145,49 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 74, "column": 1, - "endLine": 72, + "endLine": 74, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, "endColumn": 9, "problem": "IndexNegative", "suggest": "", @@ -125,14 +195,44 @@ "severity": "ERROR" }, { - "line": 81, + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 18, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 86, "column": 5, - "endLine": 81, + "endLine": 86, "endColumn": 17, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" + }, + { + "line": 101, + "column": 29, + "endLine": 101, + "endColumn": 38, + "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/avoid_using_union_types.ets b/ets2panda/linter/test/main/avoid_using_union_types.ets index 907449c2fa6cf690316687315692376de55b20bf..9b96d9dc4b9be27401b5cb27dad71ae1522d5437 100644 --- a/ets2panda/linter/test/main/avoid_using_union_types.ets +++ b/ets2panda/linter/test/main/avoid_using_union_types.ets @@ -33,4 +33,21 @@ 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); +class D { + tt() {} +} +class E { + tt() {} +} +let ab: D|E = new D(); +ab.tt(); + +declare interface TextPickerResult { + value: string | string[]; +} +const result: TextPickerResult = { value: 'a' }; +result.value.toString() // no error - ok 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..493b980c6747842aa8f083f4f6ae83999f83bc9b 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,15 @@ "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": 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/builder_node.ets b/ets2panda/linter/test/main/builder_node.ets new file mode 100644 index 0000000000000000000000000000000000000000..a277872e970debdb85bfe7d4f35e99d570c12d83 --- /dev/null +++ b/ets2panda/linter/test/main/builder_node.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 { NodeController, BuilderNode, FrameNode } from './ui_modules/@kit.ArkUI'; + +class Params { + item: string = ''; + + constructor(item: string) { + this.item = item; + } +} + +interface CustomInterface { + item: string; + age: number; +} + +class CustomClass { + private item: string = 'C'; + age: number = 10; +} + +@Builder +function buildNode(param: Params) {} + +function getObject1() { + const customInterfaceParams: CustomInterface | number = 1 > 0 ? { item: 'C', age: 100 } : 1; + return customInterfaceParams; +} + +function getObject2() { + const customInterfaceParams: CustomInterface = { + item: 'C', + age: 100 + }; + return customInterfaceParams; +} + +class MyNodeController extends NodeController { + public builderNode1: BuilderNode<[Params]> | null = null; // error + public builderNode2: BuilderNode<[Params]> | null = null; // error + public builderNode3: BuilderNode<[]> | null = null; // error + public builderNode4: BuilderNode<[]> | null = null; // error + public frameNode: FrameNode | null = null; + public item: string = ""; + + getObject3() { + const customInterfaceParams: CustomInterface = { + item: 'C', + age: 100 + }; + return customInterfaceParams; + } + + makeNode(uiContext: UIContext): FrameNode | null { + if (this.builderNode1 == null || this.builderNode2 == null + || this.builderNode3 == null || this.builderNode4 == null) { + this.builderNode1 = new BuilderNode(uiContext, { selfIdealSize : { width: 300, height: 200} }); + this.builderNode2 = new BuilderNode<[Params]>(uiContext, { selfIdealSize: { width: 300, height: 200} }); // error + this.builderNode3 = new BuilderNode(uiContext, { selfIdealSize : { width: 300, height: 200} }); + this.builderNode4 = new BuilderNode<[]>(uiContext, { selfIdealSize : { width: 300, height: 200} }); // error + this.builderNode1.build(wrapBuilder<[Params]>(buildNode), new Params(this.item), { nestingBuilderSupported: false }) // error + let flag = true; + this.builderNode2.build(wrapBuilder<[Params]>(buildNode), new Params(this.item), { nestingBuilderSupported: flag }); // error + } + + return this.frameNode; + } + + updateItem(item: string, customParam: boolean): void { + this.item = item; + if (this.builderNode1 && this.builderNode2 && this.builderNode3 && this.builderNode4) { + if (customParam) { + const a1: CustomInterface = { + item: 'C', + age: 100 + }; + const a2: CustomInterface | number = 1 > 0 ? { item: 'C', age: 100 } : 1; + const a3 = getObject1(); + const a4 = getObject2(); + const customClassParams: CustomClass = new CustomClass(); + this.builderNode1.update(a1); // error + this.builderNode2.update(a2); // error + this.builderNode3.update(a3); // error + this.builderNode4.update(a4); // error + this.builderNode1.update({ item: 'C', age: 100 }); // error + this.builderNode2.update(1 > 0 ? a1 : 1); // error + this.builderNode3.update(customClassParams); + this.builderNode3.update({ item: 'C', age: 100}); // error + this.builderNode4.update(getObject1()); // error + this.builderNode4.update(getObject2()); // error + this.builderNode4.update(this.getObject3()); // error + } else {} + } + } +} + +@Reusable +@Component +struct ReusableChildComponent { + private controller: MyNodeController = new MyNodeController(); + + aboutToReuse(params: Record): void { + this.controller?.builderNode1?.reuse(params); + } + + build() { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/builder_node.ets.args.json b/ets2panda/linter/test/main/builder_node.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/builder_node.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/builder_node.ets.arkts2.json b/ets2panda/linter/test/main/builder_node.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..fa11de342c962e69ff33e969b95d9eac7be2cac8 --- /dev/null +++ b/ets2panda/linter/test/main/builder_node.ets.arkts2.json @@ -0,0 +1,338 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 53, + "column": 24, + "endLine": 53, + "endColumn": 45, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 24, + "endLine": 54, + "endColumn": 45, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 24, + "endLine": 55, + "endColumn": 39, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 24, + "endLine": 56, + "endColumn": 39, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 27, + "endLine": 71, + "endColumn": 101, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 72, + "endLine": 71, + "endColumn": 73, + "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": 110, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 81, + "endLine": 72, + "endColumn": 82, + "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": 27, + "endLine": 73, + "endColumn": 101, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 72, + "endLine": 73, + "endColumn": 73, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 27, + "endLine": 74, + "endColumn": 105, + "problem": "BuilderNodeGenericNoTuple", + "suggest": "", + "rule": "The generic of \"BuilderNode\" does not accept tuple (arkui-buildernode-generic-no-tuple)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 76, + "endLine": 74, + "endColumn": 77, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 7, + "endLine": 75, + "endColumn": 123, + "problem": "BuilderNodeNoNestingBuilderSupported", + "suggest": "", + "rule": "Property \"nestingBuilderSupported\" is not supported (arkui-buildernode-no-nestingbuildersupported)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 31, + "endLine": 75, + "endColumn": 63, + "problem": "WrapBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"wrapBuilder\", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 7, + "endLine": 77, + "endColumn": 122, + "problem": "BuilderNodeNoNestingBuilderSupported", + "suggest": "", + "rule": "Property \"nestingBuilderSupported\" is not supported (arkui-buildernode-no-nestingbuildersupported)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 31, + "endLine": 77, + "endColumn": 63, + "problem": "WrapBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"wrapBuilder\", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 9, + "endLine": 95, + "endColumn": 37, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 9, + "endLine": 96, + "endColumn": 37, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 9, + "endLine": 97, + "endColumn": 37, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 9, + "endLine": 98, + "endColumn": 37, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 9, + "endLine": 99, + "endColumn": 58, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 9, + "endLine": 100, + "endColumn": 49, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 9, + "endLine": 102, + "endColumn": 57, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 9, + "endLine": 103, + "endColumn": 47, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 9, + "endLine": 104, + "endColumn": 47, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 9, + "endLine": 105, + "endColumn": 52, + "problem": "BuilderNodeUpdateNoLiteral", + "suggest": "", + "rule": "The \"update\" interface of \"BuilderNode\" does not accept an object literal. Please replace it with an instance of the class specified in the generic when creating a new \"BuilderNode\", and ensure that the instance has the same field values as the literal (arkui-buildernode-update-no-literal)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 2, + "endLine": 36, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 23, + "endLine": 68, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"UIContext\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 31, + "endLine": 75, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 31, + "endLine": 77, + "endColumn": 42, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 2, + "endLine": 111, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Reusable\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 2, + "endLine": 112, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/builder_node.ets.json b/ets2panda/linter/test/main/builder_node.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..cbe274b6acf883f870cc6ad44d783f614d81fb8d --- /dev/null +++ b/ets2panda/linter/test/main/builder_node.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": 71, + "column": 72, + "endLine": 71, + "endColumn": 73, + "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": 81, + "endLine": 72, + "endColumn": 82, + "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": 72, + "endLine": 73, + "endColumn": 73, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 76, + "endLine": 74, + "endColumn": 77, + "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/case_expr.ets.arkts2.json b/ets2panda/linter/test/main/case_expr.ets.arkts2.json index 6aac05a29b702d66a70faf39766582f1ed0a738a..185ad4e8d363965b35b273217a4102632f6aafa1 100755 --- a/ets2panda/linter/test/main/case_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/case_expr.ets.arkts2.json @@ -1,49 +1,19 @@ { - "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, - "column": 7, - "endLine": 17, - "endColumn": 16, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 7, - "endLine": 19, - "endColumn": 21, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 1, - "endLine": 23, - "endColumn": 2, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 29, "column": 8, @@ -61,7 +31,7 @@ "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)", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { @@ -84,16 +54,6 @@ "rule": "No two case constant expressions have identical values.(arkts-case-expr)", "severity": "ERROR" }, - { - "line": 65, - "column": 7, - "endLine": 65, - "endColumn": 25, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 77, "column": 8, diff --git a/ets2panda/linter/test/main/class_as_object.ets b/ets2panda/linter/test/main/class_as_object.ets index fcc5a362509dbc1bff8eeb8cb5d96f8848fc914e..a2bdc36a95399be407c6029f374cfaac2c55d802 100644 --- a/ets2panda/linter/test/main/class_as_object.ets +++ b/ets2panda/linter/test/main/class_as_object.ets @@ -203,4 +203,13 @@ function parse(type: "number" | "boolean", value: string): number | boolean { } function format(input: string | number): string[] | number[] { return typeof input === "string" ? input.split("") : input.toString().split("").map(Number); -} \ No newline at end of file +} + +let version: string = "1.2" +let a1 = version.split('.').map(Number); + +let version2: string = "1.2" +let a2 = version2.split('.').map(String); + +let version3: string = "1.2" +let a3 = version3.split('.').map(Boolean); \ 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 368d6ea3cad7777c00841d0645f8db69ae8ad8cd..8513dde89deb0dc97de2d37e5fff1980f7290c7f 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json @@ -14,26 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 17, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 17, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 27, "column": 9, @@ -74,26 +54,6 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, - { - "line": 32, - "column": 5, - "endLine": 32, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 5, - "endLine": 33, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 38, "column": 20, @@ -194,36 +154,6 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, - { - "line": 70, - "column": 9, - "endLine": 70, - "endColumn": 47, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 9, - "endLine": 71, - "endColumn": 47, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 9, - "endLine": 72, - "endColumn": 50, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 79, "column": 27, @@ -244,16 +174,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 87, - "column": 10, - "endLine": 87, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 87, "column": 39, @@ -305,13 +225,23 @@ "severity": "ERROR" }, { - "line": 116, - "column": 10, - "endLine": 116, - "endColumn": 18, - "problem": "NumericSemantics", + "line": 102, + "column": 13, + "endLine": 102, + "endColumn": 23, + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 18, + "endLine": 114, + "endColumn": 25, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -354,36 +284,6 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, - { - "line": 129, - "column": 15, - "endLine": 129, - "endColumn": 21, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 130, - "column": 15, - "endLine": 130, - "endColumn": 22, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 131, - "column": 15, - "endLine": 131, - "endColumn": 21, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, { "line": 132, "column": 15, @@ -765,23 +665,73 @@ "severity": "ERROR" }, { - "line": 172, + "line": 171, "column": 7, + "endLine": 171, + "endColumn": 14, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 17, + "endLine": 171, + "endColumn": 31, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 15, "endLine": 172, - "endColumn": 32, - "problem": "NumericSemantics", + "endColumn": 20, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 14, + "endLine": 174, + "endColumn": 21, + "problem": "BuiltinNoCtorFunc", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 14, + "endLine": 175, + "endColumn": 18, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 13, + "endLine": 176, + "endColumn": 18, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", "severity": "ERROR" }, { "line": 179, - "column": 7, + "column": 13, "endLine": 179, - "endColumn": 25, - "problem": "NumericSemantics", + "endColumn": 19, + "problem": "BuiltinNoCtorFunc", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", "severity": "ERROR" }, { @@ -794,6 +744,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 180, + "column": 13, + "endLine": 180, + "endColumn": 19, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, { "line": 183, "column": 15, @@ -804,6 +764,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 184, + "column": 13, + "endLine": 184, + "endColumn": 19, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 185, "column": 13, @@ -824,6 +794,16 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, + { + "line": 192, + "column": 15, + "endLine": 192, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, { "line": 193, "column": 9, @@ -831,7 +811,7 @@ "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)", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { @@ -845,23 +825,13 @@ "severity": "ERROR" }, { - "line": 205, - "column": 56, - "endLine": 205, - "endColumn": 94, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 205, - "column": 87, - "endLine": 205, - "endColumn": 93, - "problem": "ClassAsObjectError", + "line": 202, + "column": 30, + "endLine": 202, + "endColumn": 36, + "problem": "BuiltinNoCtorFunc", "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/class_as_object.ets.json b/ets2panda/linter/test/main/class_as_object.ets.json index cb35d6177679bf650989f405a3789586682d341a..5bfa876a0a6016cbd595b86d7b7b8f93779affe8 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.json +++ b/ets2panda/linter/test/main/class_as_object.ets.json @@ -212,36 +212,6 @@ "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, @@ -661,16 +631,6 @@ "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 index c13aa9b54ab1233ccdae9d6496c2f0e0147d1570..deb0598bc5812f2ca3d2f86f185f3c1020dbd16b 100644 --- a/ets2panda/linter/test/main/class_no_constructor.ets +++ b/ets2panda/linter/test/main/class_no_constructor.ets @@ -17,3 +17,13 @@ class A {} const variable = new A().constructor + +let a = new A() +console.log(a.constructor + ""); + +function foo3(): A { + return new A(); +} +console.log(foo3().constructor + ""); + +console.log(A.constructor + ""); \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json index 12f07f6aefeab765323013130ba3901be22f8c2f..940e32b5f0db67161e3a9f6e0e07d54293a1c577 100644 --- a/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json @@ -21,7 +21,37 @@ "endColumn": 37, "problem": "NoConstructorOnClass", "suggest": "", - "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 13, + "endLine": 22, + "endColumn": 26, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 31, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 13, + "endLine": 29, + "endColumn": 26, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets index c13aa9b54ab1233ccdae9d6496c2f0e0147d1570..deb0598bc5812f2ca3d2f86f185f3c1020dbd16b 100644 --- a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets @@ -17,3 +17,13 @@ class A {} const variable = new A().constructor + +let a = new A() +console.log(a.constructor + ""); + +function foo3(): A { + return new A(); +} +console.log(foo3().constructor + ""); + +console.log(A.constructor + ""); \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json index 12f07f6aefeab765323013130ba3901be22f8c2f..940e32b5f0db67161e3a9f6e0e07d54293a1c577 100644 --- a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json @@ -21,7 +21,37 @@ "endColumn": 37, "problem": "NoConstructorOnClass", "suggest": "", - "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 13, + "endLine": 22, + "endColumn": 26, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 31, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 13, + "endLine": 29, + "endColumn": 26, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "Objects have no constructor property in ArkTS1.2 (arkts-obj-no-constructor)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/class_static_init.ets b/ets2panda/linter/test/main/class_static_init.ets index c74ec693d923b780a737b7bae7c058db3e8696d4..05149dab13b44316b307e5d736e9899e2686a23a 100755 --- a/ets2panda/linter/test/main/class_static_init.ets +++ b/ets2panda/linter/test/main/class_static_init.ets @@ -139,7 +139,7 @@ class FunctionTypes { class ComplexTypes { static uninitializedComplexArray: Array<{ id: number; data: Map> }>; static uninitializedRecord: Record; - static uninitializedTuple: [string, number, boolean?]; + static uninitializedTuple: [string, number, boolean]; } // Custom Class Types diff --git a/ets2panda/linter/test/main/class_static_init.ets.args.json b/ets2panda/linter/test/main/class_static_init.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..3ef4496a819a201892114d1c90f78ae32053c334 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.args.json +++ b/ets2panda/linter/test/main/class_static_init.ets.args.json @@ -14,7 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2" + "arkts2": "" } } diff --git a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json old mode 100755 new mode 100644 index 17db245900a4df3e63c8fb82090b3ba1c3d0e4a1..6f8984af61c485b56191c0c266bc5a58d73138de --- a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_static_init.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": [ { @@ -398,7 +398,7 @@ "line": 142, "column": 3, "endLine": 142, - "endColumn": 57, + "endColumn": 56, "problem": "ClassstaticInitialization", "suggest": "", "rule": "The static property has no initializer (arkts-class-static-initialization)", @@ -501,7 +501,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -511,7 +511,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -521,7 +521,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -531,7 +531,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/class_static_init.ets.autofix.json b/ets2panda/linter/test/main/class_static_init.ets.autofix.json deleted file mode 100644 index 2be737a16e4dfb45b6d657993f04648d89d1736b..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/main/class_static_init.ets.autofix.json +++ /dev/null @@ -1,876 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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": 14, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 641, - "end": 652, - "replacementText": "static a: A | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 3, - "endLine": 25, - "endColumn": 14, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 668, - "end": 679, - "replacementText": "static g: G | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 15, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 753, - "end": 765, - "replacementText": "static g: G | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 3, - "endLine": 36, - "endColumn": 14, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 781, - "end": 792, - "replacementText": "static a: A | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 3, - "endLine": 46, - "endColumn": 29, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 933, - "end": 959, - "replacementText": "public static abc: string = \"\";" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 3, - "endLine": 59, - "endColumn": 16, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1088, - "end": 1101, - "replacementText": "static b: BB | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 35, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1156, - "end": 1188, - "replacementText": "static config: {\n theme: string;\n} = {\n theme: \"\"\n };" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 18, - "endLine": 67, - "endColumn": 19, - "problem": "ObjectTypeLiteral", - "autofix": [ - { - "start": 1143, - "end": 1143, - "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n theme: string;\n}\n" - }, - { - "start": 1171, - "end": 1187, - "replacementText": "GeneratedTypeLiteralInterface_1" - } - ], - "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", - "autofix": [ - { - "start": 1205, - "end": 1225, - "replacementText": "static name: string = \"\";" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 3, - "endLine": 79, - "endColumn": 38, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1314, - "end": 1349, - "replacementText": "static uninitializedString: string = \"\";" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 86, - "column": 3, - "endLine": 86, - "endColumn": 45, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1467, - "end": 1509, - "replacementText": "static uninitializedStringArray: string[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 3, - "endLine": 87, - "endColumn": 45, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1512, - "end": 1554, - "replacementText": "static uninitializedNumberArray: number[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 88, - "column": 3, - "endLine": 88, - "endColumn": 53, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1557, - "end": 1607, - "replacementText": "static uninitializedObjectArray: {\n id: number;\n }[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 88, - "column": 36, - "endLine": 88, - "endColumn": 37, - "problem": "ObjectTypeLiteral", - "autofix": [ - { - "start": 1446, - "end": 1446, - "replacementText": "interface GeneratedTypeLiteralInterface_2 {\n id: number;\n}\n" - }, - { - "start": 1590, - "end": 1604, - "replacementText": "GeneratedTypeLiteralInterface_2" - } - ], - "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", - "autofix": [ - { - "start": 1610, - "end": 1662, - "replacementText": "static uninitializedUnionArray: (string | number)[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 94, - "column": 3, - "endLine": 94, - "endColumn": 67, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1704, - "end": 1768, - "replacementText": "static uninitializedSimpleObject: {\n name: string;\n age: number;\n} = {\n name: \"\"\n };" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 94, - "column": 37, - "endLine": 94, - "endColumn": 38, - "problem": "ObjectTypeLiteral", - "autofix": [ - { - "start": 1682, - "end": 1682, - "replacementText": "interface GeneratedTypeLiteralInterface_3 {\n name: string;\n age: number;\n}\n" - }, - { - "start": 1738, - "end": 1767, - "replacementText": "GeneratedTypeLiteralInterface_3" - } - ], - "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", - "autofix": [ - { - "start": 1771, - "end": 1895, - "replacementText": "static uninitializedNestedObject: {\n id: number;\n metadata: {\n createdAt: Date;\n tags: string[];\n };\n} = {\n metadata: {\n createdAt: new Date(),\n tags: []\n }\n };" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 95, - "column": 37, - "endLine": 95, - "endColumn": 38, - "problem": "ObjectTypeLiteral", - "autofix": [ - { - "start": 1682, - "end": 1682, - "replacementText": "interface GeneratedTypeLiteralInterface_4 {\n id: number;\n metadata: {\n createdAt: Date;\n tags: string[];\n };\n}\n" - }, - { - "start": 1805, - "end": 1894, - "replacementText": "GeneratedTypeLiteralInterface_4" - } - ], - "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", - "autofix": [ - { - "start": 1682, - "end": 1682, - "replacementText": "interface GeneratedTypeLiteralInterface_5 {\n createdAt: Date;\n tags: string[];\n}\n" - }, - { - "start": 1837, - "end": 1889, - "replacementText": "GeneratedTypeLiteralInterface_5" - } - ], - "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", - "autofix": [ - { - "start": 1948, - "end": 1979, - "replacementText": "static uninitializedDate: Date = new Date();" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 3, - "endLine": 107, - "endColumn": 48, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 1982, - "end": 2027, - "replacementText": "static uninitializedMap: Map = new Map();" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 108, - "column": 3, - "endLine": 108, - "endColumn": 40, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 2030, - "end": 2067, - "replacementText": "static uninitializedSet: Set = new Set();" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 3, - "endLine": 109, - "endColumn": 46, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 2070, - "end": 2113, - "replacementText": "static uninitializedPromise: Promise = undefined;" - } - ], - "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", - "autofix": [ - { - "start": 2149, - "end": 2149, - "replacementText": "interface GeneratedTypeLiteralInterface_6 {\n name: string;\n}\n" - }, - { - "start": 2253, - "end": 2269, - "replacementText": "GeneratedTypeLiteralInterface_6" - } - ], - "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", - "autofix": [ - { - "start": 2149, - "end": 2149, - "replacementText": "interface GeneratedTypeLiteralInterface_7 {\n age: number;\n}\n" - }, - { - "start": 2272, - "end": 2287, - "replacementText": "GeneratedTypeLiteralInterface_7" - } - ], - "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", - "autofix": [ - { - "start": 2567, - "end": 2605, - "replacementText": "static uninitializedGenericArray: T[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 129, - "column": 3, - "endLine": 129, - "endColumn": 39, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 2608, - "end": 2644, - "replacementText": "static uninitializedGenericValue: T | undefined = undefined;" - } - ], - "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", - "autofix": [ - { - "start": 2821, - "end": 2821, - "replacementText": "interface GeneratedTypeLiteralInterface_8 {\n id: number;\n data: Map>;\n}\n" - }, - { - "start": 2884, - "end": 2930, - "replacementText": "GeneratedTypeLiteralInterface_8" - } - ], - "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", - "autofix": [ - { - "start": 2935, - "end": 2997, - "replacementText": "static uninitializedRecord: Record | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 141, - "column": 46, - "endLine": 141, - "endColumn": 47, - "problem": "ObjectTypeLiteral", - "autofix": [ - { - "start": 2821, - "end": 2821, - "replacementText": "interface GeneratedTypeLiteralInterface_9 {\n value: number;\n}\n" - }, - { - "start": 2978, - "end": 2995, - "replacementText": "GeneratedTypeLiteralInterface_9" - } - ], - "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", - "autofix": [ - { - "start": 3153, - "end": 3184, - "replacementText": "static uninitializedUser: User | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 153, - "column": 3, - "endLine": 153, - "endColumn": 37, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 3187, - "end": 3221, - "replacementText": "static uninitializedUsers: User[] = [];" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 163, - "column": 3, - "endLine": 163, - "endColumn": 38, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 3297, - "end": 3332, - "replacementText": "static uninitializedStatus: Status | undefined = undefined;" - } - ], - "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", - "severity": "ERROR" - }, - { - "line": 164, - "column": 3, - "endLine": 164, - "endColumn": 45, - "problem": "ClassstaticInitialization", - "autofix": [ - { - "start": 3335, - "end": 3377, - "replacementText": "static uninitializedStatusArray: Status[] = [];" - } - ], - "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, - "endLine": 42, - "endColumn": 7, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" - } - ], - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 2, - "endLine": 43, - "endColumn": 11, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" - } - ], - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 4, - "endLine": 45, - "endColumn": 9, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" - } - ], - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 7, - "endLine": 49, - "endColumn": 11, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Text } from '@kit.ArkUI';" - } - ], - "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/collections_module.ets b/ets2panda/linter/test/main/collections_module.ets index 5fba982f6b6426a38730e4019763ff9658df5fc2..f61a5a5a4d52d648c5a17b1166ade1c58a424468 100644 --- a/ets2panda/linter/test/main/collections_module.ets +++ b/ets2panda/linter/test/main/collections_module.ets @@ -19,7 +19,7 @@ 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 +import { collections as definedCollections } from './ignore_files/user_defined_collections'; //legal function tesCollectionsUsage() { @@ -36,3 +36,11 @@ function tesCollectionsUsage() { let collections6: definedCollections.Array; // legal } + +function test(array: collections.Array) { + const map = collections.Map(); +} + +function testBitVector(bv: collections.BitVector) { + const bitVector = new collections.BitVector(); +} diff --git a/ets2panda/linter/test/main/collections_module.ets.arkts2.json b/ets2panda/linter/test/main/collections_module.ets.arkts2.json index 584e375a01ba06e7a2ecd03772a34d762c5ccbba..e3169afb9917508130f19c1aeb3a142fd76c060a 100644 --- a/ets2panda/linter/test/main/collections_module.ets.arkts2.json +++ b/ets2panda/linter/test/main/collections_module.ets.arkts2.json @@ -14,24 +14,14 @@ "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", + "endColumn": 41, + "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", - "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, { @@ -48,10 +38,10 @@ "line": 20, "column": 10, "endLine": 20, - "endColumn": 21, - "problem": "NoNeedStdLibSendableContainer", + "endColumn": 39, + "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", - "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, { @@ -68,7 +58,7 @@ "line": 26, "column": 23, "endLine": 26, - "endColumn": 34, + "endColumn": 40, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -78,7 +68,7 @@ "line": 26, "column": 55, "endLine": 26, - "endColumn": 66, + "endColumn": 72, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -88,7 +78,7 @@ "line": 28, "column": 28, "endLine": 28, - "endColumn": 44, + "endColumn": 50, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -98,7 +88,7 @@ "line": 30, "column": 28, "endLine": 30, - "endColumn": 42, + "endColumn": 48, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -108,7 +98,7 @@ "line": 32, "column": 21, "endLine": 32, - "endColumn": 37, + "endColumn": 43, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -118,7 +108,7 @@ "line": 34, "column": 23, "endLine": 34, - "endColumn": 39, + "endColumn": 45, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", @@ -128,11 +118,71 @@ "line": 34, "column": 60, "endLine": 34, - "endColumn": 76, + "endColumn": 82, "problem": "NoNeedStdLibSendableContainer", "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" + }, + { + "line": 40, + "column": 22, + "endLine": 40, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 11, + "endLine": 41, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 17, + "endLine": 41, + "endColumn": 32, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 29, + "endLine": 41, + "endColumn": 32, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 11, + "endLine": 45, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 27, + "endLine": 45, + "endColumn": 48, + "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/collections_module.ets.autofix.json b/ets2panda/linter/test/main/collections_module.ets.autofix.json index 3b091c13f428361247667bb4cc8bd51cef9274b9..717aaa4ab4898b8e68b5d54c1849f827775e990e 100644 --- a/ets2panda/linter/test/main/collections_module.ets.autofix.json +++ b/ets2panda/linter/test/main/collections_module.ets.autofix.json @@ -14,38 +14,61 @@ "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", + "endColumn": 41, + "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { "start": 669, "end": 751, - "replacementText": "" + "replacementText": "", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 41 + }, + { + "start": 1074, + "end": 1090, + "replacementText": "collections", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 41 + }, + { + "start": 1189, + "end": 1205, + "replacementText": "collections", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 41 + }, + { + "start": 1244, + "end": 1260, + "replacementText": "collections", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 41 + }, + { + "start": 1281, + "end": 1297, + "replacementText": "collections", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 41 } ], "suggest": "", - "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, { @@ -58,7 +81,11 @@ { "start": 669, "end": 751, - "replacementText": "" + "replacementText": "", + "line": 18, + "column": 25, + "endLine": 18, + "endColumn": 41 } ], "suggest": "", @@ -69,17 +96,30 @@ "line": 20, "column": 10, "endLine": 20, - "endColumn": 21, - "problem": "NoNeedStdLibSendableContainer", + "endColumn": 39, + "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { "start": 753, "end": 825, - "replacementText": "" + "replacementText": "", + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 39 + }, + { + "start": 1136, + "end": 1150, + "replacementText": "collections", + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 39 } ], "suggest": "", - "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", "severity": "ERROR" }, { @@ -92,7 +132,11 @@ { "start": 753, "end": 825, - "replacementText": "" + "replacementText": "", + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 39 } ], "suggest": "", @@ -103,13 +147,17 @@ "line": 26, "column": 23, "endLine": 26, - "endColumn": 34, + "endColumn": 40, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 965, - "end": 982, - "replacementText": "Array" + "start": 985, + "end": 1002, + "replacementText": "Array", + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 40 } ], "suggest": "", @@ -120,13 +168,17 @@ "line": 26, "column": 55, "endLine": 26, - "endColumn": 66, + "endColumn": 72, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 997, - "end": 1014, - "replacementText": "Array" + "start": 1017, + "end": 1034, + "replacementText": "Array", + "line": 26, + "column": 55, + "endLine": 26, + "endColumn": 72 } ], "suggest": "", @@ -137,13 +189,17 @@ "line": 28, "column": 28, "endLine": 28, - "endColumn": 44, + "endColumn": 50, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 1054, - "end": 1076, - "replacementText": "Array" + "start": 1074, + "end": 1096, + "replacementText": "Array", + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 50 } ], "suggest": "", @@ -154,13 +210,17 @@ "line": 30, "column": 28, "endLine": 30, - "endColumn": 42, + "endColumn": 48, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 1116, - "end": 1136, - "replacementText": "Array" + "start": 1136, + "end": 1156, + "replacementText": "Array", + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 48 } ], "suggest": "", @@ -171,13 +231,17 @@ "line": 32, "column": 21, "endLine": 32, - "endColumn": 37, + "endColumn": 43, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 1169, - "end": 1191, - "replacementText": "Array" + "start": 1189, + "end": 1211, + "replacementText": "Array", + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 43 } ], "suggest": "", @@ -188,13 +252,17 @@ "line": 34, "column": 23, "endLine": 34, - "endColumn": 39, + "endColumn": 45, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 1224, - "end": 1246, - "replacementText": "Array" + "start": 1244, + "end": 1266, + "replacementText": "Array", + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 45 } ], "suggest": "", @@ -205,18 +273,104 @@ "line": 34, "column": 60, "endLine": 34, - "endColumn": 76, + "endColumn": 82, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1281, + "end": 1303, + "replacementText": "Array", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 82 + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 22, + "endLine": 40, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1404, + "end": 1421, + "replacementText": "Array", + "line": 40, + "column": 22, + "endLine": 40, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 11, + "endLine": 41, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 17, + "endLine": 41, + "endColumn": 32, "problem": "NoNeedStdLibSendableContainer", "autofix": [ { - "start": 1261, - "end": 1283, - "replacementText": "Array" + "start": 1449, + "end": 1464, + "replacementText": "Map", + "line": 41, + "column": 17, + "endLine": 41, + "endColumn": 32 } ], "suggest": "", "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", "severity": "ERROR" + }, + { + "line": 41, + "column": 29, + "endLine": 41, + "endColumn": 32, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 11, + "endLine": 45, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 27, + "endLine": 45, + "endColumn": 48, + "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/collections_module.ets.json b/ets2panda/linter/test/main/collections_module.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..927ff202214f3a1090827f0856d16510b65298d6 100644 --- a/ets2panda/linter/test/main/collections_module.ets.json +++ b/ets2panda/linter/test/main/collections_module.ets.json @@ -13,5 +13,36 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] -} \ No newline at end of file + "result": [ + { + "line": 41, + "column": 11, + "endLine": 41, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 29, + "endLine": 41, + "endColumn": 32, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 45, + "column": 11, + "endLine": 45, + "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/main/collections_module.ets.migrate.ets b/ets2panda/linter/test/main/collections_module.ets.migrate.ets index 02fc9aaad5de07117bf611e6701de10bcfd98aa1..e0e1909146271caca89e4884b33bd88b0b120bc2 100644 --- a/ets2panda/linter/test/main/collections_module.ets.migrate.ets +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.ets @@ -13,21 +13,21 @@ * limitations under the License. */ +import { collections } from './oh_modules/@arkts.collections'; - -import { collections as definedCollections } from 'user_defined_worker'; //legal +import { collections as definedCollections } from './ignore_files/user_defined_collections'; //legal function tesCollectionsUsage() { const collections1: Array = new Array(); - const collections2: number[] = new Array(); + const collections2 = new Array(); - const collections3: number[] = new Array(); + const collections3 = new Array(); let collections4: Array; @@ -36,3 +36,11 @@ function tesCollectionsUsage() { let collections6: definedCollections.Array; // legal } + +function test(array: Array) { + const map = Map(); +} + +function testBitVector(bv: collections.BitVector) { + const bitVector = new collections.BitVector(); +} diff --git a/ets2panda/linter/test/main/collections_module.ets.migrate.json b/ets2panda/linter/test/main/collections_module.ets.migrate.json index 4dcf9e56dbc14e1fbd427eeb3ad24f841cacf0ce..3c02aec6ac4766ca81b71799b5371a31cb8faa38 100644 --- a/ets2panda/linter/test/main/collections_module.ets.migrate.json +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.json @@ -13,6 +13,76 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] -} - + "result": [ + { + "line": 26, + "column": 43, + "endLine": 26, + "endColumn": 48, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 43, + "endLine": 34, + "endColumn": 48, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 11, + "endLine": 41, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 11, + "endLine": 45, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 27, + "endLine": 45, + "endColumn": 48, + "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/comment_test.ets b/ets2panda/linter/test/main/comment_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..3731be6780b463c034d4600620956d2c92f5d13b --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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 TestClass { + /** + * This is a comment. + */ + property = 123; // This is a comment. + // This is a comment. + arr = [1, 0]; // This is a comment. +} diff --git a/ets2panda/linter/test/main/comment_test.ets.args.json b/ets2panda/linter/test/main/comment_test.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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/comment_test.ets.arkts2.json b/ets2panda/linter/test/main/comment_test.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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": [] +} diff --git a/ets2panda/linter/test/main/comment_test.ets.autofix.json b/ets2panda/linter/test/main/comment_test.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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/comment_test.ets.json b/ets2panda/linter/test/main/comment_test.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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/comment_test.ets.migrate.ets b/ets2panda/linter/test/main/comment_test.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3731be6780b463c034d4600620956d2c92f5d13b --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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. + */ + +class TestClass { + /** + * This is a comment. + */ + property = 123; // This is a comment. + // This is a comment. + arr = [1, 0]; // This is a comment. +} diff --git a/ets2panda/linter/test/main/comment_test.ets.migrate.json b/ets2panda/linter/test/main/comment_test.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/comment_test.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/common_union_member_access.ets b/ets2panda/linter/test/main/common_union_member_access.ets new file mode 100644 index 0000000000000000000000000000000000000000..716957b9505fe2df7480ed6e490cd3d1e86fc92d --- /dev/null +++ b/ets2panda/linter/test/main/common_union_member_access.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 { MapKit } from './oh_modules/@ohos.util.HashMap'; + +let hashMap = new MapKit.HashMap(); +let res = hashMap.keys(); +for (let i = 0; i < hashMap.length; i++) { + let result = hashMap.hasKey(res.next().value!); + result = hashMap.hasKey(res.next().value); +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/common_union_member_access.ets.args.json b/ets2panda/linter/test/main/common_union_member_access.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..9b16bb93a4605b3465a0f919cd2f678737401555 --- /dev/null +++ b/ets2panda/linter/test/main/common_union_member_access.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/common_union_member_access.ets.arkts2.json b/ets2panda/linter/test/main/common_union_member_access.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..72664bab13a0bfa9216b34036e0ef086bdaef43e --- /dev/null +++ b/ets2panda/linter/test/main/common_union_member_access.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": 21, + "column": 31, + "endLine": 21, + "endColumn": 47, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 43, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/common_union_member_access.ets.json b/ets2panda/linter/test/main/common_union_member_access.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/common_union_member_access.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/custom_layout.ets b/ets2panda/linter/test/main/custom_layout.ets index 233a5aaa79d649a1bb3495a25e6cac4ec5b782e9..eb0c300ec863379315cc824d1a5f91875ea6115d 100644 --- a/ets2panda/linter/test/main/custom_layout.ets +++ b/ets2panda/linter/test/main/custom_layout.ets @@ -20,6 +20,7 @@ struct Index { Column() { CustomLayout1({ builder: ColumnChildren }) CustomLayout2({ builder: ColumnChildren }) + CustomLayout3({ builder: ColumnChildren }) } } } @@ -94,7 +95,44 @@ struct CustomLayout2 { @Component struct CustomLayout3 { - build { + @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; + } + + 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 CustomLayout4 { + build() { } } \ 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 index 7491a643b31af7bfc5d6037f36a32eaa74a9f7e1..4ebfad73cab7d735f6d1b3fc9a1f2d27c811aa31 100644 --- a/ets2panda/linter/test/main/custom_layout.ets.arkts2.json +++ b/ets2panda/linter/test/main/custom_layout.ets.arkts2.json @@ -15,63 +15,33 @@ ], "result": [ { - "line": 40, + "line": 41, "column": 8, - "endLine": 40, + "endLine": 41, "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": 53, - "column": 9, - "endLine": 53, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The Custom component \"CustomLayout1\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "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, + "line": 67, "column": 8, - "endLine": 66, + "endLine": 67, "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": 79, - "column": 9, - "endLine": 79, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The Custom component \"CustomLayout2\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { "line": 97, - "column": 3, + "column": 8, "endLine": 97, - "endColumn": 8, - "problem": "AnyType", + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "The Custom component \"CustomLayout3\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { @@ -81,7 +51,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,217 +71,337 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 2, - "endLine": 27, + "endLine": 28, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 29, + "line": 30, "column": 3, - "endLine": 29, + "endLine": 30, "endColumn": 10, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 30, + "line": 31, "column": 5, - "endLine": 30, + "endLine": 31, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 39, + "line": 40, "column": 2, - "endLine": 39, + "endLine": 40, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 41, + "line": 42, "column": 4, - "endLine": 41, + "endLine": 42, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 45, + "line": 46, "column": 4, - "endLine": 45, + "endLine": 46, "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 4, - "endLine": 46, + "endLine": 47, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 47, + "line": 48, "column": 11, - "endLine": 47, + "endLine": 48, "endColumn": 21, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 35, - "endLine": 52, + "endLine": 53, "endColumn": 47, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 65, - "endLine": 52, + "endLine": 53, "endColumn": 75, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Layoutable\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 90, - "endLine": 52, + "endLine": 53, "endColumn": 111, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 65, + "line": 66, "column": 2, - "endLine": 65, + "endLine": 66, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 67, + "line": 68, "column": 4, - "endLine": 67, + "endLine": 68, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 71, + "line": 72, "column": 4, - "endLine": 71, + "endLine": 72, "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 4, - "endLine": 72, + "endLine": 73, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 73, + "line": 74, "column": 11, - "endLine": 73, + "endLine": 74, "endColumn": 21, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 33, - "endLine": 78, + "endLine": 79, "endColumn": 45, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 63, - "endLine": 78, + "endLine": 79, "endColumn": 73, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Measurable\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 88, - "endLine": 78, + "endLine": 79, "endColumn": 109, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 81, + "line": 82, "column": 19, - "endLine": 81, + "endLine": 82, "endColumn": 32, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"MeasureResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 2, + "endLine": 96, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 4, + "endLine": 98, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 4, + "endLine": 102, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 4, + "endLine": 103, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 11, + "endLine": 104, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 33, + "endLine": 109, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 63, + "endLine": 109, + "endColumn": 73, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Measurable\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 88, + "endLine": 109, + "endColumn": 109, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 19, + "endLine": 112, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"MeasureResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 35, + "endLine": 120, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 65, + "endLine": 120, + "endColumn": 75, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Layoutable\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 90, + "endLine": 120, + "endColumn": 111, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 95, + "line": 133, "column": 2, - "endLine": 95, + "endLine": 133, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/custom_layout.ets.autofix.json b/ets2panda/linter/test/main/custom_layout.ets.autofix.json index 05aaabc6d85a1cc8a3a29a00fe92cb12e7e7299f..dea2292ba6abc898440fc7060be44175c449b762 100644 --- a/ets2panda/linter/test/main/custom_layout.ets.autofix.json +++ b/ets2panda/linter/test/main/custom_layout.ets.autofix.json @@ -15,98 +15,66 @@ ], "result": [ { - "line": 40, + "line": 41, "column": 8, - "endLine": 40, + "endLine": 41, "endColumn": 21, "problem": "CustomLayoutNeedAddDecorator", "autofix": [ { - "start": 1027, - "end": 1027, - "replacementText": "\n@Layoutable" - } - ], - "suggest": "", - "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 9, - "endLine": 53, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1367, - "end": 1381, - "replacementText": "startPos: number = 300" - } - ], - "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" + "start": 1076, + "end": 1076, + "replacementText": "\n@CustomLayout", + "line": 41, + "column": 8, + "endLine": 41, + "endColumn": 21 } ], "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The Custom component \"CustomLayout1\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 66, + "line": 67, "column": 8, - "endLine": 66, + "endLine": 67, "endColumn": 21, "problem": "CustomLayoutNeedAddDecorator", "autofix": [ { - "start": 1571, - "end": 1571, - "replacementText": "\n@Layoutable" + "start": 1620, + "end": 1620, + "replacementText": "\n@CustomLayout", + "line": 67, + "column": 8, + "endLine": 67, + "endColumn": 21 } ], "suggest": "", - "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", + "rule": "The Custom component \"CustomLayout2\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { - "line": 79, - "column": 9, - "endLine": 79, - "endColumn": 19, - "problem": "NumericSemantics", + "line": 97, + "column": 8, + "endLine": 97, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", "autofix": [ { - "start": 1909, - "end": 1919, - "replacementText": "size: number = 100" + "start": 2304, + "end": 2304, + "replacementText": "\n@CustomLayout", + "line": 97, + "column": 8, + "endLine": 97, + "endColumn": 21 } ], "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)", + "rule": "The Custom component \"CustomLayout3\" with custom layout capability needs to add the \"@CustomLayout\" decorator (arkui-custom-layout-need-add-decorator)", "severity": "ERROR" }, { @@ -119,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -136,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -153,368 +129,708 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 2, - "endLine": 27, + "endLine": 28, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 29, + "line": 30, "column": 3, - "endLine": 29, + "endLine": 30, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 30, + "line": 31, "column": 5, - "endLine": 30, + "endLine": 31, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 39, + "line": 40, "column": 2, - "endLine": 39, + "endLine": 40, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 41, + "line": 42, "column": 4, - "endLine": 41, + "endLine": 42, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 45, + "line": 46, "column": 4, - "endLine": 45, + "endLine": 46, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 4, - "endLine": 46, + "endLine": 47, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 47, + "line": 48, "column": 11, - "endLine": 47, + "endLine": 48, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 35, - "endLine": 52, + "endLine": 53, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 65, - "endLine": 52, + "endLine": 53, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Layoutable\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 52, + "line": 53, "column": 90, - "endLine": 52, + "endLine": 53, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 65, + "line": 66, "column": 2, - "endLine": 65, + "endLine": 66, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 67, + "line": 68, "column": 4, - "endLine": 67, + "endLine": 68, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 71, + "line": 72, "column": 4, - "endLine": 71, + "endLine": 72, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 4, - "endLine": 72, + "endLine": 73, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 73, + "line": 74, "column": 11, - "endLine": 73, + "endLine": 74, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 33, - "endLine": 78, + "endLine": 79, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 63, - "endLine": 78, + "endLine": 79, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Measurable\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 79, "column": 88, - "endLine": 78, + "endLine": 79, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 81, + "line": 82, "column": 19, - "endLine": 81, + "endLine": 82, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"MeasureResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 2, + "endLine": 96, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 4, + "endLine": 98, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 4, + "endLine": 102, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 4, + "endLine": 103, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 11, + "endLine": 104, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"SizeResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 33, + "endLine": 109, + "endColumn": 45, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 63, + "endLine": 109, + "endColumn": 73, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Measurable\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 88, + "endLine": 109, + "endColumn": 109, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 19, + "endLine": 112, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"MeasureResult\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 35, + "endLine": 120, + "endColumn": 47, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"GeometryInfo\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 65, + "endLine": 120, + "endColumn": 75, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Layoutable\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 90, + "endLine": 120, + "endColumn": 111, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ConstraintSizeOptions\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 95, + "line": 133, "column": 2, - "endLine": 95, + "endLine": 133, "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';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n Column,\n Builder,\n ForEach,\n Text,\n BuilderParam,\n State,\n SizeResult,\n GeometryInfo,\n Layoutable,\n ConstraintSizeOptions,\n Measurable,\n MeasureResult,\n} from '@kit.ArkUI';", + "line": 133, + "column": 2, + "endLine": 133, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/custom_layout.ets.json b/ets2panda/linter/test/main/custom_layout.ets.json index 5d769b466be894ca7e944a9048b170f15ac0ae1c..cc51fe6a1b8579dfc9a96d92c8fb908c4660e35a 100644 --- a/ets2panda/linter/test/main/custom_layout.ets.json +++ b/ets2panda/linter/test/main/custom_layout.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 78, + "line": 79, "column": 3, - "endLine": 78, + "endLine": 79, "endColumn": 16, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -25,13 +25,13 @@ "severity": "ERROR" }, { - "line": 97, + "line": 109, "column": 3, - "endLine": 97, - "endColumn": 8, - "problem": "AnyType", + "endLine": 109, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/custom_layout.ets.migrate.ets b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets index 2d98301abfceb216cb6a73f5cd01afa820994638..e802e81fdb7fdc3c33a5da707eb64ec87cb5c7d5 100644 --- a/ets2panda/linter/test/main/custom_layout.ets.migrate.ets +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets @@ -13,7 +13,24 @@ * limitations under the License. */ -import { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI'; +import { CustomLayout } from '@kit.ArkUI'; + +import { + Entry, + Component, + Column, + Builder, + ForEach, + Text, + BuilderParam, + State, + SizeResult, + GeometryInfo, + Layoutable, + ConstraintSizeOptions, + Measurable, + MeasureResult, +} from '@kit.ArkUI'; @Entry @Component @@ -22,6 +39,7 @@ struct Index { Column() { CustomLayout1({ builder: ColumnChildren }) CustomLayout2({ builder: ColumnChildren }) + CustomLayout3({ builder: ColumnChildren }) } } } @@ -39,7 +57,7 @@ function ColumnChildren() { } @Component -@Layoutable +@CustomLayout struct CustomLayout1 { @Builder doNothingBuilder() { @@ -53,9 +71,9 @@ struct CustomLayout1 { }; onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { - let startPos: number = 300; + let startPos = 300; children.forEach((child) => { - let pos: number = startPos - child.measureResult.height; + let pos = startPos - child.measureResult.height; child.layout({ x: pos, y: pos }) }) } @@ -66,7 +84,7 @@ struct CustomLayout1 { } @Component -@Layoutable +@CustomLayout struct CustomLayout2 { @Builder doNothingBuilder() { @@ -80,7 +98,7 @@ struct CustomLayout2 { }; onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { - let size: number = 100; + let size = 100; children.forEach((child) => { let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size }) size += result.width / 2 @@ -97,8 +115,46 @@ struct CustomLayout2 { } @Component +@CustomLayout struct CustomLayout3 { - build { + @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; + } + + 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 CustomLayout4 { + 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 index 6c283c3ef1beea2a8d290ae40cecd19853e44771..05a4428e94c563c103bb7ca95c9fd5959b891211 100644 --- a/ets2panda/linter/test/main/custom_layout.ets.migrate.json +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.json @@ -15,33 +15,33 @@ ], "result": [ { - "line": 42, + "line": 60, "column": 1, - "endLine": 42, - "endColumn": 12, + "endLine": 60, + "endColumn": 14, "problem": "DecoratorsNotSupported", "suggest": "", "rule": "Decorators are not supported(arkts-no-ts-decorators)", "severity": "ERROR" }, { - "line": 69, + "line": 87, "column": 1, - "endLine": 69, - "endColumn": 12, + "endLine": 87, + "endColumn": 14, "problem": "DecoratorsNotSupported", "suggest": "", "rule": "Decorators are not supported(arkts-no-ts-decorators)", "severity": "ERROR" }, { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 8, - "problem": "AnyType", + "line": 118, + "column": 1, + "endLine": 118, + "endColumn": 14, + "problem": "DecoratorsNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.args.json b/ets2panda/linter/test/main/debugger_statememt.ets.args.json index f56752f2284e65fb08a317502e548ab26eee7c70..4acc088d1da62353e56ced57f16b342de413cb78 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.args.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.args.json @@ -14,8 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2", - "migrate": "--arkts-2" + "arkts2": "" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.arkts2.json b/ets2panda/linter/test/main/debugger_statememt.ets.arkts2.json index a220a0103848419c575b937bb62dcb1a48c52321..09196c4c33797d9039007a0c93c4bd3571c6e3b3 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.arkts2.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 10, "problem": "DebuggerStatement", "suggest": "", - "rule": "\"debugger\" is not supported (arkts-no-debugger-stmt)", + "rule": "\"debugger\" is not supported (arkts-no-debugger)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 12, "problem": "DebuggerStatement", "suggest": "", - "rule": "\"debugger\" is not supported (arkts-no-debugger-stmt)", + "rule": "\"debugger\" is not supported (arkts-no-debugger)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/default_required_args.ets b/ets2panda/linter/test/main/default_required_args.ets index cbccdb42cf31c8bdadd160e270814f14ec671829..613b5ac307b2e9511bb410529417538300235a77 100644 --- a/ets2panda/linter/test/main/default_required_args.ets +++ b/ets2panda/linter/test/main/default_required_args.ets @@ -57,4 +57,17 @@ function log(level: string = 'info', some: string, message?: string): void { function config(debug: boolean = true, verbose?: boolean): string { //legal return `Debug: ${debug ?? false}, Verbose: ${verbose ?? false}`; +} + +export class DefaultArgsA { + readonly left: number; + readonly right: number; + constructor(left: number = 0.0, right: number) { // 漏扫 + this.left = left; + this.right = right; + } + + defaultArgsFoo1(left: number = 0.0, right: number): number { + return left + right; + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/default_required_args.ets.arkts2.json b/ets2panda/linter/test/main/default_required_args.ets.arkts2.json index 73fb6559a8b55f9b09b1c9c0853f42b9e521c38c..60545ba228f9bac0a85e342734d1dd382d328c28 100644 --- a/ets2panda/linter/test/main/default_required_args.ets.arkts2.json +++ b/ets2panda/linter/test/main/default_required_args.ets.arkts2.json @@ -83,6 +83,26 @@ "suggest": "", "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" + }, + { + "line": 65, + "column": 15, + "endLine": 65, + "endColumn": 19, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 19, + "endLine": 70, + "endColumn": 23, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/derived_class_field_type_matching.ets b/ets2panda/linter/test/main/derived_class_field_type_matching.ets new file mode 100644 index 0000000000000000000000000000000000000000..02bfd0a392cfaea06d5829bdd5af8d55d7fd5091 --- /dev/null +++ b/ets2panda/linter/test/main/derived_class_field_type_matching.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. + */ + +class A { + obj1: number | string = 0.0; + obj2: string = 'hello'; + obj3: number | string | boolean = false; +} + +class B extends A { + obj1: string | number = 0.0; // OK + obj2: string = 'hello'; // OK + obj3: number | string | boolean = false; // OK +} + +class C extends A { + obj1: string = 'hello'; // MISMATCH/ERROR + obj2: number = 0.0; // MISMATCH/ERROR + obj3: number | boolean = false; // MISMATCH/ERROR +} + +class D extends A { + obj1: string | number | boolean = 'hello'; // MISMATCH/ERROR + obj2: number | string = 0.0; // MISMATCH/ERROR +} + +class E { obj: number | string = 1.0; } +class F extends E { obj: number = 1.0; } // will be flagged on F vs E => MISMATCH/ERROR +class G extends F { obj: number = 1.0; } // will be checked on G vs F => OK + +class A1 {} +class A2 extends A1 { + obj: number | string = 0.0; +} +class A3 extends A2 {} +class A4 extends A3 { + obj: number = 0.0; // ERROR/MISMATCH => field type is not matching with obj from base class A2 +} + +class B1 { + obj: number | string = 0.0; +} + +class B2 extends B1 { // no error + obj: number | string = 0.0; + obj2: number | string = 0.0; + obj3: boolean = false; + obj4: string = 'hello'; +} + +interface I1 { + obj: number | string +} + +interface I2 { + obj2: number | string; +} + +interface I3 extends I2 {} + +class CI1 implements I1, I2 { + obj: number = 0.0; // error + obj2: number = 0.0; // error +} + +class CI2 implements I3 { + obj2: number = 0.0; // error +} diff --git a/ets2panda/linter/test/main/derived_class_field_type_matching.ets.args.json b/ets2panda/linter/test/main/derived_class_field_type_matching.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/derived_class_field_type_matching.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/derived_class_field_type_matching.ets.arkts2.json b/ets2panda/linter/test/main/derived_class_field_type_matching.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..06df6cd967e39790e97f60cebc51f6c4963c3f88 --- /dev/null +++ b/ets2panda/linter/test/main/derived_class_field_type_matching.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": 29, + "column": 3, + "endLine": 29, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 3, + "endLine": 30, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 21, + "endLine": 40, + "endColumn": 24, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 3, + "endLine": 49, + "endColumn": 6, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 6, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 3, + "endLine": 75, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 3, + "endLine": 79, + "endColumn": 7, + "problem": "FieldTypeMismatch", + "suggest": "", + "rule": "The field types of the subclass and parent class must be the same (arkts-class-same-type-prop-with-super)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/derived_class_field_type_matching.ets.json b/ets2panda/linter/test/main/derived_class_field_type_matching.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/derived_class_field_type_matching.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/destructuring_object_property_name.ets b/ets2panda/linter/test/main/destructuring_object_property_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6c9d7b8b0edba7932d072813c593b24ab841652 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let obj = { + a: 1, + '2': 2, + 3: 3, + ['d']: 4 +}; + +let { a, a: a2 } = obj; // OK +let { '2': b } = obj; // Not fixable, support only identifiers as property names +let { 3: c } = obj; // Not fixable, support only identifiers as property names +let { ['d']: d } = obj; // Not fixable, support only identifiers as property names + +({ a, a: a2 } = obj); // OK +({ '2': b } = obj); // Not fixable, support only identifiers as property names +({ 3: c } = obj); // Not fixable, support only identifiers as property names +({ ['d']: d } = obj); // Not fixable, support only identifiers as property names \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.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/main/destructuring_object_property_name.ets.autofix.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..218cb8f87b8c558420264b33bb31d9565fdb73fc --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.autofix.json @@ -0,0 +1,170 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 11, + "endLine": 16, + "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": 18, + "column": 3, + "endLine": 18, + "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": 19, + "column": 3, + "endLine": 19, + "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": 5, + "endLine": 23, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "let a2 = obj.a;\n", + "start": 658, + "end": 681, + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20, + "problem": "DestructuringAssignment", + "autofix": [ + { + "replacementText": "a2 = obj.a;\n", + "start": 932, + "end": 953, + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 4, + "endLine": 29, + "endColumn": 7, + "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": 2, + "endLine": 30, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dfaf7f22a125429aa1e7ec5c0ae20d49ea81e7f8 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.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": 11, + "endLine": 16, + "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": 18, + "column": 3, + "endLine": 18, + "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": 19, + "column": 3, + "endLine": 19, + "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": 5, + "endLine": 23, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 4, + "endLine": 29, + "endColumn": 7, + "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": 2, + "endLine": 30, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c72f5222fe55b3afa0baef599253a9f478c88d4 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.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. + */ + +let obj = { + a: 1, + '2': 2, + 3: 3, + ['d']: 4 +}; + +let a2 = obj.a; + // OK +let { '2': b } = obj; // Not fixable, support only identifiers as property names +let { 3: c } = obj; // Not fixable, support only identifiers as property names +let { ['d']: d } = obj; // Not fixable, support only identifiers as property names + +a2 = obj.a; + // OK +({ '2': b } = obj); // Not fixable, support only identifiers as property names +({ 3: c } = obj); // Not fixable, support only identifiers as property names +({ ['d']: d } = obj); // Not fixable, support only identifiers as property names \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d104b0838dd51443f539762d0863a3e8f97b0bd2 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_object_property_name.ets.migrate.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": 11, + "endLine": 16, + "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": 18, + "column": 3, + "endLine": 18, + "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": 19, + "column": 3, + "endLine": 19, + "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": 25, + "column": 5, + "endLine": 25, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 19, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 18, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 4, + "endLine": 31, + "endColumn": 7, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 16, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 4, + "endLine": 32, + "endColumn": 5, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 20, + "problem": "DestructuringAssignment", + "suggest": "", + "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..95dd7d9c2873cde34ff08d8ac8a99a463e822fcb --- /dev/null +++ b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 1: Simple override, no explicit type, non-async → OK +// Base has abstract foo() (no annotation), override without annotation defaults to void +abstract class A1 { + abstract foo(); +} +class B1 extends A1 { + foo() { // ✅ no error + // … + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 2: Explicit void override → OK +abstract class A2 { + abstract foo(); +} +class B2 extends A2 { + foo(): void { // ✅ no error + // … + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 3: Non-void override → ERROR +abstract class A3 { + abstract foo(); +} +class B3 extends A3 { + foo(): number { // ❌ should flag AbstractOverrideReturnTypeNotVoid + return 42; + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 4: Async override without annotation → ERROR +// async methods default to Promise, and base foo() had no type +abstract class A4 { + abstract foo(); +} +class B4 extends A4 { + async foo() { // ❌ should flag AbstractOverrideReturnTypeNotVoid + await Promise.resolve(); + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 5: Indirect inheritance through an intermediate class +abstract class A5 { + abstract foo(); +} +class B5 extends A5 { /* no override here */ } +class C5 extends B5 { + foo(): number { // ❌ should flag — walks up to A5 + return 1; + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 6: Base declares a return type +abstract class A6 { + abstract bar(): string; // explicit annotation +} +class B6 extends A6 { + bar() { // ✅ no error (base had annotation) + return "ok"; + } +} +class C6 extends A6 { + bar(): number { // ✅ no InvalidAbstractOverrideReturnType error (this rule only applies when base had no type and derived method's type is different from void) + return 123; + } +} + +// ─────────────────────────────────────────────────────────────────────────── +// CASE 7: Class with its own non-override method — no error +class OwnClass { + fooOwn() { // ✅ no error + return 'own'; + } +} diff --git a/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets.args.json b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/distinct_abstract_method_default_return_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/distinct_abstract_method_default_return_type.ets.arkts2.json b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..82d3a8851c2eef3a7883e03f507415a517348a4d --- /dev/null +++ b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.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": 23, + "column": 3, + "endLine": 23, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 10, + "endLine": 34, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 6, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 9, + "endLine": 57, + "endColumn": 12, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 9, + "endLine": 57, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 6, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 10, + "endLine": 85, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets.json b/ets2panda/linter/test/main/distinct_abstract_method_default_return_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/distinct_abstract_method_default_return_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/dollar_binding_1.ets.arkts2.json b/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json index 367b3ca3444ac8860fdc83befd563b101de460d2..402183985690ebaa06fae5bc6dda393cb52e931d 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/dollar_binding_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": [ { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Link\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 89ffaf32c0daa1d59d220779c924aa8613098740..491ed961eb9d0089f8b4257c7b356b72e87bec13 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json +++ b/ets2panda/linter/test/main/dollar_binding_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": [ { @@ -24,7 +24,11 @@ { "start": 749, "end": 755, - "replacementText": "this.count" + "replacementText": "this.count", + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 22 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 798, "end": 801, - "replacementText": "this.$$" + "replacementText": "this.$$", + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19 } ], "suggest": "", @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Link\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Link,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets index 244e4156a9e756c896fa0c9356ae003bee616597..d36a32825ba06d2df2e65b27b44f890ab02cd60d 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets @@ -13,7 +13,14 @@ * limitations under the License. */ -import { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; +import { + Component, + State, + Column, + Link, + Row, + Text, +} from '@kit.ArkUI'; @Component struct MyComponent { 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 0a8b4da88d1e6eadbe59c8c204cf4a067a7a61a3..03da9ec935aec271cedc26999ab6fb0ac5f2031c 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 @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Checkbox\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 12, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 bc08ccf2ef8b21dfedd44c0d0b1e6c610da2024b..bfa77f03ccfd83e68b397830e91d225b634b5fd5 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 @@ -24,7 +24,11 @@ { "start": 719, "end": 731, - "replacementText": "$$(this.value)" + "replacementText": "$$(this.value)", + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 28 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 862, "end": 876, - "replacementText": "$$(this.checked)" + "replacementText": "$$(this.checked)", + "line": 35, + "column": 25, + "endLine": 35, + "endColumn": 39 } ], "suggest": "", @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Checkbox\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -194,11 +234,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,11 +255,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n} from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index e598afe1a5c9ef6cc608c902b7bade026786bfd8..a4209b21e4f63a7cc8ee2fec72a7b13948ef7cef 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets @@ -13,7 +13,16 @@ * limitations under the License. */ -import { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; +import { + Component, + State, + Row, + Slider, + $$, + Checkbox, + Blank, + Text, +} from '@kit.ArkUI'; @Component struct MyComponent { 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 3211c8ca2f7758eadaebcf143ed334f2ca28ee82..924a5e241b1d54e01e3f9626beca9e7db444e628 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,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": [ { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Checkbox\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 12, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -231,7 +231,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -241,7 +241,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -261,7 +261,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -271,7 +271,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -281,7 +281,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -291,7 +291,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -301,7 +301,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -311,7 +311,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -321,7 +321,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -331,7 +331,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -341,7 +341,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -351,7 +351,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -361,7 +361,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Param\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -371,7 +371,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Event\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -381,7 +381,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -391,7 +391,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -401,7 +401,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 4b94dfd390ce05bd57843f3b962e0e7f1fb5e373..a02db2fec8ca333fb93b241230b1ec66c72496fc 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 @@ -24,7 +24,11 @@ { "start": 749, "end": 761, - "replacementText": "$$(this.value)" + "replacementText": "$$(this.value)", + "line": 25, + "column": 16, + "endLine": 25, + "endColumn": 28 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 892, "end": 906, - "replacementText": "$$(this.checked)" + "replacementText": "$$(this.checked)", + "line": 37, + "column": 25, + "endLine": 37, + "endColumn": 39 } ], "suggest": "", @@ -58,7 +66,11 @@ { "start": 1662, "end": 1685, - "replacementText": "{\n value: this.value,\n $value: value => {\n this.value = value;\n }\n }" + "replacementText": "{\n value: this.value,\n $value: (value: number) => {\n this.value = value;\n }\n }", + "line": 92, + "column": 21, + "endLine": 92, + "endColumn": 33 } ], "suggest": "", @@ -75,7 +87,11 @@ { "start": 1700, "end": 1719, - "replacementText": "{\n str: this.str,\n $str: value => {\n this.str = value;\n }\n }" + "replacementText": "{\n str: this.str,\n $str: (value: string) => {\n this.str = value;\n }\n }", + "line": 93, + "column": 21, + "endLine": 93, + "endColumn": 31 } ], "suggest": "", @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -194,11 +234,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,11 +255,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Checkbox\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -228,11 +276,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -245,11 +297,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -262,11 +318,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -279,11 +339,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -296,11 +360,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -313,11 +381,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -330,11 +402,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -347,11 +423,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -364,11 +444,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -381,11 +465,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -398,11 +486,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -415,11 +507,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -432,11 +528,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -449,11 +549,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Slider\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -466,11 +570,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -483,11 +591,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -500,11 +612,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -517,11 +633,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -534,11 +654,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -551,11 +675,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -568,11 +696,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -585,11 +717,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -602,11 +738,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Param\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -619,11 +759,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Event\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -636,11 +780,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -653,11 +801,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -670,11 +822,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n Row,\n Slider,\n $$,\n Checkbox,\n Blank,\n Text,\n Entry,\n ComponentV2,\n Local,\n Column,\n Button,\n Param,\n Event,\n} from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 30d62a94677fd337d9f627513c429737d4afca7a..56578785ad6236ffb507f6e8b27e6394539fe322 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets @@ -13,7 +13,23 @@ * limitations under the License. */ -import { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; +import { + Component, + State, + Row, + Slider, + $$, + Checkbox, + Blank, + Text, + Entry, + ComponentV2, + Local, + Column, + Button, + Param, + Event, +} from '@kit.ArkUI'; import { MyCard } from './' @@ -93,13 +109,13 @@ struct Index { }) Star({ value: this.value, - $value: value => { + $value: (value: number) => { this.value = value; } }) MyCard({ str: this.str, - $str: value => { + $str: (value: string) => { this.str = value; } }) 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 index c697fe6484ca72352bfc6b04ba5b73eade8a1961..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json @@ -13,16 +13,5 @@ "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" - } - ] + "result": [] } \ 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 56397bece3039a1107847f2f79538a15b8a80ae1..9ce7a7e1390eb1866c6616e64e3c99b788cda1e4 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,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": [ { 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 56397bece3039a1107847f2f79538a15b8a80ae1..9ce7a7e1390eb1866c6616e64e3c99b788cda1e4 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,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": [ { diff --git a/ets2panda/linter/test/main/double_excla_binding_3.ets b/ets2panda/linter/test/main/double_excla_binding_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c9dcc1e87d92cb935d8ab70085acccafdaa580a --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_3.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 User { + name: string = "Jack" +} + +@Entry +@Component +struct MyComponent { + @State user: User = new User() + + build() { + Row() { + Text(this.user!.name) + Text(this.user!!.name) + Text(this.user!!!.name) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_3.ets.args.json b/ets2panda/linter/test/main/double_excla_binding_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..30973c00a22aa0a072616f644b02c89a4a4dd4fa --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_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/double_excla_binding_3.ets.arkts2.json b/ets2panda/linter/test/main/double_excla_binding_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d73e979005ffaa2458d365d61fb1667377f3bd30 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_3.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": 20, + "column": 2, + "endLine": 20, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 4, + "endLine": 23, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_3.ets.autofix.json b/ets2panda/linter/test/main/double_excla_binding_3.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..7b9fc728ca408a5b5fc47a929bcf72a4be75b712 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_3.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": 20, + "column": 2, + "endLine": 20, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 4, + "endLine": 23, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n} from '@kit.ArkUI';", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_3.ets.json b/ets2panda/linter/test/main/double_excla_binding_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..b7a8809e02ae14f7f14ed7adbd6d2d3f630fa3f6 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_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/double_excla_binding_3.ets.migrate.ets b/ets2panda/linter/test/main/double_excla_binding_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..78c64875400f6b5c5e059274fa99a7e4cf3f2f34 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_3.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. + */ + +import { + Entry, + Component, + State, + Row, + Text, +} from '@kit.ArkUI'; + +class User { + name: string = "Jack" +} + +@Entry +@Component +struct MyComponent { + @State user: User = new User() + + build() { + Row() { + Text(this.user!.name) + Text(this.user!!.name) + Text(this.user!!!.name) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_3.ets.migrate.json b/ets2panda/linter/test/main/double_excla_binding_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b7a8809e02ae14f7f14ed7adbd6d2d3f630fa3f6 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_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/main/dynamic_import.ets.arkts2.json b/ets2panda/linter/test/main/dynamic_import.ets.arkts2.json index 30c87c82a58444ee99ddbb2374a45de7413dcd21..ae596bc17ecaec6eac5b21c688c4ec0a3ec135f1 100644 --- a/ets2panda/linter/test/main/dynamic_import.ets.arkts2.json +++ b/ets2panda/linter/test/main/dynamic_import.ets.arkts2.json @@ -161,7 +161,7 @@ "endColumn": 76, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"EllipseShape\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 32c8ce210adab22734196f8d6663f2da3f0ac8ca..5c74801c0303121b832434a3dcb4353604499376 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.arkts2.json @@ -1,28 +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": 1, - "endLine": 19, - "endColumn": 38, - "problem": "EntryAnnotation", - "suggest": "", - "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", - "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": 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" + } + ] } \ 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 index dbe2ad5dbe41f3fb63439880b4a063d7b0f1cab9..e0e39f3b86a00d67a848af08a7290a70fd914e55 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 738, "end": 775, - "replacementText": "const __get_local_storage__ = (): LocalStorage => getLocalStorage(1);\n@Entry({ storage: \"__get_local_storage__\" })" + "replacementText": "const __get_local_storage__ = (): LocalStorage => getLocalStorage(1);\n@Entry({ storage: \"__get_local_storage__\" })", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 38 } ], "suggest": "", 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 index 59b5cc120afe11a525557bea39d028065017d9dd..f5675b07667bad2abca859958b849a8d6e63d407 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.ets @@ -1,26 +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'; - +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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") - } +@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.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.arkts2.json index 8227167def1b271819ea01c30d8adbb1022b3b20..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.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." - ], - "result": [] +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES 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.autofix.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.autofix.json index 8227167def1b271819ea01c30d8adbb1022b3b20..ca88f857e960b437dcf767c0ac40be998c8f1236 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.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." - ], - "result": [] +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES 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 index b6345be4c3bb6a7373886d766bc07acff6c34f79..59984ecfef0c835cfe7b08bf4d66fafa54667db5 100644 --- a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.ets @@ -1,26 +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") - } +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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_test8_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json index c1e82092cbc8411d1014db7524fa9e02b3151d6c..a8450fce0eb32b69920c131fcd15e94c3e8f0550 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json @@ -20,13 +20,6 @@ "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" @@ -41,7 +34,11 @@ { "start": 725, "end": 750, - "replacementText": "const __get_local_storage__ = (): LocalStorage => source;\n@Entry({ storage: \"__get_local_storage__\" })" + "replacementText": "const __get_local_storage__ = (): LocalStorage => source;\n@Entry({ storage: \"__get_local_storage__\" })", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 26 } ], "suggest": "", 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 index 1159381e1c3c5eae9a51f58e38fae68cb7e2e27a..bf1b217b00c86ec03ce3342cb6a8031456bc3cca 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets @@ -15,8 +15,8 @@ import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -const source = specialAutofixLib.globalThis.get("localStorage"); -const __get_local_storage__ = (): LocalStorage => source; +const source = globalThis.localStorage; +const __get_local_storage__ = (): LocalStorage => source; @Entry({ storage: "__get_local_storage__" }) @Component struct MyPage { 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 index 045feeac1b91ac7e0aaa3fc613760478fdcaa478..8723136274aefa0e120634e1bbe69ddf54a00629 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json @@ -16,12 +16,12 @@ "result": [ { "line": 18, - "column": 7, + "column": 16, "endLine": 18, - "endColumn": 64, - "problem": "AnyType", + "endColumn": 39, + "problem": "GlobalThisError", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" } ] 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 index f73277ba2c6e5588e6920e22bfe177ab72d3790a..8723136274aefa0e120634e1bbe69ddf54a00629 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json @@ -20,13 +20,6 @@ "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" 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 index 0c20666abffa48687f2ec8cd3bd6587609d30ff2..1120a5a86040563916efc4fdd7eeba88f852e5ea 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets @@ -15,7 +15,7 @@ import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -const source = specialAutofixLib.globalThis.get("localStorage"); +const source = globalThis.localStorage; const __get_local_storage__ = (): LocalStorage => source; @Entry({storage: "__get_local_storage__"}) @Component 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 index 045feeac1b91ac7e0aaa3fc613760478fdcaa478..8723136274aefa0e120634e1bbe69ddf54a00629 100644 --- a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json @@ -16,12 +16,12 @@ "result": [ { "line": 18, - "column": 7, + "column": 16, "endLine": 18, - "endColumn": 64, - "problem": "AnyType", + "endColumn": 39, + "problem": "GlobalThisError", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" } ] 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 index f8e2a1ef6c88975cdd9dfddc0d5cd8451a81ca3b..19bc667ae8ec353640870e909f0936e7c7be9b97 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 685, "end": 727, - "replacementText": "const __get_local_storage__ = (): LocalStorage => globalThis.localStorage;\n@Entry({ storage: \"__get_local_storage__\" })" + "replacementText": "const __get_local_storage__ = (): LocalStorage => globalThis.localStorage;\n@Entry({ storage: \"__get_local_storage__\" })", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 43 } ], "suggest": "", @@ -37,13 +41,6 @@ "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" 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 index 8c9d2b20122520a1036755a7aab58b9807fc626f..94bcbfdd9b87ddd2bda4692ec11e7d24f8e07082 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets @@ -15,7 +15,7 @@ import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => globalThis.localStorage; @Entry({ storage: "__get_local_storage__" }) @Component struct MyPage { 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 index ca88f857e960b437dcf767c0ac40be998c8f1236..a390c87a2e15b3463edfc5f7a22e9dcaba33afc6 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json @@ -13,5 +13,16 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "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 index 17f6fcde033bbf37a56d9c1ce4d514a029e8e332..a390c87a2e15b3463edfc5f7a22e9dcaba33afc6 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json @@ -20,13 +20,6 @@ "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" 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 index 9f1162ccfd9b4bd32b22eda12ce9773232e37e9b..f6f5bf039ff2d569fd321183011cb8933ab65f24 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets @@ -15,7 +15,7 @@ import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; -const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => globalThis.localStorage; @Entry({storage: "__get_local_storage__"}) @Component struct MyPage { 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 index ca88f857e960b437dcf767c0ac40be998c8f1236..a390c87a2e15b3463edfc5f7a22e9dcaba33afc6 100644 --- a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json @@ -13,5 +13,16 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "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/enum_not_support_float.ets b/ets2panda/linter/test/main/enum_not_support_float.ets index 593f6c64b9c8ef4857277b4a90bac71b67df20c6..69c8157c759f0fe94e7208849f7e52e25a027558 100644 --- a/ets2panda/linter/test/main/enum_not_support_float.ets +++ b/ets2panda/linter/test/main/enum_not_support_float.ets @@ -53,3 +53,9 @@ enum ExprInits { H = '123'.length, I = 1 && 2, } + +enum Numbers14{ + RED = 1 as number, + BLUE = 2, + GREEN = -1 +} \ 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..b4b5074c74ee42251fbe35d45f33cd3694c9def2 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,26 +34,6 @@ "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", "severity": "ERROR" }, - { - "line": 44, - "column": 7, - "endLine": 44, - "endColumn": 20, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "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 +53,16 @@ "suggest": "", "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 20, + "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/main/equals_token_option.ets.arkts2.json b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json index 7100f9b7970a9327a5f72c3c3ad611843d961c0a..b8a904b57eb6163a516c3de727e3f6a1ed1ba16a 100755 --- a/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json +++ b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 15, - "column": 5, - "endLine": 15, - "endColumn": 9, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 16, "column": 3, @@ -124,16 +114,6 @@ "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, - { - "line": 34, - "column": 1, - "endLine": 36, - "endColumn": 2, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 35, "column": 17, 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..7463fcb51f18c08a7bff2481cc3428ce7794e867 100644 --- a/ets2panda/linter/test/main/es_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/es_object.ets.arkts2.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", @@ -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": "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" }, { @@ -378,70 +378,70 @@ "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 +449,9 @@ "column": 5, "endLine": 77, "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" }, { @@ -459,9 +459,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 +469,9 @@ "column": 5, "endLine": 79, "endColumn": 11, - "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" }, { @@ -479,9 +479,9 @@ "column": 5, "endLine": 80, "endColumn": 11, - "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" }, { @@ -489,9 +489,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 +499,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 +509,9 @@ "column": 5, "endLine": 85, "endColumn": 16, - "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" }, { @@ -519,9 +519,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 +529,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 +539,69 @@ "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 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "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 +609,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 +619,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 +638,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 +648,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 +698,60 @@ "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 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "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 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "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 +759,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" }, { @@ -868,30 +868,30 @@ "line": 177, "column": 5, "endLine": 177, - "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": 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 +908,40 @@ "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": 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 +949,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 +959,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,9 +969,9 @@ "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" } ] 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 9b440521971be16a2666905393f3b541f642d724..065dda4586383d26dc653d73ee1afa3e0b5c03ff 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets +++ b/ets2panda/linter/test/main/explicit_function_type.ets @@ -75,8 +75,8 @@ class I24 { constructor(par: Function, par1?: string) {} } class I24_1 extends I24 { - constructor() { - super(Function) + constructor(par: Function) { + super(par) } } @@ -172,4 +172,13 @@ let ab3 = new AB3(); ab3.fn3(); const fn29: Function[] = []; -fn29[1](); \ No newline at end of file +fn29[1](); + +SysApiWrapper.setTimeout = (handler: Function | string, delay?: number): number => { + (handler as Function)?.(); + return Math.random(); +} + +new Function('return 42')(); + +Function('return 42')(); diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json old mode 100755 new mode 100644 index 1d761807b3983d3a4286f9524be975a4e864cf30..83cdd8667b16efb8ce1df5806e184dd549673555 --- a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json @@ -1,19 +1,19 @@ { - "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": [ + "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, @@ -54,16 +54,6 @@ "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, @@ -233,6 +223,46 @@ "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": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 24, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 1, + "endLine": 182, + "endColumn": 26, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 1, + "endLine": 184, + "endColumn": 22, + "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 index 5f69b7bd511d6f196df6e1cd707d3619254be6bf..1a445e96ba30abb5eb0cf2606c6a8c9be0294dee 100644 --- a/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json +++ b/ets2panda/linter/test/main/explicit_function_type.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) 2024-2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES 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,7 +24,11 @@ { "start": 668, "end": 681, - "replacementText": "() => { }" + "replacementText": "() => { }", + "line": 16, + "column": 20, + "endLine": 16, + "endColumn": 33 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 760, "end": 773, - "replacementText": "() => { }" + "replacementText": "() => { }", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23 } ], "suggest": "", @@ -56,9 +64,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "fn.unSafeCall", "start": 1572, - "end": 1574 + "end": 1574, + "replacementText": "fn.unsafeCall", + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5 } ], "suggest": "", @@ -75,16 +87,6 @@ "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, @@ -173,9 +175,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "callback.unSafeCall", - "start": 2921, - "end": 2929 + "start": 2929, + "end": 2937, + "replacementText": "callback.unsafeCall", + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11 } ], "suggest": "", @@ -220,9 +226,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "curr.unSafeCall", - "start": 3458, - "end": 3462 + "start": 3466, + "end": 3470, + "replacementText": "curr.unsafeCall", + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66 } ], "suggest": "", @@ -237,9 +247,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "prev.unSafeCall", - "start": 3463, - "end": 3467 + "start": 3471, + "end": 3475, + "replacementText": "prev.unsafeCall", + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71 } ], "suggest": "", @@ -254,9 +268,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "f1.unSafeCall", - "start": 3586, - "end": 3588 + "start": 3594, + "end": 3596, + "replacementText": "f1.unsafeCall", + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3 } ], "suggest": "", @@ -271,9 +289,13 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "ab3.fn3.unSafeCall", - "start": 3656, - "end": 3663 + "start": 3664, + "end": 3671, + "replacementText": "ab3.fn3.unsafeCall", + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8 } ], "suggest": "", @@ -288,14 +310,69 @@ "problem": "ExplicitFunctionType", "autofix": [ { - "replacementText": "fn29[1].unSafeCall", - "start": 3697, - "end": 3704 + "start": 3705, + "end": 3712, + "replacementText": "fn29[1].unsafeCall", + "line": 175, + "column": 1, + "endLine": 175, + "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": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 24, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "start": 3804, + "end": 3827, + "replacementText": "(handler as Function)?.unsafeCall", + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 1, + "endLine": 182, + "endColumn": 26, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 1, + "endLine": 184, + "endColumn": 22, + "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.json b/ets2panda/linter/test/main/explicit_function_type.ets.json old mode 100755 new mode 100644 index d1381869898d689771df539f100eaacd386998a0..a3424dbdf251cdce4f4e0e516879ffb8aed62018 --- a/ets2panda/linter/test/main/explicit_function_type.ets.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.json @@ -1,19 +1,19 @@ { - "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": [ + "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, @@ -44,16 +44,6 @@ "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, @@ -75,4 +65,4 @@ "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 index e5584d49c72d97b78cee2c333bf39ef0522c2f99..872655fb50994dc332c6291ad7c2c84833fc44cb 100644 --- a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets @@ -54,7 +54,7 @@ class D5 implements C5 { } function run6(fn: Function) { - fn.unSafeCall(); + fn.unsafeCall(); } function getFunction8(): Function { @@ -75,8 +75,8 @@ class I24 { constructor(par: Function, par1?: string) {} } class I24_1 extends I24 { - constructor() { - super(Function) + constructor(par: Function) { + super(par) } } @@ -136,7 +136,7 @@ enum E39 { //回调参数不明确 function handleEvent41(callback: Function) { - callback.unSafeCall("event", Date.now()); + callback.unsafeCall("event", Date.now()); } let fn43: Function = (x: number) => x + 1; @@ -157,19 +157,28 @@ const fetchData44: Function = async (url: string) => { //高阶函数 function compose45(...fns: Function[]): Function { - return fns.reduce((prev, curr) => (...args: Function[]) => curr.unSafeCall(prev.unSafeCall(...args)) as 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(); +f1.unsafeCall(); class AB3 { fn3: Function = () => {}; } let ab3 = new AB3(); -ab3.fn3.unSafeCall(); +ab3.fn3.unsafeCall(); const fn29: Function[] = []; -fn29[1].unSafeCall(); \ No newline at end of file +fn29[1].unsafeCall(); + +SysApiWrapper.setTimeout = (handler: Function | string, delay?: number): number => { + (handler as Function)?.unsafeCall(); + return Math.random(); +} + +new Function('return 42')(); + +Function('return 42')(); diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json index 8b449e6619a40fc8803e44c3a933540290cf7c90..d0ebc18694d1c8a2da14b5e5acc331048fb7ad4b 100644 --- a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json @@ -24,16 +24,6 @@ "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, @@ -143,6 +133,36 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 1, + "endLine": 182, + "endColumn": 26, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 184, + "column": 1, + "endLine": 184, + "endColumn": 22, + "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/exponent.ets.arkts2.json b/ets2panda/linter/test/main/exponent.ets.arkts2.json index 642e7e5dcb664b564ef12d8c02fe4feab1fa075b..b596b5f3c26d4d51475c7c442c38f59fe7ff8a6b 100644 --- a/ets2panda/linter/test/main/exponent.ets.arkts2.json +++ b/ets2panda/linter/test/main/exponent.ets.arkts2.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 24, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 16, "column": 10, @@ -34,16 +24,6 @@ "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 15, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 19, "column": 11, diff --git a/ets2panda/linter/test/main/exponent.ets.autofix.json b/ets2panda/linter/test/main/exponent.ets.autofix.json index ba7b6664897b5ec58a87fa0e87df466c06e3849b..980ccb03858a168e780c856ef20d86753e0064fb 100644 --- a/ets2panda/linter/test/main/exponent.ets.autofix.json +++ b/ets2panda/linter/test/main/exponent.ets.autofix.json @@ -14,23 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 24, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 609, - "end": 628, - "replacementText": "kk: number = Math.pow(6, 3)" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 16, "column": 10, @@ -41,23 +24,6 @@ "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 15, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 652, - "end": 662, - "replacementText": "k: number = 5 ** 2" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 19, "column": 11, @@ -68,7 +34,11 @@ { "replacementText": "Math.pow(5, 2)", "start": 656, - "end": 662 + "end": 662, + "line": 19, + "column": 11, + "endLine": 19, + "endColumn": 13 } ], "suggest": "", @@ -85,7 +55,11 @@ { "replacementText": "k = Math.pow(k, 2)", "start": 681, - "end": 688 + "end": 688, + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 6 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.ets b/ets2panda/linter/test/main/exponent.ets.migrate.ets index 056294b8642bd9924cedb2b159320ca5b0db143d..eb206ab2f420a9df6e3110f4d1655df48b93efca 100644 --- a/ets2panda/linter/test/main/exponent.ets.migrate.ets +++ b/ets2panda/linter/test/main/exponent.ets.migrate.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -let kk: number = Math.pow(6, 3); +let kk = Math.pow(6, 3); console.log(kk); -let k: number = Math.pow(5, 2); +let k = Math.pow(5, 2); console.log(k); k = Math.pow(k, 2); diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.json b/ets2panda/linter/test/main/exponent.ets.migrate.json index daeb5bf97a9cb257e346839c0c2d883e71bca3c7..4ed19bbff5363febdd1929386c1b3b750f711edb 100644 --- a/ets2panda/linter/test/main/exponent.ets.migrate.json +++ b/ets2panda/linter/test/main/exponent.ets.migrate.json @@ -16,9 +16,9 @@ "result": [ { "line": 16, - "column": 18, + "column": 10, "endLine": 16, - "endColumn": 32, + "endColumn": 24, "problem": "MathPow", "suggest": "", "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", @@ -26,9 +26,9 @@ }, { "line": 19, - "column": 17, + "column": 9, "endLine": 19, - "endColumn": 31, + "endColumn": 23, "problem": "MathPow", "suggest": "", "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", 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 cbeedf0b663a4f9dd829ebc11d97a633d65344e3..a7c37a03eb79f0ba82896018d4a8da0c49b29dbc 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": [ { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 25, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "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 4c4123dea8b04955feb58ed0c2a27bca9815538d..9891ada46fab0af5ad138ce92367d07c566bb947 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 743, "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}" + "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": "", @@ -41,7 +45,11 @@ { "start": 1020, "end": 1105, - "replacementText": "function superCard(this: ColumnAttribute, padding: number): this {\n this.cardStyle();\n this.padding(10);\n return this;\n}" + "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": "", @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Column,\n Text,\n ColumnAttribute,\n Color,\n} from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Column,\n Text,\n ColumnAttribute,\n Color,\n} from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Column,\n Text,\n ColumnAttribute,\n Color,\n} from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Column,\n Text,\n ColumnAttribute,\n Color,\n} from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets index 829d53b38afd3152d1421b0441e8dc04fdb5ac1f..af04473478b1025b6b4f842d405777bdbc912709 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets @@ -13,7 +13,13 @@ * limitations under the License. */ -import { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; +import { + Component, + Column, + Text, + ColumnAttribute, + Color, +} from '@kit.ArkUI'; @Component struct MyCard { diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json index be60c934865f47fd861687847b25781c212573e6..3844838bf1003b726aba14c7fb5562d7af259788 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 31, + "line": 37, "column": 5, - "endLine": 31, + "endLine": 37, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 38, "column": 5, - "endLine": 32, + "endLine": 38, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 39, "column": 5, - "endLine": 33, + "endLine": 39, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 34, + "line": 40, "column": 5, - "endLine": 34, + "endLine": 40, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 41, "column": 5, - "endLine": 35, + "endLine": 41, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 42, "column": 5, - "endLine": 36, + "endLine": 42, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 43, "column": 5, - "endLine": 37, + "endLine": 43, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 38, + "line": 44, "column": 5, - "endLine": 38, + "endLine": 44, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -95,9 +95,9 @@ "severity": "ERROR" }, { - "line": 42, + "line": 48, "column": 12, - "endLine": 42, + "endLine": 48, "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", @@ -105,9 +105,9 @@ "severity": "ERROR" }, { - "line": 30, + "line": 36, "column": 20, - "endLine": 30, + "endLine": 36, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -115,9 +115,9 @@ "severity": "ERROR" }, { - "line": 30, + "line": 36, "column": 44, - "endLine": 30, + "endLine": 36, "endColumn": 48, "problem": "ThisType", "suggest": "", @@ -125,9 +125,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 52, "column": 5, - "endLine": 46, + "endLine": 52, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -135,9 +135,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 53, "column": 5, - "endLine": 47, + "endLine": 53, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -145,9 +145,9 @@ "severity": "ERROR" }, { - "line": 48, + "line": 54, "column": 12, - "endLine": 48, + "endLine": 54, "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", @@ -155,9 +155,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 51, "column": 20, - "endLine": 45, + "endLine": 51, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -165,9 +165,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 51, "column": 61, - "endLine": 45, + "endLine": 51, "endColumn": 65, "problem": "ThisType", "suggest": "", 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 47db15dc399d9b48b6ca03b082efc93990ece3bd..0f332deca642333fc8f530a70ee3252badc85eef 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/extend_decorator_2.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": [ { 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 47db15dc399d9b48b6ca03b082efc93990ece3bd..0f332deca642333fc8f530a70ee3252badc85eef 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.autofix.json +++ b/ets2panda/linter/test/main/extend_decorator_2.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": [ { diff --git a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json index d157d2e206fad21ce70c0b407679dfd378a9ff63..a4386d789f6e83c20e58082b12223291f7f42bf2 100755 --- a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json +++ b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json @@ -13,116 +13,136 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 21, - "column": 9, - "endLine": 21, - "endColumn": 10, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 17, - "endLine": 23, - "endColumn": 18, - "problem": "ExtendsExpression", - "suggest": "", - "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", - "severity": "ERROR" - }, - { - "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": 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" - } - ] + "result": [ + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 10, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 17, + "endLine": 23, + "endColumn": 18, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "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": 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": 62, + "column": 3, + "endLine": 66, + "endColumn": 4, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 71, + "endColumn": 4, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "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" + } + ] } 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 3d6311cc42123c86e67d74652f142cca73a4093a..1db059acbaa957f8e4f683d9b8768ec2460dba43 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 @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 31, - "column": 5, - "endLine": 31, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 36, "column": 5, @@ -44,16 +34,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 38, - "column": 1, - "endLine": 40, - "endColumn": 2, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 38, "column": 21, @@ -94,16 +74,6 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, - { - "line": 53, - "column": 1, - "endLine": 53, - "endColumn": 31, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 56, "column": 8, @@ -254,6 +224,16 @@ "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 11, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, { "line": 79, "column": 11, @@ -264,6 +244,56 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 3, + "endLine": 82, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 3, + "endLine": 83, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 3, + "endLine": 84, + "endColumn": 10, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 8, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 89, "column": 5, @@ -274,6 +304,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 89, + "column": 16, + "endLine": 89, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, { "line": 89, "column": 12, @@ -374,6 +414,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 93, + "column": 20, + "endLine": 93, + "endColumn": 27, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, { "line": 93, "column": 16, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets index 636e016aeadd253445251567c7f09fa7da3bd996..173fc2a7abbf7e6d13c3bfc3b1f825505d807bde 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { AttributeUpdater } from '@kit.ArkUI'; const irreparableArr = new Array(); let repairableArr: Array = new Array(); @@ -37,7 +38,7 @@ repairableC.repairableSet = new Set(); repairableC.repairableMap = new Map(); MyClass.repairableStaticMap = new Map(); -const promise: Promise = new Promise(()=> {return ''}); +const promise: Promise = new Promise(() => { return ''; }); function testA(): Map { return new Map(); @@ -72,3 +73,68 @@ class MyClassB { return new Set(); } } + +const testMap: Map = new Map([ + ['123', 1], // my comment 1 + ['sfe', 2] // my comment 2 +]); +let a : Array = new Array(); +function foo(arr:Array) { } +foo(new Array()); +@Observed +export class AppIconCloneBadgeVm { + @Track public cloneBadgeModifier: AttributeUpdater = new AttributeUpdater(); +} +class B {} +class C {} +class A { + t:T; + constructor(t:T) { + this.t = t; + } +} +new A(new C()) +let a: Array | undefined = new Array(); +let aa: Array | Set | undefined = new Array(); +let b: Array | Array | undefined = new Array(); +let test: string[] = new Array(); + +class A { + test(key: string): Promise { + if (key == undefined || key.length == 0.0) { + return new Promise((resolve, reject) => { + reject("empty key");}); + } else { + } + } +} +class SubArr extends Array {} +let subArr = new SubArr(); +class SubSet extends Set{} +let subSet = new SubSet(); +class SubMap extends Map{} +let subMap = new SubMap(); +class SubWeakMap extends WeakMap{} +let subWeakMap = new SubWeakMap(); +class SubWeakSet extends WeakSet{} +let subWeakSet = new SubWeakSet(); + +class C {} +class D {} +let a: D<[C]> = new D(); + +function fun(a?:Map){ + let c:Map|undefined + if(a === undefined){ + a = new Map() + } + if(a){ + a = new Map() + } + if(c){ + c = new Map() + } + if(c === undefined){ + c = new Map() + } +} \ 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 index 8332379fa7ccc19ab8c5ff0b28b5ca38417e962e..b04045a8b8f2b5e51f1c7229017ab29e7c87a75b 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json @@ -1,23 +1,23 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT 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": 16, + "line": 17, "column": 7, - "endLine": 16, + "endLine": 17, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -25,9 +25,19 @@ "severity": "ERROR" }, { - "line": 16, + "line": 17, + "column": 28, + "endLine": 17, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 17, "column": 24, - "endLine": 16, + "endLine": 17, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -35,9 +45,19 @@ "severity": "ERROR" }, { - "line": 17, + "line": 18, + "column": 40, + "endLine": 18, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 18, "column": 36, - "endLine": 17, + "endLine": 18, "endColumn": 47, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -45,9 +65,19 @@ "severity": "ERROR" }, { - "line": 18, + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 26, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, "column": 17, - "endLine": 18, + "endLine": 19, "endColumn": 28, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -55,9 +85,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -65,9 +95,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -75,9 +105,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 24, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -85,9 +115,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 22, "column": 44, - "endLine": 21, + "endLine": 22, "endColumn": 53, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -95,9 +125,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 23, "column": 17, - "endLine": 22, + "endLine": 23, "endColumn": 26, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -105,9 +135,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -115,9 +145,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -125,9 +155,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 27, - "endLine": 25, + "endLine": 26, "endColumn": 36, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -135,9 +165,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 10, - "endLine": 26, + "endLine": 27, "endColumn": 23, "problem": "StructuralIdentity", "suggest": "", @@ -145,9 +175,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 39, - "endLine": 26, + "endLine": 27, "endColumn": 48, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -155,9 +185,9 @@ "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 55, - "endLine": 27, + "endLine": 28, "endColumn": 64, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -165,9 +195,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 29, "column": 61, - "endLine": 28, + "endLine": 29, "endColumn": 70, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -175,9 +205,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 7, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "UnknownType", "suggest": "", @@ -185,9 +215,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 22, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -195,9 +225,9 @@ "severity": "ERROR" }, { - "line": 34, + "line": 35, "column": 38, - "endLine": 34, + "endLine": 35, "endColumn": 51, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -205,9 +235,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 36, "column": 30, - "endLine": 35, + "endLine": 36, "endColumn": 39, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -215,9 +245,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 37, "column": 29, - "endLine": 36, + "endLine": 37, "endColumn": 38, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -225,9 +255,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 38, "column": 29, - "endLine": 37, + "endLine": 38, "endColumn": 38, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -235,9 +265,9 @@ "severity": "ERROR" }, { - "line": 38, + "line": 39, "column": 31, - "endLine": 38, + "endLine": 39, "endColumn": 40, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -245,19 +275,29 @@ "severity": "ERROR" }, { - "line": 40, + "line": 41, + "column": 46, + "endLine": 41, + "endColumn": 66, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 41, "column": 34, - "endLine": 40, - "endColumn": 63, + "endLine": 41, + "endColumn": 67, "problem": "GenericCallNoTypeArgs", "suggest": "", "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, { - "line": 43, + "line": 44, "column": 10, - "endLine": 43, + "endLine": 44, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -265,9 +305,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 48, "column": 10, - "endLine": 47, + "endLine": 48, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -275,9 +315,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 52, "column": 10, - "endLine": 51, + "endLine": 52, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -285,9 +325,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 52, "column": 10, - "endLine": 51, + "endLine": 52, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -295,9 +335,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 56, "column": 10, - "endLine": 55, + "endLine": 56, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -305,9 +345,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 56, "column": 10, - "endLine": 55, + "endLine": 56, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -315,9 +355,9 @@ "severity": "ERROR" }, { - "line": 60, + "line": 61, "column": 12, - "endLine": 60, + "endLine": 61, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -325,9 +365,9 @@ "severity": "ERROR" }, { - "line": 64, + "line": 65, "column": 12, - "endLine": 64, + "endLine": 65, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -335,9 +375,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 69, "column": 12, - "endLine": 68, + "endLine": 69, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -345,9 +385,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 69, "column": 12, - "endLine": 68, + "endLine": 69, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -355,9 +395,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 12, - "endLine": 72, + "endLine": 73, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -365,14 +405,334 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 12, - "endLine": 72, + "endLine": 73, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" + }, + { + "line": 77, + "column": 38, + "endLine": 80, + "endColumn": 3, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 29, + "endLine": 81, + "endColumn": 34, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 25, + "endLine": 81, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 9, + "endLine": 83, + "endColumn": 14, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 77, + "endLine": 86, + "endColumn": 93, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 40, + "endLine": 97, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 36, + "endLine": 97, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 55, + "endLine": 98, + "endColumn": 60, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 51, + "endLine": 98, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 56, + "endLine": 99, + "endColumn": 61, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 52, + "endLine": 99, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 26, + "endLine": 100, + "endColumn": 31, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 22, + "endLine": 100, + "endColumn": 33, + "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": 106, + "endColumn": 31, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 22, + "endLine": 111, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 22, + "endLine": 113, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 22, + "endLine": 115, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 17, + "endLine": 124, + "endColumn": 24, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 9, + "endLine": 129, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 9, + "endLine": 132, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 9, + "endLine": 135, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 9, + "endLine": 138, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 2, + "endLine": 84, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Observed\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 4, + "endLine": 86, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Track\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 54, + "endLine": 86, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"CommonAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"CommonAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 22, + "endLine": 103, + "endColumn": 37, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "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 index 773fea5ff8c4e90cfc4e962f87f7eb24ea4edf71..c75c3540332d3909a6bbb2f8d4812d04710185df 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json @@ -1,23 +1,23 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT 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": 16, + "line": 17, "column": 7, - "endLine": 16, + "endLine": 17, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -25,9 +25,19 @@ "severity": "ERROR" }, { - "line": 16, + "line": 17, + "column": 28, + "endLine": 17, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 17, "column": 24, - "endLine": 16, + "endLine": 17, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -35,16 +45,30 @@ "severity": "ERROR" }, { - "line": 17, + "line": 18, + "column": 40, + "endLine": 18, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 18, "column": 36, - "endLine": 17, + "endLine": 18, "endColumn": 47, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 676, - "end": 687, - "replacementText": "new Array()" + "start": 732, + "end": 732, + "replacementText": "", + "line": 18, + "column": 36, + "endLine": 18, + "endColumn": 47 } ], "suggest": "", @@ -52,16 +76,30 @@ "severity": "ERROR" }, { - "line": 18, + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 26, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 19, "column": 17, - "endLine": 18, + "endLine": 19, "endColumn": 28, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 705, - "end": 716, - "replacementText": "new Array()" + "start": 761, + "end": 761, + "replacementText": "", + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 28 } ], "suggest": "", @@ -69,9 +107,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -79,9 +117,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -89,9 +127,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 24, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -99,16 +137,20 @@ "severity": "ERROR" }, { - "line": 21, + "line": 22, "column": 44, - "endLine": 21, + "endLine": 22, "endColumn": 53, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 796, - "end": 805, - "replacementText": "new Map()" + "start": 850, + "end": 850, + "replacementText": "", + "line": 22, + "column": 44, + "endLine": 22, + "endColumn": 53 } ], "suggest": "", @@ -116,16 +158,20 @@ "severity": "ERROR" }, { - "line": 22, + "line": 23, "column": 17, - "endLine": 22, + "endLine": 23, "endColumn": 26, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 823, - "end": 832, - "replacementText": "new Map()" + "start": 877, + "end": 877, + "replacementText": "", + "line": 23, + "column": 17, + "endLine": 23, + "endColumn": 26 } ], "suggest": "", @@ -133,9 +179,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -143,9 +189,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -153,9 +199,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 27, - "endLine": 25, + "endLine": 26, "endColumn": 36, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -163,9 +209,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 10, - "endLine": 26, + "endLine": 27, "endColumn": 23, "problem": "StructuralIdentity", "suggest": "", @@ -173,9 +219,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 27, "column": 39, - "endLine": 26, + "endLine": 27, "endColumn": 48, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -183,16 +229,20 @@ "severity": "ERROR" }, { - "line": 27, + "line": 28, "column": 55, - "endLine": 27, + "endLine": 28, "endColumn": 64, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 994, - "end": 1003, - "replacementText": "new Map string[]>()" + "start": 1048, + "end": 1048, + "replacementText": " string[]>", + "line": 28, + "column": 55, + "endLine": 28, + "endColumn": 64 } ], "suggest": "", @@ -200,16 +250,20 @@ "severity": "ERROR" }, { - "line": 28, + "line": 29, "column": 61, - "endLine": 28, + "endLine": 29, "endColumn": 70, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1065, - "end": 1074, - "replacementText": "new Map string[]>()" + "start": 1119, + "end": 1119, + "replacementText": " string[]>", + "line": 29, + "column": 61, + "endLine": 29, + "endColumn": 70 } ], "suggest": "", @@ -217,9 +271,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 7, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "UnknownType", "suggest": "", @@ -227,9 +281,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 22, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -237,16 +291,20 @@ "severity": "ERROR" }, { - "line": 34, + "line": 35, "column": 38, - "endLine": 34, + "endLine": 35, "endColumn": 51, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1215, - "end": 1228, - "replacementText": "new MyClass()" + "start": 1273, + "end": 1273, + "replacementText": "", + "line": 35, + "column": 38, + "endLine": 35, + "endColumn": 51 } ], "suggest": "", @@ -254,9 +312,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 36, "column": 30, - "endLine": 35, + "endLine": 36, "endColumn": 39, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -264,16 +322,20 @@ "severity": "ERROR" }, { - "line": 36, + "line": 37, "column": 29, - "endLine": 36, + "endLine": 37, "endColumn": 38, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1298, - "end": 1307, - "replacementText": "new Set()" + "start": 1352, + "end": 1352, + "replacementText": "", + "line": 37, + "column": 29, + "endLine": 37, + "endColumn": 38 } ], "suggest": "", @@ -281,16 +343,20 @@ "severity": "ERROR" }, { - "line": 37, + "line": 38, "column": 29, - "endLine": 37, + "endLine": 38, "endColumn": 38, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1337, - "end": 1346, - "replacementText": "new Map string[]>()" + "start": 1391, + "end": 1391, + "replacementText": " string[]>", + "line": 38, + "column": 29, + "endLine": 38, + "endColumn": 38 } ], "suggest": "", @@ -298,16 +364,20 @@ "severity": "ERROR" }, { - "line": 38, + "line": 39, "column": 31, - "endLine": 38, + "endLine": 39, "endColumn": 40, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1378, - "end": 1387, - "replacementText": "new Map string[]>()" + "start": 1432, + "end": 1432, + "replacementText": " string[]>", + "line": 39, + "column": 31, + "endLine": 39, + "endColumn": 40 } ], "suggest": "", @@ -315,16 +385,30 @@ "severity": "ERROR" }, { - "line": 40, + "line": 41, + "column": 46, + "endLine": 41, + "endColumn": 66, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 41, "column": 34, - "endLine": 40, - "endColumn": 63, + "endLine": 41, + "endColumn": 67, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1423, - "end": 1452, - "replacementText": "new Promise(() => { return ''; })" + "start": 1481, + "end": 1481, + "replacementText": "", + "line": 41, + "column": 34, + "endLine": 41, + "endColumn": 67 } ], "suggest": "", @@ -332,16 +416,20 @@ "severity": "ERROR" }, { - "line": 43, + "line": 44, "column": 10, - "endLine": 43, + "endLine": 44, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1504, - "end": 1513, - "replacementText": "new Map()" + "start": 1562, + "end": 1562, + "replacementText": "", + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 19 } ], "suggest": "", @@ -349,16 +437,20 @@ "severity": "ERROR" }, { - "line": 47, + "line": 48, "column": 10, - "endLine": 47, + "endLine": 48, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1582, - "end": 1591, - "replacementText": "new Map()" + "start": 1640, + "end": 1640, + "replacementText": "", + "line": 48, + "column": 10, + "endLine": 48, + "endColumn": 19 } ], "suggest": "", @@ -366,9 +458,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 52, "column": 10, - "endLine": 51, + "endLine": 52, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -376,9 +468,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 52, "column": 10, - "endLine": 51, + "endLine": 52, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -386,9 +478,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 56, "column": 10, - "endLine": 55, + "endLine": 56, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -396,9 +488,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 56, "column": 10, - "endLine": 55, + "endLine": 56, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -406,16 +498,20 @@ "severity": "ERROR" }, { - "line": 60, + "line": 61, "column": 12, - "endLine": 60, + "endLine": 61, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1798, - "end": 1807, - "replacementText": "new Map()" + "start": 1856, + "end": 1856, + "replacementText": "", + "line": 61, + "column": 12, + "endLine": 61, + "endColumn": 21 } ], "suggest": "", @@ -423,16 +519,20 @@ "severity": "ERROR" }, { - "line": 64, + "line": 65, "column": 12, - "endLine": 64, + "endLine": 65, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "autofix": [ { - "start": 1873, - "end": 1882, - "replacementText": "new Map()" + "start": 1931, + "end": 1931, + "replacementText": "", + "line": 65, + "column": 12, + "endLine": 65, + "endColumn": 21 } ], "suggest": "", @@ -440,9 +540,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 69, "column": 12, - "endLine": 68, + "endLine": 69, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -450,9 +550,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 69, "column": 12, - "endLine": 68, + "endLine": 69, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -460,9 +560,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 12, - "endLine": 72, + "endLine": 73, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -470,14 +570,510 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 12, - "endLine": 72, + "endLine": 73, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" + }, + { + "line": 77, + "column": 38, + "endLine": 80, + "endColumn": 3, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2121, + "end": 2121, + "replacementText": "", + "line": 77, + "column": 38, + "endLine": 80, + "endColumn": 3 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 29, + "endLine": 81, + "endColumn": 34, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 25, + "endLine": 81, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2220, + "end": 2220, + "replacementText": "", + "line": 81, + "column": 25, + "endLine": 81, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 9, + "endLine": 83, + "endColumn": 14, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2273, + "end": 2273, + "replacementText": "", + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 77, + "endLine": 86, + "endColumn": 93, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 40, + "endLine": 97, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 36, + "endLine": 97, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2592, + "end": 2592, + "replacementText": "", + "line": 97, + "column": 36, + "endLine": 97, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 55, + "endLine": 98, + "endColumn": 60, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 51, + "endLine": 98, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2655, + "end": 2655, + "replacementText": "", + "line": 98, + "column": 51, + "endLine": 98, + "endColumn": 62 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 56, + "endLine": 99, + "endColumn": 61, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 52, + "endLine": 99, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 26, + "endLine": 100, + "endColumn": 31, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 22, + "endLine": 100, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2753, + "end": 2753, + "replacementText": "", + "line": 100, + "column": 22, + "endLine": 100, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 14, + "endLine": 106, + "endColumn": 31, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2880, + "end": 2880, + "replacementText": "", + "line": 105, + "column": 14, + "endLine": 106, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 22, + "endLine": 111, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 22, + "endLine": 113, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 22, + "endLine": 115, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 17, + "endLine": 124, + "endColumn": 24, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 3313, + "end": 3313, + "replacementText": "<[C]>", + "line": 124, + "column": 17, + "endLine": 124, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 9, + "endLine": 129, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 3430, + "end": 3430, + "replacementText": "", + "line": 129, + "column": 9, + "endLine": 129, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 9, + "endLine": 132, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 3461, + "end": 3461, + "replacementText": "", + "line": 132, + "column": 9, + "endLine": 132, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 9, + "endLine": 135, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 3492, + "end": 3492, + "replacementText": "", + "line": 135, + "column": 9, + "endLine": 135, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 9, + "endLine": 138, + "endColumn": 18, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 3537, + "end": 3537, + "replacementText": "", + "line": 138, + "column": 9, + "endLine": 138, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 2, + "endLine": 84, + "endColumn": 10, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Observed,\n Track,\n CommonAttribute,\n} from '@kit.ArkUI';\n", + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Observed\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 4, + "endLine": 86, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Observed,\n Track,\n CommonAttribute,\n} from '@kit.ArkUI';\n", + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Track\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 54, + "endLine": 86, + "endColumn": 69, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Observed,\n Track,\n CommonAttribute,\n} from '@kit.ArkUI';\n", + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"CommonAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Observed,\n Track,\n CommonAttribute,\n} from '@kit.ArkUI';\n", + "line": 86, + "column": 94, + "endLine": 86, + "endColumn": 109 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"CommonAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 22, + "endLine": 103, + "endColumn": 37, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "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 index 1f00081d43be7bede54b70559d1f112d1b9b47ab..c3cf571d47c001259b422014701fc4184dc4faea 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 7, - "endLine": 16, + "endLine": 17, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 7, - "endLine": 20, + "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 26, "column": 3, - "endLine": 25, + "endLine": 26, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 7, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "UnknownType", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 33, "column": 22, - "endLine": 32, + "endLine": 33, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 52, "column": 10, - "endLine": 51, + "endLine": 52, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -95,9 +95,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 56, "column": 10, - "endLine": 55, + "endLine": 56, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -105,9 +105,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 69, "column": 12, - "endLine": 68, + "endLine": 69, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -115,14 +115,24 @@ "severity": "ERROR" }, { - "line": 72, + "line": 73, "column": 12, - "endLine": 72, + "endLine": 73, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" + }, + { + "line": 103, + "column": 22, + "endLine": 103, + "endColumn": 37, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "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 index 01a5d89f97c06ce79226ada89136f658d4d19bdb..68520df9e2244e5b6b2ca1c43a3e946ad820ccbd 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets @@ -13,6 +13,14 @@ * limitations under the License. */ +import { + Observed, + Track, + CommonAttribute, +} from '@kit.ArkUI'; + +import { AttributeUpdater } from '@kit.ArkUI'; + const irreparableArr = new Array(); let repairableArr: Array = new Array(); repairableArr = new Array(); @@ -72,3 +80,68 @@ class MyClassB { return new Set(); } } + +const testMap: Map = new Map([ + ['123', 1], // my comment 1 + ['sfe', 2] // my comment 2 +]); +let a : Array = new Array(); +function foo(arr:Array) { } +foo(new Array()); +@Observed +export class AppIconCloneBadgeVm { + @Track public cloneBadgeModifier: AttributeUpdater = new AttributeUpdater(); +} +class B {} +class C {} +class A { + t:T; + constructor(t:T) { + this.t = t; + } +} +new A(new C()) +let a: Array | undefined = new Array(); +let aa: Array | Set | undefined = new Array(); +let b: Array | Array | undefined = new Array(); +let test: string[] = new Array(); + +class A { + test(key: string): Promise { + if (key == undefined || key.length == 0.0) { + return new Promise((resolve, reject) => { + reject("empty key");}); + } else { + } + } +} +class SubArr extends Array {} +let subArr = new SubArr(); +class SubSet extends Set{} +let subSet = new SubSet(); +class SubMap extends Map{} +let subMap = new SubMap(); +class SubWeakMap extends WeakMap{} +let subWeakMap = new SubWeakMap(); +class SubWeakSet extends WeakSet{} +let subWeakSet = new SubWeakSet(); + +class C {} +class D {} +let a: D<[C]> = new D<[C]>(); + +function fun(a?:Map){ + let c:Map|undefined + if(a === undefined){ + a = new Map() + } + if(a){ + a = new Map() + } + if(c){ + c = new Map() + } + if(c === undefined){ + c = new Map() + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json index a3d92d0d965596b23b8e137b426e01275b3f7847..0012a4b9eaa78bbd3f3389adf50516710d888c7d 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 16, + "line": 24, "column": 7, - "endLine": 16, + "endLine": 24, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -25,9 +25,19 @@ "severity": "ERROR" }, { - "line": 16, + "line": 24, + "column": 28, + "endLine": 24, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 24, "column": 24, - "endLine": 16, + "endLine": 24, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -35,9 +45,29 @@ "severity": "ERROR" }, { - "line": 20, + "line": 25, + "column": 40, + "endLine": 25, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 21, + "endLine": 26, + "endColumn": 26, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 28, "column": 7, - "endLine": 20, + "endLine": 28, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -45,9 +75,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 28, "column": 7, - "endLine": 20, + "endLine": 28, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -55,9 +85,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 28, "column": 24, - "endLine": 20, + "endLine": 28, "endColumn": 33, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -65,9 +95,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 33, "column": 3, - "endLine": 25, + "endLine": 33, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -75,9 +105,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 33, "column": 3, - "endLine": 25, + "endLine": 33, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -85,9 +115,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 33, "column": 27, - "endLine": 25, + "endLine": 33, "endColumn": 36, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -95,9 +125,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 34, "column": 10, - "endLine": 26, + "endLine": 34, "endColumn": 23, "problem": "StructuralIdentity", "suggest": "", @@ -105,9 +135,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 34, "column": 39, - "endLine": 26, + "endLine": 34, "endColumn": 48, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -115,9 +145,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 40, "column": 7, - "endLine": 32, + "endLine": 40, "endColumn": 35, "problem": "UnknownType", "suggest": "", @@ -125,9 +155,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 40, "column": 22, - "endLine": 32, + "endLine": 40, "endColumn": 35, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -135,9 +165,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 43, "column": 30, - "endLine": 35, + "endLine": 43, "endColumn": 39, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -145,9 +175,19 @@ "severity": "ERROR" }, { - "line": 51, + "line": 48, + "column": 54, + "endLine": 48, + "endColumn": 74, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 59, "column": 10, - "endLine": 51, + "endLine": 59, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -155,9 +195,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 59, "column": 10, - "endLine": 51, + "endLine": 59, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -165,9 +205,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 63, "column": 10, - "endLine": 55, + "endLine": 63, "endColumn": 19, "problem": "StructuralIdentity", "suggest": "", @@ -175,9 +215,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 63, "column": 10, - "endLine": 55, + "endLine": 63, "endColumn": 19, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -185,9 +225,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 76, "column": 12, - "endLine": 68, + "endLine": 76, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -195,9 +235,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 76, "column": 12, - "endLine": 68, + "endLine": 76, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -205,9 +245,9 @@ "severity": "ERROR" }, { - "line": 72, + "line": 80, "column": 12, - "endLine": 72, + "endLine": 80, "endColumn": 21, "problem": "StructuralIdentity", "suggest": "", @@ -215,14 +255,174 @@ "severity": "ERROR" }, { - "line": 72, + "line": 80, "column": 12, - "endLine": 72, + "endLine": 80, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" + }, + { + "line": 88, + "column": 29, + "endLine": 88, + "endColumn": 34, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 9, + "endLine": 90, + "endColumn": 14, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 77, + "endLine": 93, + "endColumn": 93, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 40, + "endLine": 104, + "endColumn": 45, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 55, + "endLine": 105, + "endColumn": 60, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 56, + "endLine": 106, + "endColumn": 61, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 52, + "endLine": 106, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 26, + "endLine": 107, + "endColumn": 31, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 22, + "endLine": 118, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 22, + "endLine": 120, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 22, + "endLine": 122, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 26, + "endLine": 124, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 26, + "endLine": 124, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 26, + "endLine": 126, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 26, + "endLine": 126, + "endColumn": 33, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 22, + "endLine": 110, + "endColumn": 37, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets b/ets2panda/linter/test/main/func_inferred_type_args_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..cefc55fba0a8f50f3fee8ff86e62b29abee5a8bf --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.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 {A} from './func_inferred_type_args_ts'; +import B from './func_inferred_type_args_ts' +import A2 from './func_inferred_type_args_ts2' +import {A3} from './func_inferred_type_args_ts2' +import { HashMap } from '@kit.ArkTS'; +import { IMonitorValue, IMonitor, LocalStorage, AbstractProperty, SubscribedAbstractProperty, AppStorage} from './oh_modules/common_ts_ets_api'; + +function test() { + const a = new A(); + a.map = new Map(); //error +} +function test2() { + const a = new A2(); + a.map = new Map(); //error +} +function test3() { + const a = new A3(); + a.map = new Map(); //error +} + +class A4 { + id?: string; + map?: HashMap; +} +class Demo{} + +function test4() { + const a = new A4(); + a.map = new HashMap(); //error +} + +@ComponentV2 +struct Child { + @Param info: Info = new Info(); + @Monitor("info.message") + onMessageChange(monitor: IMonitor) { + let beforeValue: IMonitorValue = monitor.value(); + let beforeValue: IMonitorValue = monitor.value("info.message"); + console.info(`Child message change from ${monitor.value()?.before} to ${monitor.value('info.message')?.now}`); + } +} + +let para: Record = { 'PropA': 47 }; +let storage: LocalStorage = new LocalStorage(para); +let propA: number | undefined = storage.get('PropA'); +let link1: SubscribedAbstractProperty = storage.link('PropA'); +let refToPropA1: AbstractProperty | undefined = storage.ref('PropA'); + +let propA: number | undefined = AppStorage.get('PropA'); +let link1: SubscribedAbstractProperty = AppStorage.link('PropA'); +let refToPropA1: AbstractProperty | undefined = AppStorage.ref('PropA'); \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets.args.json b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..30973c00a22aa0a072616f644b02c89a4a4dd4fa --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_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/func_inferred_type_args_3.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6076658f57ad2d92b7e1ef4114cb986212379ff8 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 11, + "endLine": 24, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 32, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 24, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 27, + "endLine": 48, + "endColumn": 31, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 46, + "endLine": 51, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 46, + "endLine": 52, + "endColumn": 75, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 47, + "endLine": 53, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 77, + "endLine": 53, + "endColumn": 106, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 33, + "endLine": 59, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 49, + "endLine": 60, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 57, + "endLine": 61, + "endColumn": 77, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 33, + "endLine": 63, + "endColumn": 56, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 49, + "endLine": 64, + "endColumn": 73, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 57, + "endLine": 65, + "endColumn": 80, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 2, + "endLine": 46, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 4, + "endLine": 48, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Param\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Monitor\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets.autofix.json b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..4430d3c9813485b325f30b7158ab32c0534fbd06 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.autofix.json @@ -0,0 +1,424 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 11, + "endLine": 24, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1033, + "end": 1033, + "replacementText": "", + "line": 24, + "column": 11, + "endLine": 24, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 32, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1177, + "end": 1177, + "replacementText": "", + "line": 32, + "column": 11, + "endLine": 32, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 24, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1328, + "end": 1328, + "replacementText": "", + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 27, + "endLine": 48, + "endColumn": 31, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 46, + "endLine": 51, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1529, + "end": 1529, + "replacementText": "", + "line": 51, + "column": 46, + "endLine": 51, + "endColumn": 61 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 46, + "endLine": 52, + "endColumn": 75, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1591, + "end": 1591, + "replacementText": "", + "line": 52, + "column": 46, + "endLine": 52, + "endColumn": 75 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 47, + "endLine": 53, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1668, + "end": 1668, + "replacementText": "", + "line": 53, + "column": 47, + "endLine": 53, + "endColumn": 62 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 77, + "endLine": 53, + "endColumn": 106, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1698, + "end": 1698, + "replacementText": "", + "line": 53, + "column": 77, + "endLine": 53, + "endColumn": 106 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 33, + "endLine": 59, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1877, + "end": 1877, + "replacementText": "", + "line": 59, + "column": 33, + "endLine": 59, + "endColumn": 53 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 49, + "endLine": 60, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1948, + "end": 1948, + "replacementText": "", + "line": 60, + "column": 49, + "endLine": 60, + "endColumn": 70 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 57, + "endLine": 61, + "endColumn": 77, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2026, + "end": 2026, + "replacementText": "", + "line": 61, + "column": 57, + "endLine": 61, + "endColumn": 77 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 33, + "endLine": 63, + "endColumn": 56, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2084, + "end": 2084, + "replacementText": "", + "line": 63, + "column": 33, + "endLine": 63, + "endColumn": 56 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 49, + "endLine": 64, + "endColumn": 73, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2158, + "end": 2158, + "replacementText": "", + "line": 64, + "column": 49, + "endLine": 64, + "endColumn": 73 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 57, + "endLine": 65, + "endColumn": 80, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 2239, + "end": 2239, + "replacementText": "", + "line": 65, + "column": 57, + "endLine": 65, + "endColumn": 80 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 2, + "endLine": 46, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n ComponentV2,\n Param,\n Monitor,\n} from '@kit.ArkUI';\n", + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 4, + "endLine": 48, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n ComponentV2,\n Param,\n Monitor,\n} from '@kit.ArkUI';\n", + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Param\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n ComponentV2,\n Param,\n Monitor,\n} from '@kit.ArkUI';\n", + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Monitor\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets.json b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9b8ac8bc7dba0a8c8b78a0303ccffd0b78a19807 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.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": 51, + "column": 9, + "endLine": 51, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 52, + "column": 9, + "endLine": 52, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets.migrate.ets b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e6fc54f403bf21a8b835862455e126e5d797f4d2 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.migrate.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. + */ + +import { + ComponentV2, + Param, + Monitor, +} from '@kit.ArkUI'; + +import {A} from './func_inferred_type_args_ts'; +import B from './func_inferred_type_args_ts' +import A2 from './func_inferred_type_args_ts2' +import {A3} from './func_inferred_type_args_ts2' +import { HashMap } from '@kit.ArkTS'; +import { IMonitorValue, IMonitor, LocalStorage, AbstractProperty, SubscribedAbstractProperty, AppStorage} from './oh_modules/common_ts_ets_api'; + +function test() { + const a = new A(); + a.map = new Map(); //error +} +function test2() { + const a = new A2(); + a.map = new Map(); //error +} +function test3() { + const a = new A3(); + a.map = new Map(); //error +} + +class A4 { + id?: string; + map?: HashMap; +} +class Demo{} + +function test4() { + const a = new A4(); + a.map = new HashMap(); //error +} + +@ComponentV2 +struct Child { + @Param info: Info = new Info(); + @Monitor("info.message") + onMessageChange(monitor: IMonitor) { + let beforeValue: IMonitorValue = monitor.value(); + let beforeValue: IMonitorValue = monitor.value("info.message"); + console.info(`Child message change from ${monitor.value()?.before} to ${monitor.value('info.message')?.now}`); + } +} + +let para: Record = { 'PropA': 47 }; +let storage: LocalStorage = new LocalStorage(para); +let propA: number | undefined = storage.get('PropA'); +let link1: SubscribedAbstractProperty = storage.link('PropA'); +let refToPropA1: AbstractProperty | undefined = storage.ref('PropA'); + +let propA: number | undefined = AppStorage.get('PropA'); +let link1: SubscribedAbstractProperty = AppStorage.link('PropA'); +let refToPropA1: AbstractProperty | undefined = AppStorage.ref('PropA'); \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_3.ets.migrate.json b/ets2panda/linter/test/main/func_inferred_type_args_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..62f3ae72ba416c8d81e7056a12bd739734bbc4c4 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_3.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": 35, + "column": 11, + "endLine": 35, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 27, + "endLine": 55, + "endColumn": 31, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 9, + "endLine": 58, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "rule": "Type 'IMonitorValue | undefined' is not assignable to type 'IMonitorValue'.\n Type 'undefined' is not assignable to type 'IMonitorValue'.", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "rule": "Type 'SubscribedAbstractProperty | undefined' is not assignable to type 'SubscribedAbstractProperty'.\n Type 'undefined' is not assignable to type 'SubscribedAbstractProperty'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_ts.ts b/ets2panda/linter/test/main/func_inferred_type_args_ts.ts new file mode 100644 index 0000000000000000000000000000000000000000..59435fad582f9b7fc7f17f56d2f5be3a6520997f --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_ts.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. + */ +export class A { + id?: string; + map?: Map; +} + +export default class B {} +export class C {} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_ts.ts.json b/ets2panda/linter/test/main/func_inferred_type_args_ts.ts.json new file mode 100644 index 0000000000000000000000000000000000000000..b7a8809e02ae14f7f14ed7adbd6d2d3f630fa3f6 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_ts.ts.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/func_inferred_type_args_ts2.ts b/ets2panda/linter/test/main/func_inferred_type_args_ts2.ts new file mode 100644 index 0000000000000000000000000000000000000000..aedcb256cb4182f35f30974ac952de81423d1bfd --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_ts2.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. + */ +import {C} from './func_inferred_type_args_ts' +import B from './func_inferred_type_args_ts' +export default class A2 { + id?: string; + map?: Map; +} +export class A3 { + id?: string; + map?: Map; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_ts2.ts.json b/ets2panda/linter/test/main/func_inferred_type_args_ts2.ts.json new file mode 100644 index 0000000000000000000000000000000000000000..b7a8809e02ae14f7f14ed7adbd6d2d3f630fa3f6 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_ts2.ts.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/global_this.ets.args.json b/ets2panda/linter/test/main/global_this.ets.args.json index a89d885810708ad03d96e3e14bb6590efd1a7547..4d93062f69db6d74420adeb506e0ca28c5580728 100644 --- a/ets2panda/linter/test/main/global_this.ets.args.json +++ b/ets2panda/linter/test/main/global_this.ets.args.json @@ -14,8 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2", - "migrate": "--arkts-2" + "arkts2": "" } } diff --git a/ets2panda/linter/test/main/global_this.ets.arkts2.json b/ets2panda/linter/test/main/global_this.ets.arkts2.json index 34bcda6b2d2414dd2e9bf4d9e05f9a556ee0a4b7..d607906636042abd68a783192d34440151948e01 100644 --- a/ets2panda/linter/test/main/global_this.ets.arkts2.json +++ b/ets2panda/linter/test/main/global_this.ets.arkts2.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 7, - "endLine": 16, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 19, "column": 7, diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.ets b/ets2panda/linter/test/main/global_this.ets.migrate.ets deleted file mode 100644 index d1fb5d519f174c046533036129ee9e5653352f72..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/main/global_this.ets.migrate.ets +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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); - -const value = specialAutofixLib.globalThis.get("obj").prop; - -delete specialAutofixLib.globalThis.get("property"); - -globalThisprop = 100; - -specialAutofixLib.globalThis.get("pi"); - -specialAutofixLib.globalThis.set("pi",3.1416); - -specialAutofixLib.globalThis; - diff --git a/ets2panda/linter/test/main/ignore_files/user_created_collections.ets b/ets2panda/linter/test/main/ignore_files/user_created_collections.ets new file mode 100644 index 0000000000000000000000000000000000000000..f900dc1034ce5799ff90b47fcc74be9ab3301d19 --- /dev/null +++ b/ets2panda/linter/test/main/ignore_files/user_created_collections.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 { + + } +} diff --git a/ets2panda/linter/test/main/incompatible_function.ets b/ets2panda/linter/test/main/incompatible_function.ets index e137fe5ecc7c1d95332b75831e1e407433c031df..1701ac0932e01c42c674e4e4b9da75993f3af6c8 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets +++ b/ets2panda/linter/test/main/incompatible_function.ets @@ -79,4 +79,125 @@ type FuncTypeNoParams = () => void; let fNoParams: FuncTypeNoParams = () => { return 0; -}; \ No newline at end of file +}; + +class A {} + +class C extends Array {} + +class B { + private arr: Array = []; + + test(): C { + return this.arr; + } +} + +function sleep(time: number): Promise { + return new Promise((resolve) => setTimeout(resolve, time)); +} +sleep(100); + +const caseName = 'PromiseAnyTest0200'; +console.info(`${caseName} test start`); +const startTime = Date.now(); +const promises: Promise[] = []; +const totalPromises = 1000; +const delay = 100; +for (let i = 0; i < totalPromises; i++) { + promises.push( + new Promise((_, reject) => + setTimeout(() => { + reject(new Error(`Failure ${i}`)); + }, delay) + ) + ); +} + +class D { + fun(a: ArrayBufferLike): ArrayBuffer { + return a; + } +} + +class X { + n: number = 0 + s: string = '' +} + +class Y { + n: number = 0 + s: string = '' +} + +class E { + Dfun(a: X|Y): X { + return a; + } +} + +import { Entry, Text, Column, Component, Button, ClickEvent ,Image ,ShadowOptions} from '@ohos.arkui.component' +import { State } from '@ohos.arkui.stateManagement' +import hilog from '@ohos.hilog' +import util from '@ohos.util'; + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = 'state var'; + message: string = 'var'; + + changeValue() { + this.getUIContext(); + this.stateVar += '~' + } + + build() { + Column(undefined) { + Text('Hello World').fontSize(20) + Button(this.message).backgroundColor('#FFFF00FF') + .onClick(async (e: ClickEvent) => { + let lock: AsyncLock = AsyncLock.request("lock_1"); + hilog.info(0x0000, 'testTag', 'On Click'); + let a = this.getUIContext(); + this.changeValue(); + + }) + Text(this.stateVar).fontSize(20) + .onClick((e: ClickEvent) => { + this.message += "~" + } as (event: ClickEvent) => void) + Child({ stateVar: this.stateVar }) + } + } +} + +interface CustomClickable { + onClick(handler: (event: ClickEvent) => void): this; +} + +function onClick(handler: (event: ClickEvent) => void): this { + return this.onClick((e: ClickEvent) => { + console.log('Before custom onClick'); + handler(e); + console.log('After custom onClick'); + }); +} + +// 将扩展方法附加到Button组件 +Button.extend({ onClick }); + +@Entry +@Component +struct MyComponent { + @State message: string = 'Click me'; + + build() { + Column() { + Button(this.message) + .onClick((e: ClickEvent) => { + this.message = 'Custom onClick worked!'; + }) + } + } +} \ 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..5b2f2475b0e6a5194d038317141415d5433cbcdf 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json @@ -83,6 +83,146 @@ "suggest": "", "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" + }, + { + "line": 92, + "column": 12, + "endLine": 92, + "endColumn": 20, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 31, + "endLine": 97, + "endColumn": 38, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 26, + "endLine": 109, + "endColumn": 35, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 12, + "endLine": 135, + "endColumn": 13, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 37, + "endLine": 169, + "endColumn": 41, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "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/incompatible_function.ets.json b/ets2panda/linter/test/main/incompatible_function.ets.json index 2844fc25ba579f7e073c0d91f47b203c80c09683..e2e1afdc24b3780c5fbc0b6926038fa23b78adda 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.json @@ -13,5 +13,96 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 112, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 1, + "endLine": 140, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 1, + "endLine": 141, + "endColumn": 32, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 1, + "endLine": 142, + "endColumn": 31, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 18, + "endLine": 165, + "endColumn": 10, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 50, + "endLine": 176, + "endColumn": 54, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 10, + "endLine": 180, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 57, + "endLine": 179, + "endColumn": 61, + "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/index_access_static_and_class_instance.ets b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets new file mode 100644 index 0000000000000000000000000000000000000000..942125e00d666c37a2b292b1aae9b0d2f6a8710d --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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 { + static foo1(){} + foo2(){} +} + +let a = new A(); +(a as object)["foo2"]; //arkts-no-ops-by-index autofix is right + +(A as object)["foo1"]; // arkts-no-classes-as-obj autofix is right diff --git a/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.args.json b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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/index_access_static_and_class_instance.ets.arkts2.json b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..21e2ed90d00cef1fa05cbfc7a3d85621713be4f6 --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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": 22, + "column": 1, + "endLine": 22, + "endColumn": 22, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 2, + "endLine": 24, + "endColumn": 3, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.json b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.autofix.json similarity index 33% rename from ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.json rename to ets2panda/linter/test/main/index_access_static_and_class_instance.ets.autofix.json index 58c2313941355575e380c540f740b590f10c5723..827a118edf5e71fecb17e1339f81294be6e9b8d2 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets.autofix.json +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.autofix.json @@ -15,73 +15,45 @@ ], "result": [ { - "line": 17, + "line": 22, "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", + "endLine": 22, + "endColumn": 22, + "problem": "PropertyAccessByIndex", "autofix": [ { - "start": 618, - "end": 668, - "replacementText": "", - "line": 17, + "replacementText": "a.foo2", + "start": 664, + "end": 685, + "line": 22, "column": 1, - "endLine": 17, - "endColumn": 51 - }, - { - "start": 668, - "end": 668, - "replacementText": "let GeneratedImportVar_1 = ESObject.load('./interop_import_js_rules_js');\nlet ff1 = GeneratedImportVar_1.getPropertyByName('ff1');\n", - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 51 + "endLine": 22, + "endColumn": 22 } ], "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)", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, { - "line": 23, - "column": 1, - "endLine": 23, - "endColumn": 57, - "problem": "InteropArkTs1ObjectExport", + "line": 24, + "column": 2, + "endLine": 24, + "endColumn": 3, + "problem": "ClassAsObjectError", + "autofix": [ + { + "replacementText": "A.foo1", + "start": 729, + "end": 750, + "line": 24, + "column": 2, + "endLine": 24, + "endColumn": 3 + } + ], "suggest": "", - "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.json b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9493d7285d0e82274585ee08fc756e723f4e5ba2 --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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": 2, + "endLine": 24, + "endColumn": 3, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + } + ] +} diff --git a/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.migrate.ets b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb806649469d5af1b9349ac34044152f2637cf6e --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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. + */ + +class A { + static foo1(){} + foo2(){} +} + +let a = new A(); +a.foo2; //arkts-no-ops-by-index autofix is right + +A.foo1; // arkts-no-classes-as-obj autofix is right diff --git a/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.migrate.json b/ets2panda/linter/test/main/index_access_static_and_class_instance.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/index_access_static_and_class_instance.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": [] +} diff --git a/ets2panda/linter/test/main/index_negative.ets.arkts2.json b/ets2panda/linter/test/main/index_negative.ets.arkts2.json old mode 100755 new mode 100644 index f74d810960bf77a116281c44178ac50e57e4c9e5..399f04dc5104a140d2ad22892fc130984f087207 --- a/ets2panda/linter/test/main/index_negative.ets.arkts2.json +++ b/ets2panda/linter/test/main/index_negative.ets.arkts2.json @@ -14,34 +14,24 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 17, - "column": 5, + "column": 15, "endLine": 17, "endColumn": 26, - "problem": "NumericSemantics", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 18, - "column": 5, + "column": 16, "endLine": 18, "endColumn": 28, - "problem": "NumericSemantics", + "problem": "IndexNegative", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, { @@ -49,9 +39,9 @@ "column": 16, "endLine": 18, "endColumn": 28, - "problem": "IndexNegative", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -64,6 +54,36 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 21, "column": 10, @@ -95,13 +115,23 @@ "severity": "ERROR" }, { - "line": 32, - "column": 1, - "endLine": 34, - "endColumn": 2, - "problem": "NumericSemantics", + "line": 28, + "column": 9, + "endLine": 28, + "endColumn": 15, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 16, + "endLine": 29, + "endColumn": 21, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -114,6 +144,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 38, "column": 1, @@ -124,6 +164,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 14, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 39, "column": 5, @@ -134,6 +194,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 40, + "column": 1, + "endLine": 40, + "endColumn": 14, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 40, "column": 5, @@ -154,6 +224,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 42, + "column": 1, + "endLine": 42, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 42, "column": 5, @@ -164,6 +244,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 44, "column": 5, @@ -174,6 +264,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 45, + "column": 1, + "endLine": 45, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 45, "column": 5, @@ -184,6 +284,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 47, + "column": 1, + "endLine": 47, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 47, "column": 5, @@ -194,6 +304,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 14, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 48, "column": 5, @@ -214,6 +334,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 50, "column": 5, @@ -234,6 +364,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 52, + "column": 1, + "endLine": 52, + "endColumn": 15, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 52, "column": 5, @@ -244,6 +384,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 53, "column": 5, @@ -264,6 +414,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 54, + "column": 1, + "endLine": 54, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 54, "column": 5, @@ -274,6 +434,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 31, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 56, "column": 6, @@ -294,6 +464,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 57, + "column": 1, + "endLine": 57, + "endColumn": 29, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 57, "column": 5, @@ -304,6 +484,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 58, + "column": 1, + "endLine": 58, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 58, "column": 5, @@ -314,6 +504,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 59, + "column": 1, + "endLine": 59, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 59, "column": 5, @@ -334,6 +534,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 60, + "column": 1, + "endLine": 60, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 60, "column": 5, @@ -354,6 +564,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 61, + "column": 1, + "endLine": 61, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 61, "column": 5, @@ -374,6 +594,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 31, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 63, "column": 6, @@ -384,6 +614,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 31, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 65, "column": 1, @@ -394,6 +634,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 65, "column": 5, @@ -414,6 +664,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 66, + "column": 1, + "endLine": 66, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 66, "column": 5, @@ -434,6 +694,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 31, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 68, "column": 5, @@ -444,6 +714,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 69, "column": 5, @@ -454,6 +734,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 70, "column": 5, @@ -465,13 +755,13 @@ "severity": "ERROR" }, { - "line": 71, - "column": 7, - "endLine": 71, - "endColumn": 35, - "problem": "NumericSemantics", + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 31, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -496,72 +786,32 @@ }, { "line": 73, - "column": 5, + "column": 1, "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, - "endLine": 74, - "endColumn": 15, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 7, - "endLine": 75, - "endColumn": 16, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 7, - "endLine": 76, - "endColumn": 16, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 7, - "endLine": 77, - "endColumn": 16, - "problem": "NumericSemantics", + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 78, - "column": 7, - "endLine": 78, - "endColumn": 16, - "problem": "NumericSemantics", + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 6, + "problem": "ArrayIndexExprType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, { - "line": 79, - "column": 7, - "endLine": 79, - "endColumn": 16, - "problem": "NumericSemantics", + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 8, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -574,6 +824,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 81, "column": 5, @@ -594,6 +854,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 82, + "column": 1, + "endLine": 82, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 82, "column": 5, @@ -614,6 +884,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 83, "column": 5, @@ -624,6 +904,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 84, + "column": 1, + "endLine": 84, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 84, "column": 5, @@ -644,6 +934,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 85, "column": 5, @@ -655,13 +955,13 @@ "severity": "ERROR" }, { - "line": 86, - "column": 7, - "endLine": 86, - "endColumn": 19, - "problem": "NumericSemantics", + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 8, + "problem": "IndexNegative", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, { @@ -669,9 +969,9 @@ "column": 1, "endLine": 87, "endColumn": 8, - "problem": "IndexNegative", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -688,7 +988,7 @@ "line": 88, "column": 5, "endLine": 88, - "endColumn": 7, + "endColumn": 17, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", @@ -704,11 +1004,21 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 89, + "column": 1, + "endLine": 89, + "endColumn": 18, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 89, "column": 5, "endLine": 89, - "endColumn": 7, + "endColumn": 17, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", @@ -728,7 +1038,7 @@ "line": 90, "column": 5, "endLine": 90, - "endColumn": 7, + "endColumn": 17, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", @@ -754,6 +1064,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 91, + "column": 1, + "endLine": 91, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 91, "column": 5, @@ -774,6 +1094,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 92, + "column": 1, + "endLine": 92, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 92, "column": 5, @@ -794,6 +1124,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 96, + "column": 11, + "endLine": 96, + "endColumn": 24, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 11, + "endLine": 97, + "endColumn": 25, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 97, "column": 15, @@ -805,13 +1155,13 @@ "severity": "ERROR" }, { - "line": 98, - "column": 7, - "endLine": 98, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 99, + "column": 1, + "endLine": 99, + "endColumn": 25, + "problem": "IndexNegative", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, { @@ -819,16 +1169,16 @@ "column": 1, "endLine": 99, "endColumn": 25, - "problem": "IndexNegative", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { "line": 99, "column": 5, "endLine": 99, - "endColumn": 14, + "endColumn": 24, "problem": "ArrayIndexExprType", "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", @@ -844,15 +1194,25 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 100, + "column": 1, + "endLine": 100, + "endColumn": 19, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 100, "column": 5, "endLine": 100, - "endColumn": 8, + "endColumn": 18, "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/indexable_type_string_element_access.ets.arkts2.json b/ets2panda/linter/test/main/indexable_type_string_element_access.ets.arkts2.json index 3ee4a5b916b47d5787d5176671a81ee4d5978def..ff51cef36a773f1b7d5fda1d53fa74e4fba2226a 100644 --- a/ets2panda/linter/test/main/indexable_type_string_element_access.ets.arkts2.json +++ b/ets2panda/linter/test/main/indexable_type_string_element_access.ets.arkts2.json @@ -1,17 +1,17 @@ { - "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": [] + "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": [] } \ 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 87714d54f82072b210a623c6c869a8d9e97c02d5..956e059371053b2395b2cfbbd8831ead5f8e9d03 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_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": [ { @@ -51,7 +51,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 18, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AnimatableExtend\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 44, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ImageFit\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 513f949766dacafdf5f6beeaa36e365041a64ab1..3ce807580e9f9f40ad000ac8610f50143cd32368 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 1099, "end": 1169, - "replacementText": "function cardStyle(this: TextAttribute): this {\n this.backgroundColor(Color.Green);\n return this;\n}" + "replacementText": "function cardStyle(this: TextAttribute): this {\n this.backgroundColor(Color.Green);\n return this;\n}", + "line": 60, + "column": 1, + "endLine": 64, + "endColumn": 2 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 1171, "end": 1256, - "replacementText": "@AnimatableExtend\nfunction animatableWidth(this: ColumnAttribute, width: number): this {\n this.width(width);\n return this;\n}" + "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": "", @@ -58,7 +66,11 @@ { "start": 1374, "end": 1386, - "replacementText": "$$(this.value)" + "replacementText": "$$(this.value)", + "line": 78, + "column": 16, + "endLine": 78, + "endColumn": 28 } ], "suggest": "", @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -194,11 +234,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,11 +255,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -228,11 +276,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -245,11 +297,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AnimatableExtend\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -262,11 +318,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -279,11 +339,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -296,11 +360,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -313,11 +381,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Column,\n Button,\n Text,\n Row,\n TextAttribute,\n ColumnAttribute,\n AnimatableExtend,\n $$,\n ImageFit,\n} from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ImageFit\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets index 231baa7371468bade2ef853c22cb7a7ec5896f61..4de0a5c1cd530676488e1199a730e20ac5413f40 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets @@ -13,7 +13,20 @@ * limitations under the License. */ -import { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; +import { + Entry, + Component, + State, + Column, + Button, + Text, + Row, + TextAttribute, + ColumnAttribute, + AnimatableExtend, + $$, + ImageFit, +} from '@kit.ArkUI'; import { Slider } from '@kit.ArkUI'; diff --git a/ets2panda/linter/test/main/interface_import_1.ets.migrate.json b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json index 400a3c703388b6e748b41fa890330385a7a325eb..8ca1591553b3150223d78104f3bd62418c040b33 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.migrate.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 63, + "line": 76, "column": 5, - "endLine": 63, + "endLine": 76, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 64, + "line": 77, "column": 12, - "endLine": 64, + "endLine": 77, "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 75, "column": 20, - "endLine": 62, + "endLine": 75, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 75, "column": 42, - "endLine": 62, + "endLine": 75, "endColumn": 46, "problem": "ThisType", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 82, "column": 5, - "endLine": 69, + "endLine": 82, "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 83, "column": 12, - "endLine": 70, + "endLine": 83, "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 81, "column": 26, - "endLine": 68, + "endLine": 81, "endColumn": 30, "problem": "InvalidIdentifier", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 81, "column": 65, - "endLine": 68, + "endLine": 81, "endColumn": 69, "problem": "ThisType", "suggest": "", 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 0d9966599128787081762a3b3ab7f609e6608a85..400a3c703388b6e748b41fa890330385a7a325eb 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_2.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": [ { 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 0d9966599128787081762a3b3ab7f609e6608a85..400a3c703388b6e748b41fa890330385a7a325eb 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_2.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": [ { 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..25c9d87c31b708f6f58b4c50a65d13f141a662ba --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.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 { A } from './har' +import { common2D } from '@kit.ArkGraphics2D' +import Base from '@ohos.base' +import { window } from '@kit.ArkUI' + +A.getContext() + +A.b.getContext() + +A.getInstance().getContext() + +let a: A = new A() +a.c.getContext() + +let c = a.c +c.getContext() + +const err = (err: Base.BusinessError) => {} + +export const DEFAULT_WINDOW_SIZE: window.size = { width: 1280, height: 2580} + +function test (aa: common2D.Rect) { + +} + +@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/interface_import_3.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..920f9c505447220bff7a5fef6a9dd4ea0532099f --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.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": 27, + "column": 16, + "endLine": 27, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 2, + "endLine": 41, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 2, + "endLine": 42, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets.autofix.json b/ets2panda/linter/test/main/interface_import_3.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..cbdc19234f78327742f5b84760525076a97d3b2a --- /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": 27, + "column": 16, + "endLine": 27, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 2, + "endLine": 41, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n} from '@kit.ArkUI';", + "line": 42, + "column": 2, + "endLine": 42, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 2, + "endLine": 42, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n} from '@kit.ArkUI';", + "line": 42, + "column": 2, + "endLine": 42, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets.json b/ets2panda/linter/test/main/interface_import_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..3f72a0ba0e104768d18f6c7ba5e609cc2ffedcb8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.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": 30, + "column": 5, + "endLine": 30, + "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_import_3.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d876eb34a8129586070a7f81490ce1df6ed02fc --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.ets.migrate.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. + */ + +import { + Entry, + Component, +} from '@kit.ArkUI'; + +import { A } from './har' +import { common2D } from '@kit.ArkGraphics2D' +import Base from '@ohos.base' +import { window } from '@kit.ArkUI' + +A.getContext() + +A.b.getContext() + +A.getInstance().getContext() + +let a: A = new A() +a.c.getContext() + +let c = a.c +c.getContext() + +const err = (err: Base.BusinessError) => {} + +export const DEFAULT_WINDOW_SIZE: window.size = { width: 1280, height: 2580} + +function test (aa: common2D.Rect) { + +} + +@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..6d584ff1e5f4e9b7a2f9339e2da77e57236215f2 --- /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": 32, + "column": 16, + "endLine": 32, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "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_import_4.ets b/ets2panda/linter/test/main/interface_import_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..f682328f82a92eea9dccb7b40c33e4dc1aa10b23 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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. + */ + +@Entry +@ComponentV2 +struct MyComponent { + @Local arr: Array = []; + scroller: Scroller = new Scroller(); + build() { + Column({ space: 5 }) { + List({ scroller: this.scroller, space: 5, initialIndex: 100 }) { + Repeat(this.arr) + .virtualScroll({ + onTotalCount: () => { return 1000; }, + onLazyLoading: (index: number) => { this.arr[index] = index.toString(); } + }) + .each((obj: RepeatItem) => { + ListItem() { + Row({ space: 5 }) { + Text(`${obj.index}: Item_${obj.item}`) + } + } + .height(50) + }) + } + .height('80%') + .border({ width: 1}) + Button('ScrollToIndex 500') + .onClick(() => { this.scroller.scrollToIndex(500); }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_4.ets.args.json b/ets2panda/linter/test/main/interface_import_4.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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/interface_import_4.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_4.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5c59a9d121c15797f3ccf9a250e9ebdbcbb93f49 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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": 20, + "column": 28, + "endLine": 20, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 58, + "endLine": 27, + "endColumn": 63, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 13, + "endLine": 20, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 15, + "endLine": 31, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 17, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_4.ets.autofix.json b/ets2panda/linter/test/main/interface_import_4.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..fd133473a339008ecfae2e7d750548292c2cd8fa --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.ets.autofix.json @@ -0,0 +1,322 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 28, + "endLine": 20, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 58, + "endLine": 27, + "endColumn": 63, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 988, + "end": 993, + "replacementText": "index as int", + "line": 27, + "column": 58, + "endLine": 27, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 13, + "endLine": 20, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 28, + "endLine": 20, + "endColumn": 36, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Scroller\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 15, + "endLine": 31, + "endColumn": 18, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 17, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Scroller,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Row,\n Text,\n Button,\n} from '@kit.ArkUI';", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_4.ets.json b/ets2panda/linter/test/main/interface_import_4.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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/interface_import_4.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..95d440370b7f89408e8b7a892a9464efaf1c9a49 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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. + */ + +import { + Entry, + ComponentV2, + Local, + Scroller, + Column, + List, + Repeat, + RepeatItem, + ListItem, + Row, + Text, + Button, +} from '@kit.ArkUI'; + +@Entry +@ComponentV2 +struct MyComponent { + @Local arr: Array = []; + scroller: Scroller = new Scroller(); + build() { + Column({ space: 5 }) { + List({ scroller: this.scroller, space: 5, initialIndex: 100 }) { + Repeat(this.arr) + .virtualScroll({ + onTotalCount: () => { return 1000; }, + onLazyLoading: (index: number) => { this.arr[index as int] = index.toString(); } + }) + .each((obj: RepeatItem) => { + ListItem() { + Row({ space: 5 }) { + Text(`${obj.index}: Item_${obj.item}`) + } + } + .height(50) + }) + } + .height('80%') + .border({ width: 1}) + Button('ScrollToIndex 500') + .onClick(() => { this.scroller.scrollToIndex(500); }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_4.ets.migrate.json b/ets2panda/linter/test/main/interface_import_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..eef4db12d77a80521f674d8c624e23a2a2fcfb83 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_4.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": 35, + "column": 28, + "endLine": 35, + "endColumn": 36, + "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/interface_import_5.ets b/ets2panda/linter/test/main/interface_import_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..40a37c6d1f71b41c2537a5c7757a3427b1046d14 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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. + */ + +import * from './ui_modules/common'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + // 建议使用this.getUIContext().getHostContext() + let context: Context = getContext(this) as Context; + console.info("CacheDir:" + context.cacheDir); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.args.json b/ets2panda/linter/test/main/interface_import_5.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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/interface_import_5.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_5.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..b4edf8e90e240f0761d955582924ef7750775d1e --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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": 31, + "column": 36, + "endLine": 31, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "suggest": "", + "rule": "The ArkUI interface \"getContext\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"FontWeight\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 26, + "endLine": 31, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.autofix.json b/ets2panda/linter/test/main/interface_import_5.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..1970edd683aaaf7c875bb889ae0ce4fb398de6bd --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.autofix.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": 31, + "column": 36, + "endLine": 31, + "endColumn": 46, + "problem": "NoDeprecatedApi", + "autofix": [ + { + "start": 967, + "end": 977, + "replacementText": "getUIContext().getHostContext", + "line": 31, + "column": 36, + "endLine": 31, + "endColumn": 46 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"getContext\" is deprecated (arkui-deprecated-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"FontWeight\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 26, + "endLine": 31, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Column,\n Text,\n FontWeight,\n Context,\n getUIContext,\n} from '@kit.ArkUI';", + "line": 31, + "column": 56, + "endLine": 31, + "endColumn": 63 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Context\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.json b/ets2panda/linter/test/main/interface_import_5.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.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/interface_import_5.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..577c9eb653c860c85e1bd3fc30815c63857367ec --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_5.ets.migrate.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. + */ + +import { + Entry, + Component, + State, + Row, + Column, + Text, + FontWeight, + Context, + getUIContext, +} from '@kit.ArkUI'; + +import * from './ui_modules/common'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + // 建议使用this.getUIContext().getHostContext() + let context: Context = getUIContext().getHostContext(this) as Context; + console.info("CacheDir:" + context.cacheDir); + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_5.ets.migrate.json b/ets2panda/linter/test/main/interface_import_5.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_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/main/interface_import_6.ets b/ets2panda/linter/test/main/interface_import_6.ets new file mode 100644 index 0000000000000000000000000000000000000000..881ce6f547293ab3c1f848db7110a638a395f6b5 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_6.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 { Component } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_6.ets.args.json b/ets2panda/linter/test/main/interface_import_6.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_6.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/interface_import_6.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_6.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f1ac486b52d8c95fb776d58d1c2ece99587b9350 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_6.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json b/ets2panda/linter/test/main/interface_import_6.ets.autofix.json similarity index 58% rename from ets2panda/linter/test/main/debugger_statememt.ets.autofix.json rename to ets2panda/linter/test/main/interface_import_6.ets.autofix.json index 6c9d73e3d1b95d4073a99e0e9c4d36a103b55faa..2b63a553ae7dc31a08d2a9ee40d58b06a45934a5 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_6.ets.autofix.json @@ -15,37 +15,34 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 1, - "endLine": 16, - "endColumn": 10, - "problem": "DebuggerStatement", - "autofix": [ - { - "start": 605, - "end": 614, - "replacementText": "specialAutofixLib.debugger();" - } - ], + "endLine": 17, + "endColumn": 40, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "\"debugger\" is not supported (arkts-no-debugger-stmt)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { "line": 19, - "column": 3, + "column": 2, "endLine": 19, - "endColumn": 12, - "problem": "DebuggerStatement", + "endColumn": 7, + "problem": "UIInterfaceImport", "autofix": [ { - "start": 633, - "end": 642, - "replacementText": "specialAutofixLib.debugger();" + "start": 617, + "end": 617, + "replacementText": "\nimport { Entry } from '@kit.ArkUI';\n", + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 7 } ], "suggest": "", - "rule": "\"debugger\" is not supported (arkts-no-debugger-stmt)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/interface_import_6.ets.json b/ets2panda/linter/test/main/interface_import_6.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..0cdb08cc16ad1879ae83bcc575e2f6feb7e672d0 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_6.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": 40, + "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/runtime/ets/InterfaceInBlock.ets b/ets2panda/linter/test/main/interface_import_6.ets.migrate.ets similarity index 81% rename from ets2panda/test/runtime/ets/InterfaceInBlock.ets rename to ets2panda/linter/test/main/interface_import_6.ets.migrate.ets index 0674863ac13521b61981c34f706003060699c344..12599d4583df8e7fe2e9943190b127aace0c7dd7 100644 --- a/ets2panda/test/runtime/ets/InterfaceInBlock.ets +++ b/ets2panda/linter/test/main/interface_import_6.ets.migrate.ets @@ -13,19 +13,14 @@ * limitations under the License. */ -{ - interface I - { - foo(): int; - } +'use static' +import { Entry } from '@kit.ArkUI'; - class C implements I - { - foo(): int - { - return 1; - } - } +import { Component } from '@kit.ArkUI'; - assertEQ(new C().foo(), 1); +@Entry +@Component +struct Index { + build() { + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_6.ets.migrate.json b/ets2panda/linter/test/main/interface_import_6.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..93115465bb027e2868e67d2c0ed6c9b73278a496 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_6.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": 1, + "endLine": 17, + "endColumn": 36, + "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": 40, + "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/main/interface_literal_prop_name.ets.json b/ets2panda/linter/test/main/interface_literal_prop_name.ets.json index 6f68e19f773c93b033612ff79f18344ec936e933..323f3bdc20e445983761bdf23353290c1e3434ae 100644 --- a/ets2panda/linter/test/main/interface_literal_prop_name.ets.json +++ b/ets2panda/linter/test/main/interface_literal_prop_name.ets.json @@ -34,6 +34,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 31, + "column": 3, + "endLine": 31, + "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": 36, "column": 3, @@ -44,6 +54,26 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 37, + "column": 3, + "endLine": 37, + "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": 38, + "column": 3, + "endLine": 38, + "endColumn": 7, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, { "line": 43, "column": 10, @@ -64,6 +94,26 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 51, + "column": 3, + "endLine": 51, + "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": 52, + "column": 3, + "endLine": 52, + "endColumn": 7, + "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, @@ -73,6 +123,16 @@ "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, + "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/main/invalid_identifier.ets b/ets2panda/linter/test/main/invalid_identifier.ets index ade4397a201e9ff3aded49ca7fd2e9fdad73c859..82e23b2d2bd06ea3a9dfa779fc3e2d291360966d 100755 --- a/ets2panda/linter/test/main/invalid_identifier.ets +++ b/ets2panda/linter/test/main/invalid_identifier.ets @@ -85,7 +85,7 @@ const implements: string = "implements"; const protected: string = "protected"; -const public: string = "public"; +const public: string = "public"; const do: string = "do" @@ -134,11 +134,11 @@ const string: string = "hello"; const void: void = undefined; class String { - + private const: string = "const"; string: string = "hello"; - + constructor(string: string) { } @@ -218,4 +218,36 @@ namespace quarantine { interface test { int: int } -} \ No newline at end of file +} +class StringBuilder { +} + +class Map { +} + +let _if = null; +let _import = null; +let _export = null; +let _await = null; +let _arguments = null; +let _eval = null; +let _default = null; +let _as = null; + +export { +_if as if, +_import as import, +_export as export, +_await as await, +_arguments as arguments, +_eval as eval, +_default as default, +_as as as +}; + +let a = 1; + +let records: Record[] = []; + +records.forEach(Map => {}) +records.forEach(json => {}) diff --git a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json index 39bd99fe344bb3e011839b8bc6d1dfb9bc88ae56..1041e601a3396c117f143ef890f32646efd22f85 100644 --- a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json +++ b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json @@ -1,818 +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 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": 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": 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" - } - ] + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 16, + "column": 1, + "endLine": 16, + "endColumn": 56, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "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": 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": 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": 222, + "column": 7, + "endLine": 222, + "endColumn": 20, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 7, + "endLine": 225, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 8, + "endLine": 238, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 239, + "column": 12, + "endLine": 239, + "endColumn": 18, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 240, + "column": 12, + "endLine": 240, + "endColumn": 18, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 241, + "column": 11, + "endLine": 241, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 242, + "column": 15, + "endLine": 242, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 10, + "endLine": 243, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 13, + "endLine": 244, + "endColumn": 20, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 8, + "endLine": 245, + "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": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 2, + "endLine": 173, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 4, + "endLine": 175, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 5, + "endLine": 181, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RelativeContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 7, + "endLine": 182, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 4, + "endLine": 194, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 5, + "endLine": 197, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RelativeContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 7, + "endLine": 198, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets b/ets2panda/linter/test/main/large_numeric_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..d18e4f7ba65c4fd6e2c483169824c4cfc2226e59 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.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. + */ + + Test large number literal rule +// These should be detected as errors + +// Large number literals beyond 2^63 - 1 to -2^63 range +const tooLargePositive = 9223372036854775808; // Error: exceeds 2^63 - 1 +const tooLargeNegative = -9223372036854775809; // Error: below -2^63 + +// Edge cases - these should not report errors +const maxAllowedPositive = 9223372036854775807; // Correct: exactly 2^63 - 1 +const maxAllowedNegative = -9223372036854775808; // Correct: exactly -2^63 + +// Normal numbers - these should not report errors +const normalPositive = 1000000; +const normalNegative = -1000000; +const zero = 0; + +// Large but acceptable numbers +const largeButOk = 9223372036854775800; // Correct: within range +const largeButOkNegative = -9223372036854775800; // Correct: within range + +// Function parameters +function processLargeNumber( + value: number = 9223372036854775808 // Error: exceeds 2^63 - 1 +): void { + console.log(value); +} + +// Interface property +interface DataConfig { + maxValue: number; // This will be checked when assigned +} + +// Variable assignment +let config: DataConfig = { + maxValue: 9223372036854775808 // Error: exceeds 2^63 - 1 +}; + +// Array literal +const largeNumbers = [ + 9223372036854775808, // Error: exceeds 2^63 - 1 + -9223372036854775809, // Error: below -2^63 + 1000, // Correct: normal number + 9223372036854775807 // Correct: exactly at limit +]; + +// Object literal +const settings = { + threshold: 9223372036854775808, // Error: exceeds 2^63 - 1 + limit: 9223372036854775807 // Correct: exactly at limit +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.args.json b/ets2panda/linter/test/main/large_numeric_literal.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..75871d1cccc83c3d929dc8fd35e9246ec8c7f5e1 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.args.json @@ -0,0 +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." + ], + "mode": { + "arkts2": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json b/ets2panda/linter/test/main/large_numeric_literal.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..c3520de6621ed2f151fbd60d8ef9f7341ecab436 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.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": 20, + "column": 26, + "endLine": 20, + "endColumn": 45, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 27, + "endLine": 21, + "endColumn": 46, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 28, + "endLine": 24, + "endColumn": 47, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 29, + "endLine": 25, + "endColumn": 48, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 39, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 29, + "endLine": 34, + "endColumn": 48, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 19, + "endLine": 38, + "endColumn": 38, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 32, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 3, + "endLine": 55, + "endColumn": 22, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 4, + "endLine": 56, + "endColumn": 23, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 22, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 18, + "endLine": 62, + "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": 63, + "column": 14, + "endLine": 63, + "endColumn": 33, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 10, + "endLine": 64, + "endColumn": 29, + "problem": "LongNumeric", + "suggest": "", + "rule": "Numeric value literals outside of integer range require long representation (arkts-use-long-for-large-numeric-literal)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 6, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Test\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/large_numeric_literal.ets.json b/ets2panda/linter/test/main/large_numeric_literal.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..24907755d1a4c23d07017f317b33a03e7f3e1ea1 --- /dev/null +++ b/ets2panda/linter/test/main/large_numeric_literal.ets.json @@ -0,0 +1,28 @@ +{ + "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": 62, + "column": 18, + "endLine": 62, + "endColumn": 19, + "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/lazy_import.ets b/ets2panda/linter/test/main/lazy_import.ets index a40b832b4fe0f040cf84a16ef13b9c7c58dc08a3..86bb429ac0f4e8a039b0eed5e84b8a25fd470943 100755 --- a/ets2panda/linter/test/main/lazy_import.ets +++ b/ets2panda/linter/test/main/lazy_import.ets @@ -17,3 +17,21 @@ import lazy { m } from 'module' import lazy { a, b } from 'module1' import { c } from 'module2' + +import lazy {worker} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import lazy {harTest} from "har1" // (arkts-no-lazy-import) + +import lazy {add} from "hsp1" // (arkts-no-lazy-import) + +/* test */ import lazy {WorkerEventListener} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import /* test */ lazy {WorkerEventTarget} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ lazy /* test */ {WorkerOptions} /* test */ from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import lazy {worker as wk} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ +lazy // (arkts-no-lazy-import) +/* test */ {worker as ttt} /* test */ from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.args.json b/ets2panda/linter/test/main/lazy_import.ets.args.json index aaabef1e0a30f23f303a3fcf12ad9bd1973f6aa0..8186a08902bd23b8298befe95fff67730ddf50ab 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.args.json +++ b/ets2panda/linter/test/main/lazy_import.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json index bd0dee6544ca1c7f589ba627e4b38524d50d5777..083eb8318e68b812ea574f22f7674afac5d38818 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json +++ b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json @@ -33,6 +33,86 @@ "suggest": "", "rule": "Lazy import is not supported(arkts-no-lazy-import)", "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.autofix.json b/ets2panda/linter/test/main/lazy_import.ets.autofix.json index 765ce394d875c17c4ad49fe096ea073a84d6f57f..75ae26f1e384a702ba895a858118ccecadd728f2 100644 --- a/ets2panda/linter/test/main/lazy_import.ets.autofix.json +++ b/ets2panda/linter/test/main/lazy_import.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 612, "end": 622, - "replacementText": "{ m }" + "replacementText": "{ m }", + "line": 16, + "column": 8, + "endLine": 16, + "endColumn": 12 } ], "suggest": "", @@ -41,7 +45,179 @@ { "start": 645, "end": 658, - "replacementText": "{ a, b }" + "replacementText": "{ a, b }", + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 710, + "end": 723, + "replacementText": "{worker}", + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 779, + "end": 793, + "replacementText": "{harTest}", + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 840, + "end": 850, + "replacementText": "{add}", + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 908, + "end": 934, + "replacementText": "{WorkerEventListener}", + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 999, + "end": 1023, + "replacementText": "{WorkerEventTarget}", + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1100, + "end": 1132, + "replacementText": "/* test */ {WorkerOptions}", + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1198, + "end": 1217, + "replacementText": "{worker as wk}", + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1293, + "end": 1355, + "replacementText": "// (arkts-no-lazy-import)\n/* test */ {worker as ttt}", + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/lazy_import.ets.migrate.ets b/ets2panda/linter/test/main/lazy_import.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c02388768ffdf4e8f1473ab75e2a2fef6cc9029 --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.migrate.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { m } from 'module' + +import { a, b } from 'module1' +import { c } from 'module2' + +import {worker} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import {harTest} from "har1" // (arkts-no-lazy-import) + +import {add} from "hsp1" // (arkts-no-lazy-import) + +/* test */ import {WorkerEventListener} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import /* test */ {WorkerEventTarget} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ /* test */ {WorkerOptions} /* test */ from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import {worker as wk} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ +// (arkts-no-lazy-import) +/* test */ {worker as ttt} /* test */ from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.migrate.json b/ets2panda/linter/test/main/lazy_import.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/limit_void_type.ets b/ets2panda/linter/test/main/limit_void_type.ets index d6ae5d427f0946f89ddb7962cda23e30a91be021..3dc13d8696c499bade5e2c1757b85042f991f59d 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets +++ b/ets2panda/linter/test/main/limit_void_type.ets @@ -13,50 +13,50 @@ * limitations under the License. */ - +import {unionVoidVal,undefinedFooFun,func3Void,fun4undefined,fun5String} from './limit_void_type2' // Example 1: Basic function -function func1(): void {} +function func1(): void { } let a: void = func1(); // Example 2: Arrow function -const func2 = (): void => {}; +const func2 = (): void => { }; let b: void = func2(); // Example 3: Class method class Demo { - method(): void {} + method(): void { } } let c: void = new Demo().method(); // Example 4: Immediately Invoked Function Expression (IIFE) -let d: void = (function(): void {})(); +let d: void = (function (): void { })(); // Example 5: Asynchronous function -async function asyncFunc(): Promise {} +async function asyncFunc(): Promise { } let e: void = await asyncFunc(); // Example 6: Function parameter function wrapper(fn: () => void) { let f: void = fn(); } // Example 7: Type assertion -function func3(): void {} +function func3(): void { } let g: void = func3() as void; // Example 8: Callback function -setTimeout((): void => {}, 1000); -let h: void = setTimeout(() => {}, 1000); +setTimeout((): void => { }, 1000); +let h: void = setTimeout(() => { }, 1000); // Example 9: Array operation -const funcArr: (() => void)[] = [() => {}]; +const funcArr: (() => void)[] = [() => { }]; let i: void = funcArr[0](); // Example 10: Object method const obj = { - action: (): void => {} + action: (): void => { } }; let j: void = obj.action(); // Example 11: Strict mode // @ts-strict -function func4(): void {} +function func4(): void { } let k: void = func4(); // Example 12: Module export -export function exportedFunc(): void {} +export function exportedFunc(): void { } let l: void = exportedFunc(); // Example 13: Generic function -function genericFunc(): void {} +function genericFunc(): void { } let m: void = genericFunc(); // Example 14: Function overloading function overloadFunc(): void; @@ -65,24 +65,24 @@ function overloadFunc(n?: number) { return n; } let n: void = overloadFunc(); // Example 15: Type alias type VoidFunc = () => void; -const aliasFunc: VoidFunc = () => {}; +const aliasFunc: VoidFunc = () => { }; let o: void = aliasFunc(); // Example 16: Interface implementation interface Task { run(): void; } class Printer implements Task { - run(): void {} + run(): void { } } let p: void = new Printer().run(); // Example 17: Optional parameter -function withParam(param?: string): void {} +function withParam(param?: string): void { } let q: void = withParam(); // Example 18: Rest parameter -function sum(...nums: number[]): void {} +function sum(...nums: number[]): void { } let r: void = sum(1, 2, 3); // Example 19: This parameter -function withThis(this: Window): void {} +function withThis(this: Window): void { } let s: void = withThis.call(window); // Example 20: Generator function function* genFunc(): Generator { @@ -90,31 +90,31 @@ function* genFunc(): Generator { } let u: void = genFunc().next().value; // Example 21: Function currying -const curry = () => (): void => {}; +const curry = () => (): void => { }; let w: void = curry()(); // Example 22: Method chaining class Chain { first(): this { return this; } - last(): void {} + last(): void { } } let x: void = new Chain().first().last(); // Example 23: Destructuring assignment -const [func] = [(): void => {}]; +const [func] = [(): void => { }]; let y: void = func(); // Example 24: Type mapping type Wrapper = { value: T }; -const wrapped: Wrapper<() => void> = { value: () => {} }; +const wrapped: Wrapper<() => void> = { value: () => { } }; let z: void = wrapped.value(); // Example 25: Conditional type type Conditional = T extends boolean ? () => void : never; -const condFunc: Conditional = () => {}; +const condFunc: Conditional = () => { }; let aa: void = condFunc(); // Example 26: Mixed type interface Mixed { (): void; prop: string; } -const mixed: Mixed = Object.assign(() => {}, { prop: "" }); +const mixed: Mixed = Object.assign(() => { }, { prop: "" }); let ab: void = mixed(); // Example 27: Recursive call function recursive(): void { @@ -123,13 +123,13 @@ function recursive(): void { let ac: void = recursive(); // Example 28: Decorator function function decorator() { - return function(target: any) {}; + return function (target: any) { }; } @decorator() -class Decorated {} +class Decorated { } let ad: void = decorator()(Decorated); -function f1(): void {} +function f1(): void { } let a1 = f1(); // type `void` is used as value @@ -145,24 +145,24 @@ a3[0] = f1(); // type `void` is used as value let a4: void = f1(); // type `void` is used as type annotation -function f2(a: void) {} // type `void` is used as type annotation +function f2(a: void) { } // type `void` is used as type annotation f2(f1()); // type `void` is used as value class A { f: void; // type `void` is used as type annotation - m(p: void) {} // type `void` is used as type annotation + m(p: void) { } // type `void` is used as type annotation constructor(a: void) { // type `void` is used as type annotation this.f = a; } } -function f3(): void | Promise {} // type `void` is not allowed in union type +function f3(): void | Promise { } // type `void` is not allowed in union type class B { - m(): void | number {} // type `void` is not allowed in union type + m(): void | number { } // type `void` is not allowed in union type } type ss = void; @@ -178,20 +178,20 @@ interface BT { } class C { - private cc?:BT; + private cc?: BT; - private d():void { + private d(): void { this.cc = { - qaq: (caller?:string):void => this.qaqq(caller) + qaq: (caller?: string): void => this.qaqq(caller) } } - private qaqq(caller?:string):void { + private qaqq(caller?: string): void { return; } } -function foo(): void {} -function bar(): void {} +function foo(): void { } +function bar(): void { } let aa = '1'; let bb = aa === '1' ? foo() : bar(); // Error @@ -199,7 +199,167 @@ 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 +interface testB { + u: void; // Error + fooIf(): void; +} + +function foo1():void{ + return foo(); // No Error +} + +function foocfe(a: number): string | void { + if (a >= 0) { + return "a >= 0"; + } +} + +function foocfe2(a: number): string | void { + if (a < 0) { + return; + } + return "a >= 0"; +} +function fooefc(): void { } +let ss: void = foo() +let t: void | number = foo() +let t2: void | number = 1; + +function greet(hour: number): string | void { + if (hour < 12) { + return; + } else if (hour < 18) { + return "Good afternoon"; + } else { + return; + } +} + +function logOrReturn(flag: boolean): string | void { + if (flag) { + return "Flag is true"; + } + console.log("Flag is false"); + return; +} + +function justLogs(): string | void { + console.log("Hello!"); +} + +function getStatus(code: number): string | void { + switch (code) { + case 1: return "OK"; + case 2: return "Warning"; + } +} + +function tryThing(): string | void { + try { + return "Worked!"; + } catch (e) { + console.error(e); + } +} + +class A1 { + // test + aa?: boolean | void + + test(a: number): boolean | void { + if (a > 0) { + // will return + return; + } + // will return + return; + } + + test1(a: number): void | boolean { + if (a > 0) { + // will return + return true; + } + // will return + return; + } + + test2(a: number): void | boolean { + if (a > 0) { + // will return + return; + } + } + + test3(a: number): void | boolean { + if (a > 0) { + // will return + return; + } + return false; + } + + test4(): void | boolean { + // will return + } +} + +function test(a: number): boolean | void { + if (a > 0) { + // will return + return; + } + // will return + return; +} + +function test1(a: number): void | boolean { + if (a > 0) { + // will return + return true; + } + // will return + return; +} + +function test2(a: number): void | boolean { + if (a > 0) { + // will return + return; + } +} + +function test3(a: number): void | boolean { + if (a > 0) { + // will return + return; + } + return false; +} + +function test4(a: number): void | boolean { + // will return +} + +let unionVoid = (()=>{ + return undefined; +})() as void; //error +function undefinedFoo(){ + return undefined; +} +function unionFoo(): undefined | boolean{ + return undefined; +} +let asVoidFun = undefinedFoo() as void; //error +let undefinedAsVoid = undefined as void; //error +let unionFooAsVoid = unionFoo() as void; //error + +function func6() { + return undefined as void; //error +} + +let exportAsVoidFun = unionVoidVal as void; +let exportUndefinedFooFun = undefinedFooFun() as void; //error +let exportfunc3Void = func3Void() as void; //error +console.log(fun5String() as void); +typeof (fun4undefined() as void) //error diff --git a/ets2panda/linter/test/main/limit_void_type.ets.args.json b/ets2panda/linter/test/main/limit_void_type.ets.args.json index 948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.args.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.args.json @@ -1,19 +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": "" - } + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT 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/limit_void_type.ets.arkts2.json b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json index 3555b90375b19e0340c6444b89dabd0d60507238..fb694d6a8054da14a38410731c1e6ef82d22697e 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json @@ -88,7 +88,7 @@ "line": 29, "column": 15, "endLine": 29, - "endColumn": 38, + "endColumn": 40, "problem": "LimitedVoidType", "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", @@ -98,7 +98,7 @@ "line": 29, "column": 16, "endLine": 29, - "endColumn": 35, + "endColumn": 37, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", @@ -144,6 +144,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 39, + "column": 26, + "endLine": 39, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 39, "column": 15, @@ -184,6 +194,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 45, + "column": 15, + "endLine": 45, + "endColumn": 25, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 47, "column": 13, @@ -479,9 +499,9 @@ "column": 15, "endLine": 91, "endColumn": 37, - "problem": "AvoidUnionTypes", + "problem": "BuiltinIteratorResultValue", "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", "severity": "ERROR" }, { @@ -538,7 +558,7 @@ "line": 102, "column": 7, "endLine": 102, - "endColumn": 32, + "endColumn": 33, "problem": "DestructuringDeclaration", "suggest": "", "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", @@ -656,9 +676,9 @@ }, { "line": 117, - "column": 46, + "column": 47, "endLine": 117, - "endColumn": 47, + "endColumn": 48, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", @@ -718,7 +738,7 @@ "line": 126, "column": 10, "endLine": 126, - "endColumn": 34, + "endColumn": 36, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", @@ -726,9 +746,9 @@ }, { "line": 126, - "column": 27, + "column": 28, "endLine": 126, - "endColumn": 30, + "endColumn": 31, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -834,6 +854,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 144, + "column": 1, + "endLine": 144, + "endColumn": 6, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, { "line": 144, "column": 9, @@ -914,6 +944,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 162, + "column": 16, + "endLine": 162, + "endColumn": 36, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 162, "column": 16, @@ -924,6 +964,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 165, "column": 8, @@ -934,6 +984,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 168, + "column": 6, + "endLine": 168, + "endColumn": 8, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, { "line": 168, "column": 11, @@ -1016,9 +1076,559 @@ }, { "line": 203, - "column": 5, + "column": 6, "endLine": 203, - "endColumn": 9, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 29, + "endLine": 211, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 38, + "endLine": 211, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 30, + "endLine": 217, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 39, + "endLine": 217, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 5, + "endLine": 224, + "endColumn": 7, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 9, + "endLine": 224, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 16, + "endLine": 224, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 8, + "endLine": 225, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 8, + "endLine": 225, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 24, + "endLine": 225, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 40, + "endLine": 228, + "endColumn": 44, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 38, + "endLine": 238, + "endColumn": 51, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 47, + "endLine": 238, + "endColumn": 51, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 22, + "endLine": 246, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 31, + "endLine": 246, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 250, + "column": 35, + "endLine": 250, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 250, + "column": 44, + "endLine": 250, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 22, + "endLine": 257, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 31, + "endLine": 257, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 8, + "endLine": 267, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 18, + "endLine": 267, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 269, + "column": 20, + "endLine": 269, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 269, + "column": 30, + "endLine": 269, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 16, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 27, + "endLine": 307, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 37, + "endLine": 307, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 346, + "column": 9, + "endLine": 346, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 353, + "column": 35, + "endLine": 353, + "endColumn": 39, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 354, + "column": 36, + "endLine": 354, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 355, + "column": 36, + "endLine": 355, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 358, + "column": 23, + "endLine": 358, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 39, + "endLine": 361, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 362, + "column": 50, + "endLine": 362, + "endColumn": 54, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 38, + "endLine": 363, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 23, + "endLine": 363, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 29, + "endLine": 364, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 365, + "column": 28, + "endLine": 365, + "endColumn": 32, "problem": "LimitedVoidType", "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", diff --git a/ets2panda/linter/test/main/limit_void_type.ets.autofix.json b/ets2panda/linter/test/main/limit_void_type.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..1d193402460bed0b8e90b42435c4de9ecb4538d0 --- /dev/null +++ b/ets2panda/linter/test/main/limit_void_type.ets.autofix.json @@ -0,0 +1,2125 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 8, + "endLine": 19, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 15, + "endLine": 19, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 8, + "endLine": 22, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 16, + "endLine": 29, + "endColumn": 37, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 1040, + "end": 1061, + "replacementText": "(): void => { }", + "line": 29, + "column": 16, + "endLine": 29, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 10, + "endLine": 35, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 26, + "endLine": 39, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 15, + "endLine": 39, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 8, + "endLine": 45, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 15, + "endLine": 45, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 15, + "endLine": 45, + "endColumn": 25, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 13, + "endLine": 47, + "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": 8, + "endLine": 50, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 8, + "endLine": 54, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 8, + "endLine": 57, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 15, + "endLine": 57, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 8, + "endLine": 60, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 15, + "endLine": 60, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 15, + "endLine": 60, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 62, + "endColumn": 31, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 42, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 48, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 8, + "endLine": 65, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 15, + "endLine": 65, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 15, + "endLine": 69, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 8, + "endLine": 77, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 15, + "endLine": 77, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 8, + "endLine": 80, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 15, + "endLine": 80, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 8, + "endLine": 83, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 15, + "endLine": 83, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 19, + "endLine": 85, + "endColumn": 23, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 8, + "endLine": 86, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 24, + "endLine": 86, + "endColumn": 28, + "problem": "FunctionApplyCall", + "suggest": "", + "rule": "'Function.apply', 'Function.call' are not supported (arkts-no-func-apply-call)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 90, + "endColumn": 2, + "problem": "GeneratorFunction", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 3, + "endLine": 89, + "endColumn": 8, + "problem": "YieldExpression", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 8, + "endLine": 91, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 15, + "endLine": 91, + "endColumn": 37, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 8, + "endLine": 94, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 15, + "endLine": 94, + "endColumn": 24, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 12, + "endLine": 97, + "endColumn": 16, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 8, + "endLine": 100, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 15, + "endLine": 100, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 7, + "endLine": 102, + "endColumn": 33, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "GeneratedDestructArray_1", + "start": 3148, + "end": 3154, + "line": 102, + "column": 7, + "endLine": 102, + "endColumn": 33 + }, + { + "replacementText": "\nconst func = GeneratedDestructArray_1[0];\n", + "start": 3175, + "end": 3175, + "line": 102, + "column": 7, + "endLine": 102, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 8, + "endLine": 103, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 15, + "endLine": 103, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 19, + "endLine": 105, + "endColumn": 20, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 3226, + "end": 3257, + "replacementText": "interface Wrapper {\n value: T;\n}", + "line": 105, + "column": 19, + "endLine": 105, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 38, + "endLine": 106, + "endColumn": 39, + "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": 8, + "endLine": 107, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 15, + "endLine": 107, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 23, + "endLine": 109, + "endColumn": 61, + "problem": "ConditionalType", + "suggest": "", + "rule": "Conditional types are not supported (arkts-no-conditional-types)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 9, + "endLine": 111, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 16, + "endLine": 111, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 12, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 29, + "endLine": 117, + "endColumn": 35, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 47, + "endLine": 117, + "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": 118, + "column": 9, + "endLine": 118, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 23, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 10, + "endLine": 121, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 9, + "endLine": 123, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 16, + "endLine": 123, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 10, + "endLine": 126, + "endColumn": 36, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 3855, + "end": 3881, + "replacementText": "(target: any) => { }", + "line": 126, + "column": 10, + "endLine": 126, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 28, + "endLine": 126, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 1, + "endLine": 128, + "endColumn": 13, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 9, + "endLine": 130, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 16, + "endLine": 130, + "endColumn": 38, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 28, + "endLine": 130, + "endColumn": 37, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 10, + "endLine": 134, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 6, + "endLine": 136, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 9, + "endLine": 138, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 9, + "endLine": 140, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 19, + "endLine": 140, + "endColumn": 23, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 7, + "endLine": 142, + "endColumn": 11, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 1, + "endLine": 144, + "endColumn": 6, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 9, + "endLine": 144, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 9, + "endLine": 146, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 16, + "endLine": 146, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 16, + "endLine": 148, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 4, + "endLine": 150, + "endColumn": 8, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 6, + "endLine": 153, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 8, + "endLine": 155, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 18, + "endLine": 157, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 16, + "endLine": 162, + "endColumn": 36, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 4697, + "end": 4717, + "replacementText": "undefined | Promise", + "line": 162, + "column": 16, + "endLine": 162, + "endColumn": 36 + }, + { + "start": 4720, + "end": 4720, + "replacementText": "\n return undefined;\n", + "line": 162, + "column": 16, + "endLine": 162, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 16, + "endLine": 162, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 21, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 4784, + "end": 4797, + "replacementText": "undefined | number", + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 21 + }, + { + "start": 4800, + "end": 4800, + "replacementText": "\n return undefined;\n ", + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 6, + "endLine": 168, + "endColumn": 8, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 11, + "endLine": 168, + "endColumn": 15, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 12, + "endLine": 169, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 22, + "endLine": 174, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "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": "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": 6, + "endLine": 203, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 29, + "endLine": 211, + "endColumn": 42, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 5530, + "end": 5543, + "replacementText": "string | undefined", + "line": 211, + "column": 29, + "endLine": 211, + "endColumn": 42 + }, + { + "start": 5586, + "end": 5586, + "replacementText": "\n return undefined;", + "line": 211, + "column": 29, + "endLine": 211, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 38, + "endLine": 211, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 30, + "endLine": 217, + "endColumn": 43, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 5619, + "end": 5632, + "replacementText": "string | undefined", + "line": 217, + "column": 30, + "endLine": 217, + "endColumn": 43 + }, + { + "start": 5654, + "end": 5661, + "replacementText": "return undefined;", + "line": 217, + "column": 30, + "endLine": 217, + "endColumn": 43 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 39, + "endLine": 217, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 5, + "endLine": 224, + "endColumn": 7, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 9, + "endLine": 224, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 16, + "endLine": 224, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 8, + "endLine": 225, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 8, + "endLine": 225, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 24, + "endLine": 225, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 5823, + "end": 5836, + "replacementText": "string | undefined", + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44 + }, + { + "start": 5862, + "end": 5869, + "replacementText": "return undefined;", + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44 + }, + { + "start": 5940, + "end": 5947, + "replacementText": "return undefined;", + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44 + }, + { + "start": 5951, + "end": 5951, + "replacementText": "\n return undefined;", + "line": 228, + "column": 31, + "endLine": 228, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 40, + "endLine": 228, + "endColumn": 44, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 38, + "endLine": 238, + "endColumn": 51, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 5992, + "end": 6005, + "replacementText": "string | undefined", + "line": 238, + "column": 38, + "endLine": 238, + "endColumn": 51 + }, + { + "start": 6087, + "end": 6094, + "replacementText": "return undefined;", + "line": 238, + "column": 38, + "endLine": 238, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 238, + "column": 47, + "endLine": 238, + "endColumn": 51, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 22, + "endLine": 246, + "endColumn": 35, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6119, + "end": 6132, + "replacementText": "string | undefined", + "line": 246, + "column": 22, + "endLine": 246, + "endColumn": 35 + }, + { + "start": 6159, + "end": 6159, + "replacementText": "\n return undefined;", + "line": 246, + "column": 22, + "endLine": 246, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 31, + "endLine": 246, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 250, + "column": 35, + "endLine": 250, + "endColumn": 48, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6197, + "end": 6210, + "replacementText": "string | undefined", + "line": 250, + "column": 35, + "endLine": 250, + "endColumn": 48 + }, + { + "start": 6289, + "end": 6289, + "replacementText": "\n return undefined;", + "line": 250, + "column": 35, + "endLine": 250, + "endColumn": 48 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 250, + "column": 44, + "endLine": 250, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 22, + "endLine": 257, + "endColumn": 35, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6314, + "end": 6327, + "replacementText": "string | undefined", + "line": 257, + "column": 22, + "endLine": 257, + "endColumn": 35 + }, + { + "start": 6401, + "end": 6401, + "replacementText": "\n return undefined;", + "line": 257, + "column": 22, + "endLine": 257, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 31, + "endLine": 257, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 8, + "endLine": 267, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 18, + "endLine": 267, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 269, + "column": 20, + "endLine": 269, + "endColumn": 34, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6468, + "end": 6482, + "replacementText": "boolean | undefined", + "line": 269, + "column": 20, + "endLine": 269, + "endColumn": 34 + }, + { + "start": 6529, + "end": 6536, + "replacementText": "return undefined;", + "line": 269, + "column": 20, + "endLine": 269, + "endColumn": 34 + }, + { + "start": 6566, + "end": 6573, + "replacementText": "return undefined;", + "line": 269, + "column": 20, + "endLine": 269, + "endColumn": 34 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 269, + "column": 30, + "endLine": 269, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 35, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6599, + "end": 6613, + "replacementText": "undefined | boolean", + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 35 + }, + { + "start": 6702, + "end": 6709, + "replacementText": "return undefined;", + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 21, + "endLine": 278, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 35, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6735, + "end": 6749, + "replacementText": "undefined | boolean", + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 35 + }, + { + "start": 6796, + "end": 6803, + "replacementText": "return undefined;", + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 35 + }, + { + "start": 6809, + "end": 6809, + "replacementText": "\n return undefined;", + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 21, + "endLine": 287, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 35, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6835, + "end": 6849, + "replacementText": "undefined | boolean", + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 35 + }, + { + "start": 6896, + "end": 6903, + "replacementText": "return undefined;", + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 21, + "endLine": 294, + "endColumn": 25, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 26, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 6944, + "end": 6958, + "replacementText": "undefined | boolean", + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 26 + }, + { + "start": 6982, + "end": 6982, + "replacementText": "\n return undefined;\n ", + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 12, + "endLine": 302, + "endColumn": 16, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 27, + "endLine": 307, + "endColumn": 41, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 7013, + "end": 7027, + "replacementText": "boolean | undefined", + "line": 307, + "column": 27, + "endLine": 307, + "endColumn": 41 + }, + { + "start": 7068, + "end": 7075, + "replacementText": "return undefined;", + "line": 307, + "column": 27, + "endLine": 307, + "endColumn": 41 + }, + { + "start": 7099, + "end": 7106, + "replacementText": "return undefined;", + "line": 307, + "column": 27, + "endLine": 307, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 37, + "endLine": 307, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 42, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 7137, + "end": 7151, + "replacementText": "undefined | boolean", + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 42 + }, + { + "start": 7228, + "end": 7235, + "replacementText": "return undefined;", + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 28, + "endLine": 316, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 42, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 7266, + "end": 7280, + "replacementText": "undefined | boolean", + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 42 + }, + { + "start": 7321, + "end": 7328, + "replacementText": "return undefined;", + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 42 + }, + { + "start": 7332, + "end": 7332, + "replacementText": "\n return undefined;", + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 28, + "endLine": 325, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 42, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 7363, + "end": 7377, + "replacementText": "undefined | boolean", + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 42 + }, + { + "start": 7418, + "end": 7425, + "replacementText": "return undefined;", + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 28, + "endLine": 332, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 42, + "problem": "LimitedVoidType", + "autofix": [ + { + "start": 7476, + "end": 7490, + "replacementText": "undefined | boolean", + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 42 + }, + { + "start": 7510, + "end": 7510, + "replacementText": "\n return undefined;\n", + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 340, + "column": 28, + "endLine": 340, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 346, + "column": 9, + "endLine": 346, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 353, + "column": 35, + "endLine": 353, + "endColumn": 39, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 354, + "column": 36, + "endLine": 354, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 355, + "column": 36, + "endLine": 355, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 358, + "column": 23, + "endLine": 358, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 39, + "endLine": 361, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 362, + "column": 50, + "endLine": 362, + "endColumn": 54, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 38, + "endLine": 363, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 23, + "endLine": 363, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 29, + "endLine": 364, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 365, + "column": 28, + "endLine": 365, + "endColumn": 32, + "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/main/limit_void_type.ets.json b/ets2panda/linter/test/main/limit_void_type.ets.json index c23430e5d2f182b83a08ba6b9c9c8445030b3948..1e0934e13b4d8af69357c031cfc4004d958a4efb 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.json @@ -18,7 +18,7 @@ "line": 29, "column": 16, "endLine": 29, - "endColumn": 35, + "endColumn": 37, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", @@ -88,7 +88,7 @@ "line": 102, "column": 7, "endLine": 102, - "endColumn": 32, + "endColumn": 33, "problem": "DestructuringDeclaration", "suggest": "", "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", @@ -138,7 +138,7 @@ "line": 117, "column": 22, "endLine": 117, - "endColumn": 59, + "endColumn": 60, "problem": "LimitedStdLibApi", "suggest": "", "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", @@ -146,9 +146,9 @@ }, { "line": 117, - "column": 46, + "column": 47, "endLine": 117, - "endColumn": 47, + "endColumn": 48, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", @@ -158,7 +158,7 @@ "line": 126, "column": 10, "endLine": 126, - "endColumn": 34, + "endColumn": 36, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", @@ -166,9 +166,9 @@ }, { "line": 126, - "column": 27, + "column": 28, "endLine": 126, - "endColumn": 30, + "endColumn": 31, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -184,6 +184,16 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "WARNING" }, + { + "line": 168, + "column": 6, + "endLine": 168, + "endColumn": 8, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, { "line": 200, "column": 5, @@ -193,6 +203,16 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 224, + "column": 5, + "endLine": 224, + "endColumn": 7, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limit_void_type.ets.migrate.ets b/ets2panda/linter/test/main/limit_void_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc497a973ff9ea1be168d58184b6aa15f3af75b5 --- /dev/null +++ b/ets2panda/linter/test/main/limit_void_type.ets.migrate.ets @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {unionVoidVal,undefinedFooFun,func3Void,fun4undefined,fun5String} from './limit_void_type2' +// Example 1: Basic function +function func1(): void { } +let a: void = func1(); +// Example 2: Arrow function +const func2 = (): void => { }; +let b: void = func2(); +// Example 3: Class method +class Demo { + method(): void { } +} +let c: void = new Demo().method(); +// Example 4: Immediately Invoked Function Expression (IIFE) +let d: void = ((): void => { })(); +// Example 5: Asynchronous function +async function asyncFunc(): Promise { } +let e: void = await asyncFunc(); +// Example 6: Function parameter +function wrapper(fn: () => void) { + let f: void = fn(); +} +// Example 7: Type assertion +function func3(): void { } +let g: void = func3() as void; +// Example 8: Callback function +setTimeout((): void => { }, 1000); +let h: void = setTimeout(() => { }, 1000); +// Example 9: Array operation +const funcArr: (() => void)[] = [() => { }]; +let i: void = funcArr[0](); +// Example 10: Object method +const obj = { + action: (): void => { } +}; +let j: void = obj.action(); +// Example 11: Strict mode +// @ts-strict +function func4(): void { } +let k: void = func4(); +// Example 12: Module export +export function exportedFunc(): void { } +let l: void = exportedFunc(); +// Example 13: Generic function +function genericFunc(): void { } +let m: void = genericFunc(); +// Example 14: Function overloading +function overloadFunc(): void; +function overloadFunc(n: number): number; +function overloadFunc(n?: number) { return n; } +let n: void = overloadFunc(); +// Example 15: Type alias +type VoidFunc = () => void; +const aliasFunc: VoidFunc = () => { }; +let o: void = aliasFunc(); +// Example 16: Interface implementation +interface Task { + run(): void; +} +class Printer implements Task { + run(): void { } +} +let p: void = new Printer().run(); +// Example 17: Optional parameter +function withParam(param?: string): void { } +let q: void = withParam(); +// Example 18: Rest parameter +function sum(...nums: number[]): void { } +let r: void = sum(1, 2, 3); +// Example 19: This parameter +function withThis(this: Window): void { } +let s: void = withThis.call(window); +// Example 20: Generator function +function* genFunc(): Generator { + yield; +} +let u: void = genFunc().next().value; +// Example 21: Function currying +const curry = () => (): void => { }; +let w: void = curry()(); +// Example 22: Method chaining +class Chain { + first(): this { return this; } + last(): void { } +} +let x: void = new Chain().first().last(); +// Example 23: Destructuring assignment +const GeneratedDestructArray_1 = [(): void => { }]; +const func = GeneratedDestructArray_1[0]; + +let y: void = func(); +// Example 24: Type mapping +interface Wrapper { + value: T; +} +const wrapped: Wrapper<() => void> = { value: () => { } }; +let z: void = wrapped.value(); +// Example 25: Conditional type +type Conditional = T extends boolean ? () => void : never; +const condFunc: Conditional = () => { }; +let aa: void = condFunc(); +// Example 26: Mixed type +interface Mixed { + (): void; + prop: string; +} +const mixed: Mixed = Object.assign(() => { }, { prop: "" }); +let ab: void = mixed(); +// Example 27: Recursive call +function recursive(): void { + return recursive(); +} +let ac: void = recursive(); +// Example 28: Decorator function +function decorator() { + return (target: any) => { }; +} +@decorator() +class Decorated { } +let ad: void = decorator()(Decorated); + +function f1(): void { } + +let a1 = f1(); // type `void` is used as value + +a1 = f1(); // type `void` is used as value + +let a2: void; // type `void` is used as type annotation + +let a3: void[] = [f1()]; // type `void` is used as type annotation + +a3 = [f1()]; // type `void` is used as value + +a3[0] = f1(); // type `void` is used as value + +let a4: void = f1(); // type `void` is used as type annotation + +function f2(a: void) { } // type `void` is used as type annotation + +f2(f1()); // type `void` is used as value + +class A { + f: void; // type `void` is used as type annotation + + m(p: void) { } // type `void` is used as type annotation + + constructor(a: void) { // type `void` is used as type annotation + this.f = a; + } +} + +function f3(): undefined | Promise { + return undefined; +} // type `void` is not allowed in union type + +class B { + m(): undefined | number { + return undefined; + } // type `void` is not allowed in union type +} + +type ss = void; +let sspar: ss; + +type ff = string; +let ffpar: ff; + +let sread: readonly [void] = [undefined]; + +interface BT { + qaq: Function; +} + +class C { + private cc?: BT; + + private d(): void { + this.cc = { + qaq: (caller?: string): void => this.qaqq(caller) + } + } + private qaqq(caller?: string): void { + 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; +} + +function foo1():void{ + return foo(); // No Error +} + +function foocfe(a: number): string | undefined { + if (a >= 0) { + return "a >= 0"; + } + return undefined; +} + +function foocfe2(a: number): string | undefined { + if (a < 0) { + return undefined; + } + return "a >= 0"; +} +function fooefc(): void { } +let ss: void = foo() +let t: void | number = foo() +let t2: void | number = 1; + +function greet(hour: number): string | undefined { + if (hour < 12) { + return undefined; + } else if (hour < 18) { + return "Good afternoon"; + } else { + return undefined; + } + return undefined; +} + +function logOrReturn(flag: boolean): string | undefined { + if (flag) { + return "Flag is true"; + } + console.log("Flag is false"); + return undefined; +} + +function justLogs(): string | undefined { + console.log("Hello!"); + return undefined; +} + +function getStatus(code: number): string | undefined { + switch (code) { + case 1: return "OK"; + case 2: return "Warning"; + } + return undefined; +} + +function tryThing(): string | undefined { + try { + return "Worked!"; + } catch (e) { + console.error(e); + } + return undefined; +} + +class A1 { + // test + aa?: boolean | void + + test(a: number): boolean | undefined { + if (a > 0) { + // will return + return undefined; + } + // will return + return undefined; + } + + test1(a: number): undefined | boolean { + if (a > 0) { + // will return + return true; + } + // will return + return undefined; + } + + test2(a: number): undefined | boolean { + if (a > 0) { + // will return + return undefined; + } + return undefined; + } + + test3(a: number): undefined | boolean { + if (a > 0) { + // will return + return undefined; + } + return false; + } + + test4(): undefined | boolean { + // will return + + return undefined; + } +} + +function test(a: number): boolean | undefined { + if (a > 0) { + // will return + return undefined; + } + // will return + return undefined; +} + +function test1(a: number): undefined | boolean { + if (a > 0) { + // will return + return true; + } + // will return + return undefined; +} + +function test2(a: number): undefined | boolean { + if (a > 0) { + // will return + return undefined; + } + return undefined; +} + +function test3(a: number): undefined | boolean { + if (a > 0) { + // will return + return undefined; + } + return false; +} + +function test4(a: number): undefined | boolean { + // will return + + return undefined; +} + +let unionVoid = (()=>{ + return undefined; +})() as void; //error +function undefinedFoo(){ + return undefined; +} +function unionFoo(): undefined | boolean{ + return undefined; +} +let asVoidFun = undefinedFoo() as void; //error +let undefinedAsVoid = undefined as void; //error +let unionFooAsVoid = unionFoo() as void; //error + +function func6() { + return undefined as void; //error +} + +let exportAsVoidFun = unionVoidVal as void; +let exportUndefinedFooFun = undefinedFooFun() as void; //error +let exportfunc3Void = func3Void() as void; //error +console.log(fun5String() as void); +typeof (fun4undefined() as void) //error diff --git a/ets2panda/linter/test/main/limit_void_type.ets.migrate.json b/ets2panda/linter/test/main/limit_void_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2d6fa2f24571adc48cd1d92271dcfe8a9af99d90 --- /dev/null +++ b/ets2panda/linter/test/main/limit_void_type.ets.migrate.json @@ -0,0 +1,1218 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 8, + "endLine": 19, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 15, + "endLine": 19, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 8, + "endLine": 22, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 10, + "endLine": 35, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 26, + "endLine": 39, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 15, + "endLine": 39, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 8, + "endLine": 45, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 15, + "endLine": 45, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 15, + "endLine": 45, + "endColumn": 25, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 13, + "endLine": 47, + "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": 8, + "endLine": 50, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 8, + "endLine": 54, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 8, + "endLine": 57, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 15, + "endLine": 57, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 8, + "endLine": 60, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 15, + "endLine": 60, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 15, + "endLine": 60, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 62, + "endColumn": 31, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 42, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 48, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 8, + "endLine": 65, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 15, + "endLine": 65, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 15, + "endLine": 69, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 8, + "endLine": 77, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 15, + "endLine": 77, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 8, + "endLine": 80, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 15, + "endLine": 80, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 8, + "endLine": 83, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 15, + "endLine": 83, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 19, + "endLine": 85, + "endColumn": 23, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 8, + "endLine": 86, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 24, + "endLine": 86, + "endColumn": 28, + "problem": "FunctionApplyCall", + "suggest": "", + "rule": "'Function.apply', 'Function.call' are not supported (arkts-no-func-apply-call)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 90, + "endColumn": 2, + "problem": "GeneratorFunction", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 3, + "endLine": 89, + "endColumn": 8, + "problem": "YieldExpression", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 8, + "endLine": 91, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 15, + "endLine": 91, + "endColumn": 37, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 8, + "endLine": 94, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 15, + "endLine": 94, + "endColumn": 24, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 12, + "endLine": 97, + "endColumn": 16, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 8, + "endLine": 100, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 15, + "endLine": 100, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 14, + "endLine": 103, + "endColumn": 41, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 15, + "endLine": 105, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 8, + "endLine": 111, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 15, + "endLine": 111, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 23, + "endLine": 113, + "endColumn": 61, + "problem": "ConditionalType", + "suggest": "", + "rule": "Conditional types are not supported (arkts-no-conditional-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 9, + "endLine": 115, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 16, + "endLine": 115, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 3, + "endLine": 118, + "endColumn": 12, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 29, + "endLine": 121, + "endColumn": 35, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 47, + "endLine": 121, + "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": 122, + "column": 9, + "endLine": 122, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 16, + "endLine": 122, + "endColumn": 23, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 10, + "endLine": 125, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 9, + "endLine": 127, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 16, + "endLine": 127, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 19, + "endLine": 130, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 1, + "endLine": 132, + "endColumn": 13, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 9, + "endLine": 134, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 16, + "endLine": 134, + "endColumn": 38, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 28, + "endLine": 134, + "endColumn": 37, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 10, + "endLine": 138, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 6, + "endLine": 140, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 9, + "endLine": 142, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 9, + "endLine": 144, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 19, + "endLine": 144, + "endColumn": 23, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 7, + "endLine": 146, + "endColumn": 11, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 1, + "endLine": 148, + "endColumn": 6, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 9, + "endLine": 148, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 9, + "endLine": 150, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 16, + "endLine": 152, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 4, + "endLine": 154, + "endColumn": 8, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 6, + "endLine": 157, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 159, + "column": 8, + "endLine": 159, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 18, + "endLine": 161, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 6, + "endLine": 176, + "endColumn": 8, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 11, + "endLine": 176, + "endColumn": 15, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 12, + "endLine": 177, + "endColumn": 14, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 22, + "endLine": 182, + "endColumn": 26, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 23, + "endLine": 205, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 31, + "endLine": 205, + "endColumn": 36, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 5, + "endLine": 208, + "endColumn": 7, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 19, + "endLine": 209, + "endColumn": 24, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 27, + "endLine": 209, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 6, + "endLine": 211, + "endColumn": 10, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 5, + "endLine": 233, + "endColumn": 7, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 9, + "endLine": 233, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 16, + "endLine": 233, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 234, + "column": 8, + "endLine": 234, + "endColumn": 21, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 234, + "column": 8, + "endLine": 234, + "endColumn": 12, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 234, + "column": 24, + "endLine": 234, + "endColumn": 29, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 9, + "endLine": 235, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 9, + "endLine": 235, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 8, + "endLine": 280, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 18, + "endLine": 280, + "endColumn": 22, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 365, + "column": 9, + "endLine": 365, + "endColumn": 13, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 35, + "endLine": 372, + "endColumn": 39, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 373, + "column": 36, + "endLine": 373, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 374, + "column": 36, + "endLine": 374, + "endColumn": 40, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 23, + "endLine": 377, + "endColumn": 27, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 380, + "column": 39, + "endLine": 380, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 381, + "column": 50, + "endLine": 381, + "endColumn": 54, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 38, + "endLine": 382, + "endColumn": 42, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 23, + "endLine": 382, + "endColumn": 34, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 383, + "column": 29, + "endLine": 383, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 384, + "column": 28, + "endLine": 384, + "endColumn": 32, + "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/main/limit_void_type2.ets b/ets2panda/linter/test/main/limit_void_type2.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc2727c71674f9af7c6792bed305307b620a86ce --- /dev/null +++ b/ets2panda/linter/test/main/limit_void_type2.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 let unionVoidVal = (()=>{ + return undefined; +})() as void; +export function undefinedFooFun(){ + return undefined; +} +export function func3Void(): void { } +export function fun4undefined(): undefined | boolean { } +export function fun5String(): string { + return ''; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/limit_void_type2.ets.json b/ets2panda/linter/test/main/limit_void_type2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/limit_void_type2.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/limited_literal_type.ets.arkts2.json b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json index 08bcd5b26c682f11bfdd6e7d42ea431e7f85707b..3570308268ac8d18a3c979c8d8e808d82ba03faf 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json @@ -54,16 +54,6 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "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, @@ -84,16 +74,6 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "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": 42, "column": 17, @@ -114,16 +94,6 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "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": 14, @@ -134,16 +104,6 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "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, 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 115d052092240903c4c0013c4f3e219ff4c7e24f..34029346712ccd9625235de6edec0588fd885ebe 100644 --- a/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json @@ -24,26 +24,6 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 14, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 31, "column": 8, @@ -154,6 +134,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 62, + "column": 8, + "endLine": 62, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, { "line": 62, "column": 8, @@ -314,6 +304,36 @@ "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", "severity": "ERROR" }, + { + "line": 81, + "column": 20, + "endLine": 81, + "endColumn": 26, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 20, + "endLine": 82, + "endColumn": 27, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 51, + "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": 85, "column": 9, @@ -324,6 +344,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 39, + "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": 86, "column": 9, @@ -344,6 +374,16 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 36, + "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": 87, "column": 9, @@ -364,6 +404,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 34, + "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": 88, "column": 9, @@ -374,6 +424,26 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 89, + "column": 1, + "endLine": 89, + "endColumn": 32, + "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": 90, + "column": 1, + "endLine": 90, + "endColumn": 53, + "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": 90, "column": 9, @@ -384,6 +454,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 91, + "column": 1, + "endLine": 91, + "endColumn": 27, + "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": 91, "column": 9, @@ -394,6 +474,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 92, + "column": 1, + "endLine": 92, + "endColumn": 25, + "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": 92, "column": 9, @@ -404,6 +494,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 93, + "column": 1, + "endLine": 93, + "endColumn": 30, + "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": 93, "column": 9, @@ -414,6 +514,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 94, + "column": 1, + "endLine": 94, + "endColumn": 30, + "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": 94, "column": 9, @@ -424,14 +534,104 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 39, + "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": 95, + "column": 21, + "endLine": 95, + "endColumn": 24, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 1, + "endLine": 96, + "endColumn": 46, + "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": 96, + "column": 21, + "endLine": 96, + "endColumn": 24, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 39, + "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": 98, + "column": 1, + "endLine": 98, + "endColumn": 39, + "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": 99, + "column": 1, + "endLine": 99, + "endColumn": 38, + "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": 99, + "column": 21, + "endLine": 99, + "endColumn": 28, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 1, + "endLine": 100, + "endColumn": 31, + "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": 101, "column": 1, "endLine": 101, - "endColumn": 28, - "problem": "NumericSemantics", + "endColumn": 29, + "problem": "InteropCallReflect", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "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" }, { @@ -714,6 +914,26 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 120, + "column": 13, + "endLine": 120, + "endColumn": 19, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 7, + "endLine": 123, + "endColumn": 14, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, { "line": 127, "column": 12, diff --git a/ets2panda/linter/test/main/limited_stdlib_api.ets.json b/ets2panda/linter/test/main/limited_stdlib_api.ets.json index 0b436b2d76124a34bd7ba9709100409e382d9762..75f3d7b10e9b7ff3f3b2577f5761e7c4a0b426f1 100644 --- a/ets2panda/linter/test/main/limited_stdlib_api.ets.json +++ b/ets2panda/linter/test/main/limited_stdlib_api.ets.json @@ -274,6 +274,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 51, + "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": 86, "column": 1, @@ -284,6 +294,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 39, + "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": 86, "column": 32, @@ -304,6 +324,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 36, + "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": 87, "column": 32, @@ -324,6 +354,26 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 34, + "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": 89, + "column": 1, + "endLine": 89, + "endColumn": 32, + "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": 90, "column": 1, @@ -334,6 +384,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 90, + "column": 1, + "endLine": 90, + "endColumn": 53, + "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": 91, "column": 1, @@ -344,6 +404,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 91, + "column": 1, + "endLine": 91, + "endColumn": 27, + "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": 92, "column": 1, @@ -354,6 +424,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 92, + "column": 1, + "endLine": 92, + "endColumn": 25, + "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": 93, "column": 1, @@ -364,6 +444,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 93, + "column": 1, + "endLine": 93, + "endColumn": 30, + "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": 94, "column": 1, @@ -374,6 +464,86 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 94, + "column": 1, + "endLine": 94, + "endColumn": 30, + "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": 95, + "column": 1, + "endLine": 95, + "endColumn": 39, + "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": 96, + "column": 1, + "endLine": 96, + "endColumn": 46, + "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": 97, + "column": 1, + "endLine": 97, + "endColumn": 39, + "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": 98, + "column": 1, + "endLine": 98, + "endColumn": 39, + "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": 99, + "column": 1, + "endLine": 99, + "endColumn": 38, + "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": 100, + "column": 1, + "endLine": 100, + "endColumn": 31, + "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": 101, + "column": 1, + "endLine": 101, + "endColumn": 29, + "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": 104, "column": 32, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets b/ets2panda/linter/test/main/literals_as_prop_names.ets index 3c736bdefb6d8602a4bb42553e9d6b591f8b945c..e0fd0882c2f421890539561d80d79c004339252f 100755 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets @@ -118,4 +118,58 @@ struct Index { 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, // Error in arkts 2.0 + 'value2': 1 // ok +} + +class CompPropClass { + ['CompProp'] = 1; // Error in arkts 2.0 + [2] = 'CompProp2'; // Error in arkts 2.0 + [LiteralAsPropertyNameEnum.One] = 3; // Error in arkts 2.0 +} + +let compPropObj = { + ['CompProp']: 1, // Error in arkts 2.0 + [2]: 'CompProp2', // Error in arkts 2.0 + [LiteralAsPropertyNameEnum.One]: 3 // Error in arkts 2.0 +}; + +enum TEST { + A, + B, + C, +} +enum TEST2 { + A, + B, + C, +} + +let de3 = TEST2[TEST.A] //error +let de4 = TEST2[TEST.A| TEST.B] //error +let de5 = TEST[TEST.C] //ok + +export enum DeviceTypes12 { + PHONE = 'phone', + TABLET = 'tablet', + "2IN1" = '2in1', +} + +export class A{ + public static a= DeviceTypes12["2IN1"] } \ No newline at end of file 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 old mode 100755 new mode 100644 index 9d889b27b6d96e10cbfce88c6221ba819c65a722..f094451863721a0c420b22ef8bdda803879e4f18 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Copyright (c) 2024-2025 Huawei Device Co., Ltd.", "Licensed under the Apache License, Version 2.0 (the 'License');", "you may not use this file except in compliance with the License.", "You may obtain a copy of the License at", @@ -49,9 +49,9 @@ "column": 3, "endLine": 32, "endColumn": 4, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -59,9 +59,9 @@ "column": 3, "endLine": 33, "endColumn": 8, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -104,26 +104,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 57, - "column": 10, - "endLine": 57, - "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": 57, - "column": 22, - "endLine": 57, - "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": 59, "column": 13, @@ -189,9 +169,9 @@ "column": 3, "endLine": 80, "endColumn": 4, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -199,9 +179,9 @@ "column": 3, "endLine": 81, "endColumn": 8, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -209,9 +189,29 @@ "column": 36, "endLine": 84, "endColumn": 37, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 33, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 40, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -266,22 +266,22 @@ }, { "line": 105, - "column": 5, + "column": 14, "endLine": 105, "endColumn": 31, - "problem": "NumericSemantics", + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { "line": 106, - "column": 5, + "column": 15, "endLine": 106, "endColumn": 35, - "problem": "NumericSemantics", + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -304,6 +304,176 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 118, + "column": 18, + "endLine": 118, + "endColumn": 35, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 13, + "endLine": 128, + "endColumn": 18, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "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": 136, + "column": 3, + "endLine": 136, + "endColumn": 12, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 37, + "endLine": 135, + "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": 136, + "column": 3, + "endLine": 136, + "endColumn": 12, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 3, + "endLine": 143, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 19, + "endLine": 146, + "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": 147, + "column": 3, + "endLine": 147, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 3, + "endLine": 149, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 11, + "endLine": 163, + "endColumn": 24, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 11, + "endLine": 164, + "endColumn": 32, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 3, + "endLine": 170, + "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": 174, + "column": 20, + "endLine": 174, + "endColumn": 41, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, { "line": 115, "column": 2, @@ -311,7 +481,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -321,7 +491,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { 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 69a6d4d352fdcc3396e6c1797e0444f4dc4cc168..353c9e527250144e48d4ec5d566673aeb4a19174 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) 2025 Huawei Device Co., Ltd.", + "Copyright (c) 2024-2025 Huawei Device Co., Ltd.", "Licensed under the Apache License, Version 2.0 (the 'License');", "you may not use this file except in compliance with the License.", "You may obtain a copy of the License at", @@ -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": "", @@ -73,17 +93,29 @@ { "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": "", @@ -95,26 +127,9 @@ "column": 3, "endLine": 32, "endColumn": 4, - "problem": "LiteralAsPropertyName", - "autofix": [ - { - "replacementText": "__2", - "start": 836, - "end": 837 - }, - { - "replacementText": "__2", - "start": 928, - "end": 929 - }, - { - "replacementText": "litAsPropName.__2", - "start": 1001, - "end": 1017 - } - ], + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -122,26 +137,9 @@ "column": 3, "endLine": 33, "endColumn": 8, - "problem": "LiteralAsPropertyName", - "autofix": [ - { - "replacementText": "Two", - "start": 849, - "end": 854 - }, - { - "replacementText": "Two", - "start": 940, - "end": 945 - }, - { - "replacementText": "litAsPropName.Two", - "start": 1032, - "end": 1052 - } - ], + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -154,7 +152,11 @@ { "replacementText": "litAsPropName.one", "start": 966, - "end": 986 + "end": 986, + "line": 36, + "column": 13, + "endLine": 36, + "endColumn": 33 } ], "suggest": "", @@ -171,17 +173,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": "", @@ -198,17 +212,29 @@ { "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": "", @@ -225,26 +251,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 57, - "column": 10, - "endLine": 57, - "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": 57, - "column": 22, - "endLine": 57, - "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": 59, "column": 13, @@ -275,12 +281,20 @@ { "start": 1556, "end": 1556, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\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_1" + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 67, + "column": 13, + "endLine": 67, + "endColumn": 14 } ], "suggest": "", @@ -297,12 +311,20 @@ { "replacementText": "___2", "start": 1726, - "end": 1727 + "end": 1727, + "line": 75, + "column": 3, + "endLine": 75, + "endColumn": 4 }, { "replacementText": "___2", "start": 1808, - "end": 1809 + "end": 1809, + "line": 75, + "column": 3, + "endLine": 75, + "endColumn": 4 } ], "suggest": "", @@ -319,12 +341,20 @@ { "replacementText": "__2", "start": 1739, - "end": 1744 + "end": 1744, + "line": 76, + "column": 3, + "endLine": 76, + "endColumn": 8 }, { "replacementText": "__2", "start": 1824, - "end": 1829 + "end": 1829, + "line": 76, + "column": 3, + "endLine": 76, + "endColumn": 8 } ], "suggest": "", @@ -346,21 +376,9 @@ "column": 3, "endLine": 80, "endColumn": 4, - "problem": "LiteralAsPropertyName", - "autofix": [ - { - "replacementText": "___2", - "start": 1726, - "end": 1727 - }, - { - "replacementText": "___2", - "start": 1808, - "end": 1809 - } - ], + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -368,21 +386,9 @@ "column": 3, "endLine": 81, "endColumn": 8, - "problem": "LiteralAsPropertyName", - "autofix": [ - { - "replacementText": "__2", - "start": 1739, - "end": 1744 - }, - { - "replacementText": "__2", - "start": 1824, - "end": 1829 - } - ], + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -390,9 +396,29 @@ "column": 36, "endLine": 84, "endColumn": 37, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 33, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 40, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -405,7 +431,11 @@ { "replacementText": "__empty", "start": 1991, - "end": 1993 + "end": 1993, + "line": 92, + "column": 4, + "endLine": 92, + "endColumn": 10 } ], "suggest": "", @@ -422,7 +452,11 @@ { "replacementText": "___x5c", "start": 2033, - "end": 2037 + "end": 2037, + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 11 } ], "suggest": "", @@ -439,7 +473,11 @@ { "replacementText": "__x5c", "start": 2045, - "end": 2052 + "end": 2052, + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 14 } ], "suggest": "", @@ -456,12 +494,20 @@ { "replacementText": "___x5c", "start": 2088, - "end": 2092 + "end": 2092, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11 }, { "replacementText": "Direction17.___x5c", "start": 2128, - "end": 2145 + "end": 2145, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11 } ], "suggest": "", @@ -478,12 +524,20 @@ { "replacementText": "__x5c", "start": 2100, - "end": 2107 + "end": 2107, + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14 }, { "replacementText": "Direction17.__x5c", "start": 2160, - "end": 2180 + "end": 2180, + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14 } ], "suggest": "", @@ -492,36 +546,22 @@ }, { "line": 105, - "column": 5, + "column": 14, "endLine": 105, "endColumn": 31, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2119, - "end": 2145, - "replacementText": "case17: number = Direction17[\"\\\\\"]" - } - ], + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { "line": 106, - "column": 5, + "column": 15, "endLine": 106, "endColumn": 35, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2150, - "end": 2180, - "replacementText": "case172: number = Direction17[\"__x5c\"]" - } - ], + "problem": "UnsupportPropNameFromValue", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -534,12 +574,20 @@ { "replacementText": "__x21x21", "start": 2207, - "end": 2211 + "end": 2211, + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9 }, { "replacementText": "Direction11.__x21x21", "start": 2349, - "end": 2366 + "end": 2366, + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9 } ], "suggest": "", @@ -556,13 +604,218 @@ { "replacementText": "aaa", "start": 2244, - "end": 2249 + "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": 118, + "column": 18, + "endLine": 118, + "endColumn": 35, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 13, + "endLine": 128, + "endColumn": 18, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 10, + "endLine": 132, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "age", + "start": 2466, + "end": 2471, + "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": 136, + "column": 3, + "endLine": 136, + "endColumn": 12, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 37, + "endLine": 135, + "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": 136, + "column": 3, + "endLine": 136, + "endColumn": 12, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 3, + "endLine": 143, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 19, + "endLine": 146, + "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": 147, + "column": 3, + "endLine": 147, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 3, + "endLine": 149, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 11, + "endLine": 163, + "endColumn": 24, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 11, + "endLine": 164, + "endColumn": 32, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__2IN1", + "start": 3173, + "end": 3179, + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 18 + }, + { + "replacementText": "DeviceTypes12.__2IN1", + "start": 3228, + "end": 3249, + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 20, + "endLine": 174, + "endColumn": 41, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, { "line": 115, "column": 2, @@ -573,11 +826,15 @@ { "start": 608, "end": 608, - "replacementText": "\n\nimport { Component, State } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n} from '@kit.ArkUI';", + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -590,11 +847,15 @@ { "start": 608, "end": 608, - "replacementText": "\n\nimport { Component, State } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n State,\n} from '@kit.ArkUI';", + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { 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 7e721f74f1a1f51c82e35dff5046839e4d2c21de..67551a2d06c68cd5f8c820c47e5c5f24de1232f9 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.json @@ -34,6 +34,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 33, + "column": 3, + "endLine": 33, + "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": 36, "column": 13, @@ -74,6 +84,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 57, + "column": 10, + "endLine": 57, + "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": 57, "column": 22, @@ -134,6 +154,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 81, + "column": 3, + "endLine": 81, + "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": 84, "column": 36, @@ -144,6 +174,46 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "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": 142, + "column": 3, + "endLine": 142, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 19, + "endLine": 146, + "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": 148, + "column": 3, + "endLine": 148, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, { "line": 42, "column": 11, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets index 322bb59464962c413fe980594f548f55391f1300..cfe2c22819d9f63eba12ba0d098c099764c901a5 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets @@ -13,7 +13,10 @@ * limitations under the License. */ -import { Component, State } from '@kit.ArkUI'; +import { + Component, + State, +} from '@kit.ArkUI'; import { ExportLitAsPropName } from './ignore_files/good'; @@ -108,8 +111,8 @@ const enum Direction17 { ___x5c = 1, __x5c = 1, } -let case17: number = Direction17.___x5c -let case172: number = Direction17.__x5c +let case17 = Direction17.___x5c +let case172 = Direction17.__x5c const enum Direction11 { __x21x21 = 1, @@ -124,4 +127,58 @@ struct Index { private case11 = Direction11.__x21x21 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, // Error in arkts 2.0 + 'value2': 1 // ok +} + +class CompPropClass { + ['CompProp'] = 1; // Error in arkts 2.0 + [2] = 'CompProp2'; // Error in arkts 2.0 + [LiteralAsPropertyNameEnum.One] = 3; // Error in arkts 2.0 +} + +let compPropObj = { + ['CompProp']: 1, // Error in arkts 2.0 + [2]: 'CompProp2', // Error in arkts 2.0 + [LiteralAsPropertyNameEnum.One]: 3 // Error in arkts 2.0 +}; + +enum TEST { + A, + B, + C, +} +enum TEST2 { + A, + B, + C, +} + +let de3 = TEST2[TEST.A] //error +let de4 = TEST2[TEST.A| TEST.B] //error +let de5 = TEST[TEST.C] //ok + +export enum DeviceTypes12 { + PHONE = 'phone', + TABLET = 'tablet', + __2IN1 = '2in1', +} + +export class A{ + public static a= DeviceTypes12.__2IN1 } \ No newline at end of file diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json index f58bbbb8ee64ff10fe13db138a4a73365de42868..46bd0dfc2b394ad37a46306567e3fcbb34ff3928 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Copyright (c) 2024-2025 Huawei Device Co., Ltd.", "Licensed under the Apache License, Version 2.0 (the 'License');", "you may not use this file except in compliance with the License.", "You may obtain a copy of the License at", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 59, + "line": 62, "column": 9, - "endLine": 59, + "endLine": 62, "endColumn": 10, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -25,29 +25,9 @@ "severity": "ERROR" }, { - "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": 59, - "column": 22, - "endLine": 59, - "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": 61, + "line": 64, "column": 13, - "endLine": 61, + "endLine": 64, "endColumn": 22, "problem": "PropertyAccessByIndex", "suggest": "", @@ -55,9 +35,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 65, "column": 13, - "endLine": 62, + "endLine": 65, "endColumn": 17, "problem": "PropertyAccessByIndex", "suggest": "", @@ -65,9 +45,9 @@ "severity": "ERROR" }, { - "line": 84, + "line": 87, "column": 7, - "endLine": 84, + "endLine": 87, "endColumn": 10, "problem": "InvalidIdentifier", "suggest": "", @@ -75,19 +55,159 @@ "severity": "ERROR" }, { - "line": 90, + "line": 93, "column": 36, - "endLine": 90, + "endLine": 93, "endColumn": 37, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 33, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 13, + "endLine": 137, + "endColumn": 18, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 3, + "endLine": 145, + "endColumn": 12, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 37, + "endLine": 144, + "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": 145, + "column": 3, + "endLine": 145, + "endColumn": 12, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 3, + "endLine": 150, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 3, + "endLine": 151, + "endColumn": 6, + "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 28, + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 19, + "endLine": 155, + "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": 156, + "column": 3, + "endLine": 156, + "endColumn": 15, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 3, + "endLine": 157, + "endColumn": 6, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 3, + "endLine": 158, + "endColumn": 34, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 172, "column": 11, - "endLine": 28, + "endLine": 172, + "endColumn": 24, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 11, + "endLine": 173, + "endColumn": 32, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 11, + "endLine": 31, "endColumn": 14, "problem": "StrictDiagnostic", "suggest": "Property '__2' has no initializer and is not definitely assigned in the constructor.", @@ -95,9 +215,9 @@ "severity": "ERROR" }, { - "line": 29, + "line": 32, "column": 3, - "endLine": 29, + "endLine": 32, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", @@ -105,9 +225,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 47, "column": 11, - "endLine": 44, + "endLine": 47, "endColumn": 13, "problem": "StrictDiagnostic", "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", @@ -115,9 +235,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 48, "column": 3, - "endLine": 45, + "endLine": 48, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", @@ -125,9 +245,9 @@ "severity": "ERROR" }, { - "line": 65, + "line": 68, "column": 12, - "endLine": 65, + "endLine": 68, "endColumn": 16, "problem": "StrictDiagnostic", "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", @@ -135,9 +255,9 @@ "severity": "ERROR" }, { - "line": 66, + "line": 69, "column": 12, - "endLine": 66, + "endLine": 69, "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.arkts2.json b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json index d25d1a3cb3e628d2e1c93e5d29b19d430e622fed..2476b270173391453e64fca61f2021c3c7a6d6bd 100644 --- a/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json @@ -31,7 +31,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (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 index 03374a941ac15fbb8447ff5882f0c9b24f25192e..2c776ac2ff71c88b27e50599e2131f35e96ef612 100644 --- a/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json +++ b/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 676, "end": 689, - "replacementText": "@Builder" + "replacementText": "@Builder", + "line": 21, + "column": 3, + "endLine": 21, + "endColumn": 16 } ], "suggest": "", @@ -41,11 +45,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n State,\n Row,\n Text,\n Column,\n} from '@kit.ArkUI';", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets index d9a2b55ebe936e012207a55d2db5de2634f3e8f7..d3f6980a0655e271fa43c9fbf5bf04d4f6307ce4 100644 --- a/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets @@ -15,7 +15,14 @@ import { Builder } from '@kit.ArkUI'; -import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; +import { + Entry, + Component, + State, + Row, + Text, + Column, +} from '@kit.ArkUI'; @Entry @Component diff --git a/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json index 25479ad946f42f3dd678a6b7969c929657e281fd..4f6be2ebe6496fb2a8112ff5e9cb0e06b38faca8 100644 --- a/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json @@ -19,9 +19,9 @@ "column": 26, "endLine": 28, "endColumn": 46, - "problem": "MakeObservedIsNotSupported", + "problem": "MakeObservedCannotObserveCustomClass", "suggest": "", - "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "rule": "The \"makeObserved\" function cannot observe custom class (arkui-makeobserved-cannot-observe-custom-class)", "severity": "ERROR" }, { @@ -29,9 +29,9 @@ "column": 24, "endLine": 38, "endColumn": 44, - "problem": "MakeObservedIsNotSupported", + "problem": "MakeObservedCannotObserveCustomClass", "suggest": "", - "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "rule": "The \"makeObserved\" function cannot observe custom class (arkui-makeobserved-cannot-observe-custom-class)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json index 9637e0d4ecb5005c28e884a9c3500654b30ac794..593093161363dc044c80eb06355d5c3403088dbb 100644 --- a/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json @@ -19,9 +19,9 @@ "column": 26, "endLine": 28, "endColumn": 44, - "problem": "MakeObservedIsNotSupported", + "problem": "MakeObservedCannotObserveCustomClass", "suggest": "", - "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "rule": "The \"makeObserved\" function cannot observe custom class (arkui-makeobserved-cannot-observe-custom-class)", "severity": "ERROR" }, { @@ -29,9 +29,9 @@ "column": 24, "endLine": 38, "endColumn": 42, - "problem": "MakeObservedIsNotSupported", + "problem": "MakeObservedCannotObserveCustomClass", "suggest": "", - "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "rule": "The \"makeObserved\" function cannot observe custom class (arkui-makeobserved-cannot-observe-custom-class)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json index 19d2b241e60fca7ef5f66689b1c82a49dd52b1b5..293592a2e0bccc845416a637f0a014ac99f02f55 100644 --- a/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json +++ b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/make_observed_4.ets b/ets2panda/linter/test/main/make_observed_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..5ef66a5672d8e5eec2b2a22d7ae0e566b421dbfc --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_4.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. + */ + +import { UIUtils } from '@kit.ArkUI'; + +interface User { + name: string; +} + +@Entry +@Component +struct Index { + user: User = UIUtils.makeObserved({ name: 'jack' }); + MyArr: Array = UIUtils.makeObserved(new Array(1, 2)); + MySet: Set = UIUtils.makeObserved(new Set([1, 2, 3])) + myMap: Map = UIUtils.makeObserved(new Map([["jack", 3], ["tom", 2]])); + myDate: Date = UIUtils.makeObserved(new Date()); + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_4.ets.args.json b/ets2panda/linter/test/main/make_observed_4.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_4.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_4.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_4.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7d3ef2b4a08b000d69829e2475f50bb43a02633a --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_4.ets.arkts2.json @@ -0,0 +1,74 @@ +{ + "result": [ + { + "line": 26, + "column": 51, + "endLine": 26, + "endColumn": 56, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 47, + "endLine": 26, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 45, + "endLine": 27, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 53, + "endLine": 28, + "endColumn": 87, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 43, + "endLine": 29, + "endColumn": 47, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 2, + "endLine": 23, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_4.ets.json b/ets2panda/linter/test/main/make_observed_4.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..43cb4a27bcc78710d4aa5130c22ee053f66c3fbc --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_4.ets.json @@ -0,0 +1,3 @@ +{ + "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 index ff1895fc91560a5662f08d3eb401caa34da364e0..fe85d554a311e7709436d4d4ac2a805b4438c010 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets +++ b/ets2panda/linter/test/main/method_inheritance.ets @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import {AAA} from './method_inheritance_ts' abstract class Y { abstract getDataByName(name: string | number, albumUri: string): Promise; } class X extends Y { - async getDataByName(name: string, albumUri: string): Promise { + async getDataByName(name: string, albumUri: string): Promise { // error 2 return; } } @@ -38,7 +38,7 @@ abstract class W { } class Q extends W { - async getDataByName(name: string | number, albumUri: string | number): Promise { + async getDataByName(name: string | number, albumUri: string | number): Promise {// error 1 return; }; } @@ -48,7 +48,7 @@ abstract class BaseClass3 { } class IncorrectWiderReturn extends BaseClass3 { - compute(value: string): string | number { + compute(value: string): string | number {// error 1 return value.length > 5 ? value : 0; } } @@ -58,7 +58,7 @@ abstract class BaseClass4 { } class IncorrectMultipleParamMismatch extends BaseClass4 { - setValues(x: string, y: boolean): void { + setValues(x: string, y: boolean): void {// error 2 console.log(x, y); } } @@ -68,7 +68,7 @@ abstract class BaseClass5 { } class IncorrectBothMismatch extends BaseClass5 { - transform(data: number): number | string { + transform(data: number): number | string {// error 2 return data > 10 ? data : "too small"; } } @@ -97,3 +97,278 @@ class CorrectBothWiderParamNarrowReturn extends BaseClass { } +class A1 { + a: number = 0 +} +class B1 { + a: number = 0 +} +class C { + a: number = 0 +} + +class Base { + foo(obj: A1 | B1): void { + console.log("base") + } + foo2(obj: A1 | B1): void { + console.log("base") + } + foo3(obj: A1 | B1 | C): void { + console.log("base") + } +} + +// extends +class Derived extends Base { + foo(obj: A1): void { // error 1 + console.log("Derived:" + obj.a) + } + foo2(): void { // error 1 + console.log("Derived:") + } + foo3(obj: A1 | B1): void { // error 1 + console.log("Derived:") + } +} + +interface BaseI { + foo(obj: A1 | B1):void; + foo2(obj: A1): void; + foo3(obj: A1 | B1 | C): void; +} + +// implements +class Derived2 implements BaseI { + foo(obj: A1): void { // error 1 + console.log("Drived"); + } + foo2(): void { // error 1 + console.log("Drived"); + } + foo3(obj: A1 | B1): void { // error 1 + console.log("Drived"); + } +} + +class Base2 { + foo(): A1|B1 { + console.log("base") + return new A1(); + } + foo2(){ + console.log("base") + // return new A(); + } + foo3(): A1 { + console.log("base") + return new A1(); + } + foo4():void{ + console.log("base") + // return new A(); + } +} + +//extends +class Derived3 extends Base2 { + foo(): A1|B1|C{ // error 1 + console.log("Derived:") + return new A1(); + } + + foo2(): A1{ // error 1 + console.log("Derived:") + return new A1(); + } + + foo3(): A1|B1 { // error 1 + console.log("Derived:") + return new A1(); + } + foo4(): A1{ // error 1 + console.log("Derived:") + return new A1(); + } +} + + +interface Base3 { + foo(): A1|B1 ; + foo2(): void; + foo3(): A1; +} + +// implements +class Derived4 implements Base3 { + foo(): A1|B1|C{ // error 1 + console.log("Derived:") + return new A1(); + } + + foo2(): A1{ // error 1 + console.log("Derived:") + return new A1(); + } + + foo3(): A1|B1 { // error 1 + console.log("Derived:") + return new A1(); + } +} + +class P { +} + +class PP extends P { + public static toString(result: number): string { // Legal + return ''; + } +} + +class RCP {} + +interface aa { + aa?: Function; +} +interface bb extends aa { + onError(res: RCP): void; +} +class CC implements bb { + onError(res: RCP): void {} // Legal + aa?: Function = () => {} +} +class Animal {} +class Dog extends Animal {} + +class Base6 { + public foo(): Animal { + console.log("base") + } +} +// extends +class Derived6 extends Base6 { + public foo(): Dog { // no error + console.log("Derived:") + } +} + +abstract class Parent{ + abstract foo(); + +} +abstract class Parent1{ + abstract foo(): Promise; + +} + +abstract class Child extends Parent{ + async foo(){ //error + + } +} +class Child1 extends Parent{ + async foo(){ //error + + } +} + +class Child11 extends Parent{ + async foo():Promise{ //error + + } +} +class Child12 extends Parent{ + async foo():Promise{ //error + return ''; + } +} +abstract class Child13 extends Parent{ + async foo():Promise{ //error + return ''; + } +} +abstract class Child14 extends Parent{ + async foo():Promise{ //error + + } +} + +abstract class Child2 extends Parent{ + foo(): void { //error + + } +} +abstract class Child3 extends Parent{ + foo(): boolean { + return false; + } +} + +class Child17 extends Parent{ + foo(){ //error??? + } +} +abstract class Child18 extends Parent{ + foo(){ //error??? + } +} + +class Child19 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child20 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child21 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child5 extends Parent1{ + async foo(): Promise{ //error + return ''; + } +} + +abstract class Child4 extends Parent1{ + async foo() { + + } +} + +class CCC {} +class BBB extends AAA { + test(): CCC { + return new CCC(); + } +} + +class BBB2 extends AAA { + test(): void { //error + return ; + } +} + +class BBB3 extends AAA { + test() { //error + } +} + + +abstract class Test1 { + abstract test(params: Map): void; +} + +class Test2 extends Test1 { + test(params: Map): void { // no Error + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json index 4a6d9d7c640d149afa79fccf76081d127aa4f7b1..bac26d04ac18a7d3d6029cdd7e6def8ffd04a4e1 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json +++ b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json @@ -93,6 +93,406 @@ "suggest": "", "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", "severity": "ERROR" + }, + { + "line": 95, + "column": 16, + "endLine": 95, + "endColumn": 22, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 7, + "endLine": 124, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 8, + "endLine": 130, + "endColumn": 20, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 3, + "endLine": 146, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 8, + "endLine": 149, + "endColumn": 20, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 10, + "endLine": 175, + "endColumn": 17, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 11, + "endLine": 180, + "endColumn": 13, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 11, + "endLine": 185, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 11, + "endLine": 189, + "endColumn": 13, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 10, + "endLine": 204, + "endColumn": 17, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 11, + "endLine": 209, + "endColumn": 13, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 11, + "endLine": 214, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 3, + "endLine": 226, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 9, + "endLine": 266, + "endColumn": 12, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 9, + "endLine": 266, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 9, + "endLine": 271, + "endColumn": 12, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 9, + "endLine": 271, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 277, + "column": 15, + "endLine": 277, + "endColumn": 28, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 277, + "column": 9, + "endLine": 277, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 282, + "column": 15, + "endLine": 282, + "endColumn": 30, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 282, + "column": 9, + "endLine": 282, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 15, + "endLine": 287, + "endColumn": 30, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 9, + "endLine": 287, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 292, + "column": 15, + "endLine": 292, + "endColumn": 28, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 292, + "column": 9, + "endLine": 292, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 298, + "column": 10, + "endLine": 298, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 3, + "endLine": 303, + "endColumn": 6, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 309, + "column": 3, + "endLine": 309, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 3, + "endLine": 313, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 3, + "endLine": 318, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 324, + "column": 3, + "endLine": 324, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 330, + "column": 3, + "endLine": 330, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 336, + "column": 16, + "endLine": 336, + "endColumn": 31, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 355, + "column": 11, + "endLine": 355, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 3, + "endLine": 361, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 320, + "column": 12, + "endLine": 320, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 326, + "column": 12, + "endLine": 326, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 332, + "column": 12, + "endLine": 332, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets.json b/ets2panda/linter/test/main/method_inheritance.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..144f84de60945d1566ca79326891588f004d1755 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets.json +++ b/ets2panda/linter/test/main/method_inheritance.ets.json @@ -13,5 +13,36 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 320, + "column": 12, + "endLine": 320, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 326, + "column": 12, + "endLine": 326, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 332, + "column": 12, + "endLine": 332, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance2.ets b/ets2panda/linter/test/main/method_inheritance2.ets new file mode 100755 index 0000000000000000000000000000000000000000..1f8bd037830fa698d02226b8e241f6e39785e2ff --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance2.ets @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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: number = 0 +} +class B { + a: number = 0 +} +class C { + a: number = 0 +} + +class D extends A{ + a: number = 0; + b: number = 1; +} + + +// T +class Base3 { + foo(obj: A | B): void { + console.log("base") + } + foo2(obj: A | B): void { + console.log("base") + } + foo3(obj: A | B | C): void { + console.log("base") + } +} +// T extends +class Derived3 extends Base3 { + foo(obj: A): void { // (arkts-method-inherit-rule) error + console.log("Derived:" + obj.a) + } + foo2(): void { // (arkts-method-inherit-rule) error + console.log("Derived:") + } + foo3(obj: A | B): void { //(arkts-method-inherit-rule) error + console.log("Derived:") + } +} + +// T interface +interface BaseI2 { + foo(obj: A | B):void; + foo2(obj: A ): void; + foo3(obj: A | B | C): void; +} + +// T implements +class DerivedI2 implements BaseI2 { + foo(obj: A): void { // (arkts-method-inherit-rule) error + console.log("Derived"); + } + foo2(): void { // (arkts-method-inherit-rule) error + console.log("Derived"); + } + foo3(obj: A | B): void { // (arkts-method-inherit-rule) error + console.log("Derived"); + } +} + +class Base5 { + public foo(): A|B { + console.log("base") + return new A(); + } + static foo2(){ + console.log("base") + // return new A(); + } + async foo3(): Promise { + console.log("base") + return new A(); + } + static foo4():void{ + console.log("base") + // return new A(); + } +} + +// extends +class Derived5 extends Base5 { + public foo(): A|B|C{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + static foo2(): A{ // (arkts-method-inherit-rule) error + console.log("Derived:") + return new A(); + } + + async foo3(): Promise { // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + static foo4(): A{ // (arkts-method-inherit-rule) error + console.log("Derived:") + return new A(); + } +} + +interface I{ + pp(key:string,value:string):void + pp(key:string):void +} + +class J implements I{ + pp(key: string,value?:string):void { // arkts-method-inherit-rule + } +} + +interface BaseI { + foo(): A|B ; + foo2(): void; + foo3(): A; +} + +class Derived2 implements BaseI { + foo(): A|B|C{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo2(): A{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo3(): A|B { // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } +} + +let b2:BaseI = new Derived2(); +b2.foo(); +b2.foo2() +b2.foo3() + + +class Base32 { + foo(): A|B { + console.log("base") + return new A(); + } + foo2():void{ + console.log("base") + // return new A(); + } + foo3(): A { + console.log("base") + return new A(); + } + foo4(){ + console.log("base") + // return new A(); + } +} + +class Derived32 extends Base32 { + foo(): A|B|C{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo2(): A{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo3(): A|B { // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo4(): A{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } +} + +interface BaseI4 { + foo(): A|B ; + foo2(): void; + foo3(): A; +} + +class Derived4 implements BaseI4 { + foo(): A|B|C{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo2(): A{ // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } + + foo3(): A|B { // (arkts-method-inherit-rule) + console.log("Derived:") + return new A(); + } +} + +class Animal {} +class Dog extends Animal {} +class Base55 { + public foo(obj: Animal): void { + console.log("base") + } +} + +class Derived55 extends Base55 { + public foo(obj: Dog): void { // (arkts-method-inherit-rule) + console.log("Derived:") + } +} + +class Base6 { + public foo(): Dog { + console.log("base") + return new Dog(); + } +} + +class Derived6 extends Base6 { + public foo(): Animal { // (arkts-method-inherit-rule) + console.log("Derived:") + return new Animal() + } +} + +abstract class Base66{ + abstract foo(); + abstract foo1(); +} + +abstract class Derived66 extends Base66{ + async foo(){ // (arkts-method-inherit-rule) + + } + foo1(): number { // (arkts-method-inherit-rule)? + return 1 + } +} +class Base7{ + foo(){ + + } +} +class Derived7 extends Base7{ + foo(): number { // (arkts-method-inherit-rule) + return 12; + } +} +class Base44 { + public foo(obj: A | B): void { + console.log("base") + } + protected foo2(obj: A | B): void { + console.log("base") + } + async foo3(obj: A | B | C): Promise { + console.log("base") + } +} + +class Derived44 extends Base44 { + public foo(obj: A): void { // (arkts-method-inherit-rule) + console.log("Derived:" + obj.a) + } + protected foo2(): void { // (arkts-method-inherit-rule) + console.log("Derived:") + } + async foo3(obj: A | B): Promise { // (arkts-method-inherit-rule) + console.log("Derived:") + } +} +class Base { + foo(obj: A | B): void { + console.log("base") + } + foo2(obj: A | B): void { + console.log("base") + } + foo3(obj: A | B | C): void { + console.log("base") + } + foo4(obj: A): void { + console.log("base" ); + } +} +class Derived extends Base { + foo(obj: A): void { // (arkts-method-inherit-rule) + console.log("Derived:" + obj.a) + } + foo2(): void { // (arkts-method-inherit-rule) + console.log("Derived:") + } + foo3(obj: A | B): void { // (arkts-method-inherit-rule) + console.log("Derived:") + } + foo4(obj: D): void { // (arkts-method-inherit-rule) + console.log("Derived:" + obj.b) + } +} +class Derived_Derived extends Derived { + foo(): void { // (arkts-method-inherit-rule) + } + + foo3(obj: A): void { // (arkts-method-inherit-rule) + console.log("Derived:") + } +} + +let b:Base = new Derived(); +b.foo(new B()); +b.foo2(new B()) + +interface BaseI22 { + foo(obj: A | B):void; + foo2(obj: A ): void; + foo3(obj: A | B | C): void; +} + +class Derived22 implements BaseI22 { + foo(obj: A): void { // (arkts-method-inherit-rule) + console.log("Derived"); + } + foo2(): void { // (arkts-method-inherit-rule) + console.log("Derived"); + } + foo3(obj: A | B): void { // (arkts-method-inherit-rule) + console.log("Derived"); + } +} +let b22 :BaseI = new Derived2(); \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance2.ets.args.json b/ets2panda/linter/test/main/method_inheritance2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance2.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_inheritance2.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b1dcfe111286c87f6f3c5f5600d6910f187952bd --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance2.ets.arkts2.json @@ -0,0 +1,398 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 3, + "endLine": 49, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 21, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 10, + "endLine": 66, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 11, + "endLine": 72, + "endColumn": 21, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 17, + "endLine": 98, + "endColumn": 22, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 18, + "endLine": 103, + "endColumn": 19, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 17, + "endLine": 108, + "endColumn": 29, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 18, + "endLine": 112, + "endColumn": 19, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 10, + "endLine": 135, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 11, + "endLine": 140, + "endColumn": 12, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 11, + "endLine": 145, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 13, + "endLine": 177, + "endColumn": 18, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 14, + "endLine": 182, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 14, + "endLine": 187, + "endColumn": 17, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 14, + "endLine": 192, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 13, + "endLine": 205, + "endColumn": 18, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 210, + "column": 14, + "endLine": 210, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 14, + "endLine": 215, + "endColumn": 17, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 14, + "endLine": 230, + "endColumn": 22, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 17, + "endLine": 243, + "endColumn": 23, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 255, + "column": 9, + "endLine": 255, + "endColumn": 12, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 255, + "column": 9, + "endLine": 255, + "endColumn": 12, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 3, + "endLine": 258, + "endColumn": 7, + "problem": "InvalidAbstractOverrideReturnType", + "suggest": "", + "rule": "In 1.1, the default type obtained for the abstract method without the annotation type is any. In 1.2, the default type for the abstract method without the annotation type is void. (arkts-distinct-abstract-method-default-return-type)", + "severity": "ERROR" + }, + { + "line": 268, + "column": 10, + "endLine": 268, + "endColumn": 16, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 285, + "column": 14, + "endLine": 285, + "endColumn": 20, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 288, + "column": 13, + "endLine": 288, + "endColumn": 17, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 291, + "column": 14, + "endLine": 291, + "endColumn": 24, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 7, + "endLine": 310, + "endColumn": 13, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 3, + "endLine": 313, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 8, + "endLine": 316, + "endColumn": 18, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 319, + "column": 8, + "endLine": 319, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 324, + "column": 3, + "endLine": 324, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 327, + "column": 8, + "endLine": 327, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 343, + "column": 7, + "endLine": 343, + "endColumn": 13, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 346, + "column": 3, + "endLine": 346, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 349, + "column": 8, + "endLine": 349, + "endColumn": 18, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance2.ets.json b/ets2panda/linter/test/main/method_inheritance2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance2.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_inheritance3.ets b/ets2panda/linter/test/main/method_inheritance3.ets new file mode 100755 index 0000000000000000000000000000000000000000..d4b5b6b18efa1af9de3c9df43ee80ec2c259ff15 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance3.ets @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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{ + getData(a:T):T{ + return a; + } +} + +class B extends A{ + getData(a: number): number { // no error + return 123; + } +} + +enum E{ + E1, + E2 +} + +interface I { + fun(e:E):void +} + +class C implements I { + fun(e:E):void{ // no error + + } +} + +Class UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void; + onWindowStageCreate(windowStage: window.WindowStage): void; +} + +class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // no error + + } + + onWindowStageCreate(windowStage: window.WindowStage): void { // no error + try { + windowStage.loadContent('pages/Index', (err: BusinessError | null): void => { + if (err && err.code) { + return; + } + }); + } catch (e) { + } + } +} + +class TestA { + a: number = 0 +} + +class TestD extends TestA{ + a: number = 0; + b: number = 1; +} + +class TestE implements TestI{ + +} + +class TestF extends TestE{ + +} +interface TestI{ + +} + +interface TestI2 extends TestI{ + +} +class TestBase { + foo3(obj: TestD): void { + console.log("Derived:" + obj.b) + } + + foo4(obj: TestD): TestA { + console.log("base" ); + return new TestA() + } + + foo5():TestI{ + return {} + } + + foo12(obj:never){ + + } +} + +class TestDerived extends TestBase { + override foo3(obj: TestA): void { // no error + console.log("base" ); + } + + override foo4(obj: TestA): TestD { // no error + return new TestD(); + } + + override foo5(): TestI2 { // no error + return {} + } + + override foo12(obj:TestA){ // no error + + } +} + +class CC1 {} +class CC2 extends CC1 { + public static toString(result: number): string { // no error + return ''; + } +} + +class AA{ + getData(a:T):T{ + + return a; + } +} + +class BB extends AA{ + getData(a: number): number { // no error + return 123; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance3.ets.args.json b/ets2panda/linter/test/main/method_inheritance3.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance3.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_inheritance3.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance3.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..6fd8017e327821c67a10278cb6bbd9721ae86f29 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance3.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": 44, + "column": 67, + "endLine": 44, + "endColumn": 71, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 57, + "endLine": 45, + "endColumn": 61, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 3, + "endLine": 129, + "endColumn": 4, + "problem": "NoSignatureDistinctWithObjectPublicApi", + "suggest": "", + "rule": "The signature of a method in a class/interface cannot be different from the public interface in an object. (arkts-class-no-signature-distinct-with-object-public-api)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 18, + "endLine": 44, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Want\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 18, + "endLine": 49, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Want\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 52, + "endLine": 55, + "endColumn": 65, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"BusinessError\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance3.ets.json b/ets2panda/linter/test/main/method_inheritance3.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance3.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_positive.ets b/ets2panda/linter/test/main/method_inheritance_positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..89011c52f9835ab1d2639058c246ac37f304fe1d --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_positive.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 II{ + pp(key:string,value:string):void + fun(num:number):string; +} + +class CC implements II{ + pp(key: string,value?:string):void { //ok + } + + fun(num?: number): string { //ok + return "123"; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance_positive.ets.args.json b/ets2panda/linter/test/main/method_inheritance_positive.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_positive.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_positive.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance_positive.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_positive.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/method_inheritance_positive.ets.json b/ets2panda/linter/test/main/method_inheritance_positive.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_positive.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_ts.ts b/ets2panda/linter/test/main/method_inheritance_ts.ts new file mode 100644 index 0000000000000000000000000000000000000000..f11bbedb831cd5ff67a788774352e3f06c1ae4ea --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_ts.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export abstract class AAA { + abstract test():any; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance_ts.ts.json b/ets2panda/linter/test/main/method_inheritance_ts.ts.json new file mode 100644 index 0000000000000000000000000000000000000000..a28a98c2bdf6ac528e9f0331f9159cc3747913ce --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_ts.ts.json @@ -0,0 +1,28 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_class_omit_interface_optional.ets b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets new file mode 100644 index 0000000000000000000000000000000000000000..875ef361b3472e323ebf4138622eecd8395bf0c3 --- /dev/null +++ b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets @@ -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. + */ + +// 1) Required Fields +interface I1 { + a: number; + b: string; +} +class C1 implements I1 { // ✅ no error + a: number = 0.0; + b: string = ''; +} + +class C2 implements I1 { // ✅ no error - Required fields are already handled on ArkTS 1.1 + a: number = 0.0; +} + +// 2) Optional fields are treated as required +interface I3 { + foo?: string; + bar?: number; +} +class C3 implements I3 { // ❌ Error: missing both `foo` and `bar` (first missing stops checking) +} + +class C4 implements I3 { // ✅ no error + foo?: string; + bar?: number; +} + +// 3) Interface extends another +interface A5 { + p?: string; +} +interface B5 extends A5 { + q?: string; +} +class C5 implements B5 { // ✅ no error + p: string = 'hello'; + q: string = 'world'; +} +class C6 implements B5 { // ❌ Error: missing `q` + p: string = 'hello'; +} +class C61 implements B5 { // ❌ Error: missing `p` + q: string = 'hello'; +} + +// 4) Multiple interfaces at once +interface I6a { u?: number } +interface I6b { v?: boolean } +class C7 implements I6a, I6b { // ✅ no error + u: number = 42.0; + v: boolean = false; +} +class C8 implements I6a, I6b { // ❌ Error: missing `v` + u: number = 42.0; +} diff --git a/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.args.json b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/no_class_omit_interface_optional.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_class_omit_interface_optional.ets.arkts2.json b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5b06edf9f560f71c2bde4dbe84d29868c63a2267 --- /dev/null +++ b/ets2panda/linter/test/main/no_class_omit_interface_optional.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": 35, + "column": 7, + "endLine": 35, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 7, + "endLine": 57, + "endColumn": 10, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 7, + "endLine": 68, + "endColumn": 9, + "problem": "InterfaceFieldNotImplemented", + "suggest": "", + "rule": "ArkTS 1.2 should implement all optional fields from the interface in the class (arkts-no-class-omit-interface-optional-prop)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.json b/ets2panda/linter/test/main/no_class_omit_interface_optional.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/no_class_omit_interface_optional.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/no_enum_prop_as_type.ets.arkts2.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json index 5974b151459cc560e541b4b565b58b1bbfc11d17..be0d1b9493001b13e588a2405cc082e6429ec87e 100644 --- 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 @@ -21,7 +21,7 @@ "endColumn": 20, "problem": "NoEnumPropAsType", "suggest": "", - "rule": "Enum prop as type are not supported (arkts-no-enum-prop-as-type)", + "rule": "Enum elements cannot be types in ArkTS1.2 (arkts-no-enum-prop-as-type)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 11, "problem": "NoEnumPropAsType", "suggest": "", - "rule": "Enum prop as type are not supported (arkts-no-enum-prop-as-type)", + "rule": "Enum elements cannot be types in ArkTS1.2 (arkts-no-enum-prop-as-type)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/no_function_return_this.ets b/ets2panda/linter/test/main/no_function_return_this.ets new file mode 100644 index 0000000000000000000000000000000000000000..7642726e36ed3c8882ea0df6b8853513bde21077 --- /dev/null +++ b/ets2panda/linter/test/main/no_function_return_this.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 t1 = Function('return this')(); // error + +let t2 = Function("return this")(); // error + +let t3 = Function(`return this`)(); // error + +let t4 = new Function('return this')(); // error + +let fn = Function('return this'); // error +let t5 = fn(); + +let t6 = (Function)('return this')(); // error + +let t7 = (globalThis.Function)('return this')(); // error + +let t8 = (0, Function)('return this')(); // error + +let t9 = (Function.bind(null))('return this')(); // error + +const body = "return this"; +let t10 = Function(body)(); // error + +let a1 = Function('return 123')(); // legal + +let a2 = Function('return window')(); // legal + +let a3 = Function('x', 'return this')(); // legal + +const a4 = Function; // legal + +let a5 = Function("return somethingElse")(); // legal + +let a7 = SomeOtherConstructor('return this'); // legal \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_function_return_this.ets.args.json b/ets2panda/linter/test/main/no_function_return_this.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/no_function_return_this.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_function_return_this.ets.arkts2.json b/ets2panda/linter/test/main/no_function_return_this.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d47ccbc573e9ce67d4a48d24a75c6c9d0c8d5890 --- /dev/null +++ b/ets2panda/linter/test/main/no_function_return_this.ets.arkts2.json @@ -0,0 +1,468 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 33, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 33, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 33, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 33, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "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": 20, + "column": 10, + "endLine": 20, + "endColumn": 33, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 33, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 10, + "endLine": 22, + "endColumn": 37, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 10, + "endLine": 22, + "endColumn": 37, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 33, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "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": 12, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 10, + "endLine": 27, + "endColumn": 35, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 10, + "endLine": 27, + "endColumn": 35, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 11, + "endLine": 27, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 46, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 46, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 11, + "endLine": 29, + "endColumn": 30, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 30, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 10, + "endLine": 31, + "endColumn": 38, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 10, + "endLine": 31, + "endColumn": 38, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 11, + "endLine": 31, + "endColumn": 22, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 14, + "endLine": 31, + "endColumn": 22, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 46, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 24, + "problem": "FunctionBindError", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 25, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 25, + "problem": "NoFunctionReturnThis", + "suggest": "", + "rule": "Function(\"return this\") is not supported (arkts-no-function-return-this)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 10, + "endLine": 38, + "endColumn": 32, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 10, + "endLine": 40, + "endColumn": 35, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 38, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 12, + "endLine": 44, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 42, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 45, + "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/no_function_return_this.ets.json b/ets2panda/linter/test/main/no_function_return_this.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..44fc2a3c888b0d859694801338cdb7358a6be175 --- /dev/null +++ b/ets2panda/linter/test/main/no_function_return_this.ets.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": 16, + "column": 5, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "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": 22, + "column": 5, + "endLine": 22, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 11, + "endLine": 27, + "endColumn": 19, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 11, + "endLine": 29, + "endColumn": 21, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + }, + { + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 30, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 11, + "endLine": 31, + "endColumn": 22, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 14, + "endLine": 31, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 30, + "problem": "FunctionBind", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "WARNING" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 40, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 12, + "endLine": 44, + "endColumn": 20, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 45, + "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/no_import_concurrency.ets b/ets2panda/linter/test/main/no_import_concurrency.ets index d6f173602ac9b97d67ee5a86e8c873a096fc19ad..12769039210f812543bb434807bc6b4b49b77ca2 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets +++ b/ets2panda/linter/test/main/no_import_concurrency.ets @@ -17,10 +17,30 @@ 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 defaultImport, { 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 doo, { fooModule as fooAs, too } from '@kit.ArkTS'; +import bbbb, { taskpool as tsk, process as prs } from '@kit.ArkTS'; +import fooke from '@ohos.process'; +import { process as ps, collections as clt } from '@kit.ArkTS'; import process from '@ohos.process'; -import ArkTSUtils, { taskpool as tsk, process as prs } from '@kit.ArkTS'; \ No newline at end of file +import aaa from '@ohos.taskpool' +import aaaa from '@arkts.collections'; +import utils from './oh_modules/@arkts.utils' +import { ArkTSUtils } from './oh_modules/@kit.ArkTS'; + +aaa.getTaskPoolInfo() + +function concurrency () { + const aaa = 123; + console.log(aaa); +} + +ps.isIsolatedProcess(); +tsk.cancel(); +aaaa.Set() +clt.Set() +fooAs.getFoo(); + +let lock1: utils.locks.AsyncLock = utils.locks.AsyncLock.request('lock1'); +let lock2 = new ArkTSUtils.locks.AsyncLock(); diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json index 7d90da63697aff2fcbf4ea04318ef9be41fd6d1a..596eceebd8668d984395f76e620735b0f879b4ef 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json @@ -25,10 +25,10 @@ "severity": "ERROR" }, { - "line": 20, + "line": 19, "column": 8, - "endLine": 20, - "endColumn": 16, + "endLine": 19, + "endColumn": 12, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", @@ -36,9 +36,9 @@ }, { "line": 20, - "column": 20, + "column": 25, "endLine": 20, - "endColumn": 37, + "endColumn": 42, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", @@ -65,10 +65,20 @@ "severity": "ERROR" }, { - "line": 22, - "column": 15, - "endLine": 22, - "endColumn": 32, + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 31, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 33, + "endLine": 23, + "endColumn": 47, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", @@ -76,9 +86,9 @@ }, { "line": 24, - "column": 1, + "column": 8, "endLine": 24, - "endColumn": 47, + "endColumn": 13, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", @@ -86,9 +96,19 @@ }, { "line": 25, - "column": 1, + "column": 10, "endLine": 25, - "endColumn": 37, + "endColumn": 23, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 25, + "endLine": 25, + "endColumn": 43, "problem": "LimitedStdLibNoImportConcurrency", "suggest": "", "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", @@ -96,13 +116,73 @@ }, { "line": 26, - "column": 1, + "column": 8, "endLine": 26, - "endColumn": 74, + "endColumn": 15, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 11, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 12, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 13, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 20, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 28, + "endLine": 46, + "endColumn": 33, "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 index 2a756c0a4edcbb1429418311fc03b308492aa42e..06610d9db9efb567996b5c3b287178a67b509188 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 629, "end": 646, - "replacementText": "" + "replacementText": "", + "line": 17, + "column": 21, + "endLine": 17, + "endColumn": 36 } ], "suggest": "", @@ -32,16 +36,20 @@ "severity": "ERROR" }, { - "line": 20, + "line": 19, "column": 8, - "endLine": 20, - "endColumn": 16, + "endLine": 19, + "endColumn": 12, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 783, - "end": 793, - "replacementText": "" + "start": 726, + "end": 732, + "replacementText": "", + "line": 19, + "column": 8, + "endLine": 19, + "endColumn": 12 } ], "suggest": "", @@ -50,15 +58,19 @@ }, { "line": 20, - "column": 20, + "column": 25, "endLine": 20, - "endColumn": 37, + "endColumn": 42, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 795, - "end": 814, - "replacementText": "" + "start": 800, + "end": 819, + "replacementText": "", + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 42 } ], "suggest": "", @@ -73,9 +85,13 @@ "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 853, - "end": 872, - "replacementText": "" + "start": 858, + "end": 877, + "replacementText": "", + "line": 21, + "column": 15, + "endLine": 21, + "endColumn": 32 } ], "suggest": "", @@ -90,9 +106,13 @@ "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 870, - "end": 885, - "replacementText": "" + "start": 875, + "end": 890, + "replacementText": "", + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 47 } ], "suggest": "", @@ -100,16 +120,50 @@ "severity": "ERROR" }, { - "line": 22, - "column": 15, - "endLine": 22, - "endColumn": 32, + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 31, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 986, + "end": 1003, + "replacementText": "", + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 31 + }, + { + "start": 1467, + "end": 1470, + "replacementText": "taskpool", + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 33, + "endLine": 23, + "endColumn": 47, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 921, - "end": 940, - "replacementText": "" + "start": 1001, + "end": 1017, + "replacementText": "", + "line": 23, + "column": 33, + "endLine": 23, + "endColumn": 47 } ], "suggest": "", @@ -118,15 +172,49 @@ }, { "line": 24, - "column": 1, + "column": 8, "endLine": 24, - "endColumn": 47, + "endColumn": 13, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1039, + "end": 1073, + "replacementText": "", + "line": 24, + "column": 8, + "endLine": 24, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 23, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 1008, - "end": 1054, - "replacementText": "" + "start": 1083, + "end": 1098, + "replacementText": "", + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 23 + }, + { + "start": 1443, + "end": 1445, + "replacementText": "process", + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 23 } ], "suggest": "", @@ -135,15 +223,28 @@ }, { "line": 25, - "column": 1, + "column": 25, "endLine": 25, - "endColumn": 37, + "endColumn": 43, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 1055, - "end": 1091, - "replacementText": "" + "start": 1096, + "end": 1116, + "replacementText": "", + "line": 25, + "column": 25, + "endLine": 25, + "endColumn": 43 + }, + { + "start": 1492, + "end": 1495, + "replacementText": "collections", + "line": 25, + "column": 25, + "endLine": 25, + "endColumn": 43 } ], "suggest": "", @@ -152,15 +253,161 @@ }, { "line": 26, - "column": 1, + "column": 8, "endLine": 26, - "endColumn": 74, + "endColumn": 15, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 11, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1175, + "end": 1207, + "replacementText": "", + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 11 + }, + { + "start": 1348, + "end": 1351, + "replacementText": "taskpool", + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 12, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1208, + "end": 1246, + "replacementText": "", + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 12 + }, + { + "start": 1481, + "end": 1485, + "replacementText": "collections", + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 13, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1247, + "end": 1292, + "replacementText": "", + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 20, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1293, + "end": 1346, + "replacementText": "", + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1530, + "end": 1551, + "replacementText": "AsyncLock", + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 47 + }, + { + "start": 1554, + "end": 1592, + "replacementText": "AsyncLock.request('lock1')", + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 28, + "endLine": 46, + "endColumn": 33, "problem": "LimitedStdLibNoImportConcurrency", "autofix": [ { - "start": 1092, - "end": 1165, - "replacementText": "" + "start": 1606, + "end": 1638, + "replacementText": "new AsyncLock()", + "line": 46, + "column": 28, + "endLine": 46, + "endColumn": 33 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets index a7dc1cccd1e7d3efc28ac56813a2342e849546cc..5d2ec5d14fb83bcda4f828b21773ea366307ed60 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets @@ -16,10 +16,31 @@ 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 { fooClass } from '@ohos.taskpool'; //legal +import defaultImport, { roo } from '@kit.ArkTS'; import koo from '@kit.ArkTS'; -import doo, { too } from '@kit.ArkTS'; -import fooke from '@ohos.process'; //legal +import doo, { fooModule as fooAs, too } from '@kit.ArkTS'; +import bbbb from '@kit.ArkTS'; +import process from '@ohos.process'; + + + + + +taskpool.getTaskPoolInfo() + +function concurrency () { + const aaa = 123; + console.log(aaa); +} + +process.isIsolatedProcess(); +taskpool.cancel(); +Set() +Set() +fooAs.getFoo(); + +let lock1: AsyncLock = AsyncLock.request('lock1'); +let lock2 = new AsyncLock(); diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json index ca88f857e960b437dcf767c0ac40be998c8f1236..3eb706b6b61bad2cd1d323802d2d4a541cc204ef 100644 --- a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json @@ -13,5 +13,56 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 26, + "column": 8, + "endLine": 26, + "endColumn": 15, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "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": 42, + "column": 1, + "endLine": 42, + "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": 5, + "endLine": 46, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 17, + "endLine": 46, + "endColumn": 26, + "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/no_import_namespace_star_as_var.ets b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets new file mode 100644 index 0000000000000000000000000000000000000000..9047c6adaa90e6b51042b2fc658562ac1b77f991 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.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 * as host from './file1'; +const alias = host; // error +alias.run(); + +function getHost() { + return host; // error +} +const edgeCase = getHost(); + +function run(h: any) { + h.doSomething(); +} +run(host); // error + +host(); // error + +const { foo } = host; // error + +let g; +g = host; // error + +host.doSomething() // valid +new host.Host(); // valid + +const h2 = host.h2(); // valid + +function f1() { + return host.b(); // valid +} + +const fn = () => host.work(); // valid \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.args.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.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_import_namespace_star_as_var.ets.arkts2.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1266c69bfca5190fe69b7b4b806747aa9610c8d6 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.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": 7, + "endLine": 17, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 15, + "endLine": 17, + "endColumn": 19, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 14, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 9, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 5, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 17, + "endLine": 32, + "endColumn": 21, + "problem": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 6, + "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": "NoImportNamespaceStarAsVar", + "suggest": "", + "rule": "The namespace imported by import * as cannot be used as a variable (arkts-no-import-namespace-with-star-as-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 14, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 12, + "endLine": 46, + "endColumn": 29, + "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/no_import_namespace_star_as_var.ets.json b/ets2panda/linter/test/main/no_import_namespace_star_as_var.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..5714e6776f3b4184dfef47779816d432f445ec38 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_namespace_star_as_var.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": 7, + "endLine": 17, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 27, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 21, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 6, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 12, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 12, + "endLine": 46, + "endColumn": 29, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/no_local_class.ets b/ets2panda/linter/test/main/no_local_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..473c36c98ae0a17f8cb6fe9f48ebc42452cce939 --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// VALID: Class/interface can be declared outside of functions +class GlobalClass { } +interface GlobalInterface { } + +// INVALID: Class declared inside a function +function foo() { + class Boo { } +} + +// INVALID: Interface declared inside a function +function a() { + interface B { } +} + +// INVALID: Both class and interface declared inside a function +function b() { + interface C { } + class D { } +} + +// INVALID: Interface declared inside an arrow function +const poo = () => { + interface T { } +} + +// INVALID: Both interface and class declared inside an arrow function +const yoo = () => { + interface L { } + class Zoo { } +} + +// INVALID: Class declared inside an arrow function +const qoo = () => { + class Moo { } +} + +// INVALID: Class declared inside a function expression +const dest = function () { + class Doo { } +} + +// INVALID: Both class and interface declared inside a function expression +const test = function () { + class Koo { } + interface Goo { } +} + +// INVALID: Interface declared inside a function expression +const cast = function () { + interface Pop { } +} + +// INVALID: Class declared inside a top-level block statement +{ + class BlockLocal { } +} + +// INVALID: Interface declared inside a top-level block statement +{ + interface BlockIface { } +} + +// INVALID: Class declared inside an if block +if (true) { + class IfBlockClass { } +} + +// INVALID: Interface declared inside an if block +if (false) { + interface IfBlockIface { } +} + +// INVALID: Class declared inside a for loop block +for (let i = 0; i < 1; i++) { + class ForBlockClass { } +} + +// INVALID: Interface declared inside a for loop block +for (let i = 0; i < 1; i++) { + interface ForBlockIface { } +} + +// INVALID: Class declared inside a while loop block +while (false) { + class WhileBlockClass { } +} + +// INVALID: Interface declared inside a while loop block +while (false) { + interface WhileBlockIface { } +} + +// INVALID: Class declared inside a nested block (block inside block) +{ + { + class NestedBlockClass { } + } +} + +// INVALID: Interface declared inside a nested block (block inside block) +{ + { + interface NestedBlockIface { } + } +} + +// VALID: Type alias at top-level (should NOT warn) +type FooType = number; + +// NESTED CASE: Deeply nested class inside arrow functions +function xyc(): void { + const a1 = () => { + const b2 = () => { + class Abc { + + } + } + } +} + diff --git a/ets2panda/linter/test/main/no_local_class.ets.args.json b/ets2panda/linter/test/main/no_local_class.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d2ef7038fc686415cfc67c9806ba7d19391382df --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.args.json @@ -0,0 +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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/no_local_class.ets.arkts2.json b/ets2panda/linter/test/main/no_local_class.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..056ad84f0b073d29b0951d25cc71500fd0175fcf --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.arkts2.json @@ -0,0 +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": 22, + "column": 5, + "endLine": 22, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 16, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 20, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 14, + "endLine": 55, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 14, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 22, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 14, + "endLine": 66, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 22, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 25, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 29, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 27, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 31, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 28, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 5, + "endLine": 95, + "endColumn": 32, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 30, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 34, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 9, + "endLine": 111, + "endColumn": 35, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 9, + "endLine": 118, + "endColumn": 39, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 13, + "endLine": 131, + "endColumn": 14, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_local_class.ets.json b/ets2panda/linter/test/main/no_local_class.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8d562d8ee29ccac7c0610636aa5b7cc17b3c0c12 --- /dev/null +++ b/ets2panda/linter/test/main/no_local_class.ets.json @@ -0,0 +1,48 @@ +{ + "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": 53, + "column": 14, + "endLine": 55, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 14, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 14, + "endLine": 66, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/no_side_effect_import.ets.args.json b/ets2panda/linter/test/main/no_side_effect_import.ets.args.json index 4d93062f69db6d74420adeb506e0ca28c5580728..a89d885810708ad03d96e3e14bb6590efd1a7547 100755 --- a/ets2panda/linter/test/main/no_side_effect_import.ets.args.json +++ b/ets2panda/linter/test/main/no_side_effect_import.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/no_side_effect_import.ets.autofix.json b/ets2panda/linter/test/main/no_side_effect_import.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..4723887320a710cda4191b750032bd80aae8e28a --- /dev/null +++ b/ets2panda/linter/test/main/no_side_effect_import.ets.autofix.json @@ -0,0 +1,110 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 19, + "problem": "NoSideEffectImport", + "autofix": [ + { + "start": 610, + "end": 628, + "replacementText": "initModule(\"./logger\");", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Import for side-effect only is prohibited.(arkts-no-side-effect-import)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 23, + "problem": "NoSideEffectImport", + "autofix": [ + { + "start": 669, + "end": 691, + "replacementText": "initModule(\"./utils/init\");", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Import for side-effect only is prohibited.(arkts-no-side-effect-import)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 23, + "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": 45, + "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": 31, + "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": 34, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 40, + "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/main/no_side_effect_import.ets.migrate.ets b/ets2panda/linter/test/main/no_side_effect_import.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a70297d4caea562168c338d773124639dca8b6ce --- /dev/null +++ b/ets2panda/linter/test/main/no_side_effect_import.ets.migrate.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. + */ + +initModule("./logger"); +console.log("Main program running..."); +initModule("./utils/init"); + +import { cookBookTag } from './CookBookMsg'; +import Logger from './logger'; +import * as Utils from './utils'; + +import { initApp } from './utils/init'; + + diff --git a/ets2panda/linter/test/main/no_side_effect_import.ets.migrate.json b/ets2panda/linter/test/main/no_side_effect_import.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e6817505079c74e6aa9b918b489be9036ce13b40 --- /dev/null +++ b/ets2panda/linter/test/main/no_side_effect_import.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": 1, + "endLine": 20, + "endColumn": 45, + "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": 31, + "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": 34, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 40, + "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/main/no_sparse_array.ets b/ets2panda/linter/test/main/no_sparse_array.ets index 3298c36c9294e9ca7c6a20a5a0b06add4789a2d5..39116898dffd135353fa87d9dff42e8d81483934 100644 --- a/ets2panda/linter/test/main/no_sparse_array.ets +++ b/ets2panda/linter/test/main/no_sparse_array.ets @@ -13,5 +13,89 @@ * limitations under the License. */ -let a = [1, , , 3]; -let b = []; \ No newline at end of file +/* + * Shouldn't report (arkts-no-sparse-array) + */ + +let c: number[] = []; + +let i = Promise.race([1.0]); +let j = Promise.all([2.0]); +let k = Promise.allSettled([3.0]); +let l = Promise.any([4.0]); +let m = Promise.resolve([5.0]); + +let i1 = Promise.race([1]); +let j1 = Promise.all([2]); +let k1 = Promise.allSettled([3]); +let l1 = Promise.any([4]); +let m1 = Promise.resolve([5]); + +let bigInt64 = new BigInt64Array([1.0]); +let bigUint64 = new BigUint64Array([1.0]); +let floast64 = new Float64Array([1.0]); +let float32 = new Float32Array([1.0]); +let int32 = new Int32Array([1.0]); +let int64 = new Int16Array([1.0]); +let int8 = new Int8Array([1.0]); +let uint32 = new Uint32Array([1.0]); +let uint64 = new Uint16Array([1.0]); +let uint8 = new Uint8Array([1.0]); +let uint8Clamped = new Uint8ClampedArray([1.0]); + +let str1 = new String(['1']); +let bool1 = new Boolean(['1']); +let num1 = new Number(['1']); +let obj1 = new Object(['1']); + +function foo(arr: number[]) { + return; +} +foo([]); + +function foo1(arr: Array) { + return; +} +foo1([]); + +function foo2(a: T) { + return; +} +foo2([]); + +function foo3(a: T[]) { + return; +} +foo3([]); + +function foo4(a: T) { + return; +} +foo4([]); + +function foo5(a: T[]) { + return; +} +foo5([]); + +let set1 = new WeakSet(); +set1.has(['1']); +set1.add(['1']); +set1.delete(['1']); + +let map1 = new WeakMap(); +map1.has(['1']); +map1.set(['1'], ""); +map1.delete(['1']); +map1.get(['1']); + +let set2 = new Set(); +set2.has(['1']); +set2.add(['1']); +set2.delete(['1']); + +let map2 = new Map(); +map2.has(['1']); +map2.set(['1'], ""); +map2.delete(['1']); +map2.get(['1']); \ 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 index e6e42965237a4262fa2907e51c5dedcde372c47b..292a9e3ce5bc6d1089fdeb6b665bd91108636bac 100644 --- a/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json @@ -15,23 +15,83 @@ ], "result": [ { - "line": 16, + "line": 46, "column": 12, - "endLine": 16, - "endColumn": 12, - "problem": "NosparseArray", + "endLine": 46, + "endColumn": 29, + "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "Sparse array are not supported (arkts-no-sparse-array)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", "severity": "ERROR" }, { - "line": 16, - "column": 14, - "endLine": 16, - "endColumn": 14, - "problem": "NosparseArray", + "line": 46, + "column": 16, + "endLine": 46, + "endColumn": 22, + "problem": "BuiltinNewCtor", "suggest": "", - "rule": "Sparse array are not supported (arkts-no-sparse-array)", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 13, + "endLine": 47, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 17, + "endLine": 47, + "endColumn": 24, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 29, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 16, + "endLine": 48, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 16, + "endLine": 49, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 16, + "endLine": 86, + "endColumn": 23, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets b/ets2panda/linter/test/main/no_sparse_array2.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bc89431c2f8e74bb400e24b5fd3ffed829d8f86 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.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. + */ + +/* + * Should report (arkts-no-sparse-array) + */ + +let a = [1, , , 3]; +let b = []; + +let d = Promise.race([]); +let e = Promise.all([]); +let f = Promise.allSettled([]); +let g = Promise.any([]); +let h = Promise.resolve([]); + +let d1 = Promise.race([]); +let e1 = Promise.all([]); +let f1 = Promise.allSettled([]); +let g1 = Promise.any([]); +let h1 = Promise.resolve([]); + +let bigInt64 = new BigInt64Array([]); +let bigUint64 = new BigUint64Array([]); +let floast64 = new Float64Array([]); +let float32 = new Float32Array([]); +let int32 = new Int32Array([]); +let int64 = new Int16Array([]); +let int8 = new Int8Array([]); +let uint32 = new Uint32Array([]); +let uint64 = new Uint16Array([]); +let uint8 = new Uint8Array([]); +let uint8Clamped = new Uint8ClampedArray([]); + +let str1 = new String([]); +let bool1 = new Boolean([]); +let num1 = new Number([]); +let obj1 = new Object([]); + +let set1 = new WeakSet(); +set1.has([]); +set1.add([]); +set1.delete([]); + +let map1 = new WeakMap(); +map1.has([]); +map1.set([], ""); +map1.delete([]); +map1.get([]); + +let set2 = new Set(); +set2.has([]); +set2.add([]); +set2.delete([]); + +let map2 = new Map(); +map2.has([]); +map2.set([], ""); +map2.delete([]); +map2.get([]); \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.args.json b/ets2panda/linter/test/main/no_sparse_array2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ddcd120faf3e98361f3f7d57d51d0137c8c25fe0 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets.args.json @@ -0,0 +1,20 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } + } + \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json b/ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6451b27b1d10594592b9ee8a088760500444492c --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.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": 20, + "column": 12, + "endLine": 20, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 14, + "endLine": 20, + "endColumn": 14, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 11, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 30, + "endLine": 23, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 29, + "endLine": 24, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 36, + "endLine": 25, + "endColumn": 38, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 29, + "endLine": 26, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 35, + "endLine": 27, + "endColumn": 37, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 24, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 29, + "endLine": 31, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 24, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 28, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 34, + "endLine": 35, + "endColumn": 36, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 36, + "endLine": 36, + "endColumn": 38, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 35, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 32, + "endLine": 38, + "endColumn": 34, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 28, + "endLine": 39, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 28, + "endLine": 40, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 28, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 30, + "endLine": 42, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 30, + "endLine": 43, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 28, + "endLine": 44, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 44, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 16, + "endLine": 47, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 23, + "endLine": 47, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 13, + "endLine": 48, + "endColumn": 28, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 17, + "endLine": 48, + "endColumn": 24, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 25, + "endLine": 48, + "endColumn": 27, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 16, + "endLine": 49, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 23, + "endLine": 49, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 16, + "endLine": 50, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 23, + "endLine": 50, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 10, + "endLine": 53, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 15, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 16, + "endLine": 57, + "endColumn": 23, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 10, + "endLine": 58, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 10, + "endLine": 59, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 13, + "endLine": 60, + "endColumn": 15, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 10, + "endLine": 61, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 10, + "endLine": 64, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 15, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 10, + "endLine": 69, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 10, + "endLine": 70, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 13, + "endLine": 71, + "endColumn": 15, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.json b/ets2panda/linter/test/main/no_sparse_array2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets index 01a023bc1fb85ad7b5d4f8c352dd8ef27e1beb15..367815236a2855e0d75090a8dcf1bea2654df18e 100755 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets @@ -12,23 +12,365 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// static + +class AW { + private static instance:AW = new AW(); + static get():AW { + return AW.instance; // + } +} + +class AA { + public static instance?: number; + + getInstance(): number { + if (!AA.instance) { + return 0; + } + return AA.instance; // Error + } +} + class AA1 { - public static instance : number | string; - getInstance(): number { - if (AA1.instance instanceof string) { - return 0; - } - return AA1.instance; // Error + public static instance : Number | String | Object = "smart cast"; + getInstance(): Number { + if (!(AA1.instance instanceof Number)) { + return 0; } + return AA1.instance; // Error + } } class AA2 { - public instance : number | string; - getInstance(): number { - if (this.instance instanceof string) { - return 0; + public instance : Number | String | Object= 'smart cast'; + getInstance(): Number { + if (!(this.instance instanceof Number)) { + return 0; + } + return this.instance; // Error + } +} + +class AA3 { + public instance : number | String | Object = 'string'; + getInstance(): number { + if (this.instance instanceof String) { + return 0; + } else if (this.instance instanceof Object) { + return 1; + } + return this.instance; // Error + } +} + +function foo2(str:string){ +} +function foo22(str:number|string){ +} +function foo(spec :string|number){ + foo2(spec) // Error +} +function foo3(spec :string|number){ + if (typeof spec == "string") { + foo2(spec) // Error + } +} +function foo3(spec :string|number){ + if (typeof spec == "string") { + foo22(spec) + } +} + +const input = true; +if (typeof input === 'boolean') { +} else { + let result = input as string | number | null; // Error +} + +async function taskInfo():Promise {//nopass + for (let i:int = 0; i < 1000; i++) { + let taskpoolInfo: taskpool.TaskPoolInfo = taskpool.getTaskPoolInfo(); + hilog.info(0x0000, 'testTag-----',`getTaskPoolInfo: , ${JSON.stringify(taskpoolInfo)}`) + let tid: number = 0; + let taskIds: number[] = []; + let priority: int = 0; + let taskId: number = 0; + let state: number = 0; + let duration: number = 0; + let name: string = ""; + let threadIS: Array = Array.from(taskpoolInfo.threadInfos) + for (let threadInfo of threadIS) { + tid = threadInfo.tid; + if (threadInfo.taskIds != undefined && threadInfo.priority != undefined) { + priority = threadInfo.priority; // Error + } + hilog.info(0x0000, 'testTag-----',"getTaskPoolInfo: --tid is:" + tid + ", taskIds is:" + taskIds + ", priority is:" + priority); + } + let taskIS: Array = Array.from(taskpoolInfo.taskInfos) + for (let taskInfo of taskIS) { + taskId = taskInfo.taskId; + state = taskInfo.state; + if (taskInfo.duration != undefined) { + duration = taskInfo.duration as number; // Error + name = taskInfo.name; + } + hilog.info(0x0000, 'testTag-----',"getTaskPoolInfo: --taskId is:" + taskId + ", state is:" + state + ", duration is:" + duration + + ", name is:" + name); + } + } +} + +class A { + f(): number| null { + return 1 + } +} + +class B { + a?:A = new A() +} +let b = new B() +if(b.a && b.a.f() !== null){ //Error + console.log('23') +} + +if (b.a.f() !== null) { //Error + console.log('warn'); +} +if (b.a?.f() !== null) { + console.log('ok'); +} +function check(obj?: A) { + if (obj.f() !== null) { //Error + console.log('warn'); + } +} +if ((b.a?.f() ?? 0) > 0) { + console.log('ok'); +} +const val = b.a.f(); //Error + + +function foo4(uri: string | number | boolean) : string { + return uri as string +} + +class AA5 { + public static starUrl(url: string) { + if (url?startsWith('http')) { + url = `https:/test?appid=2000?url=${foo4(url)}`; + } + } +} + + +function sleep(ms: number): PromiseLike { + return new Promise( + (resolve: (value: T | PromiseLike) => void): number => setTimeout(resolve, ms) + ); +} + +type TypeA = (key: string) => string | undefined + +class ClassA { + static sA?: TypeA = undefined + + static funA(key: string): string | undefined { + if (ClassA.sA) { + return ClassA.sA(key) //error + } + else { + return undefined; + } + } +} + +class AT { + b?: boolean + + isRelease(): boolean { + if (this.b != undefined) { + return this.b //error } - return this.instance; // Error } +} + +export class K { + _t:string + constructor(t:string) { + this._t = t; + } +} + +export class P extends K { + constructor(t:string){ + super(t) + } + toString(): string { + return this._t // legal + } +} + +export class H { + protected _t:string + constructor(t:string) { + this._t = t; + } +} + +export class T extends H { + constructor(t:string) { + super(t) + } +} + +export class N extends T { + constructor(t:string){ + super(t) + } + toString(): string { + return this._t // legal + } +} + +type AsyncCB = () => T | Promise; + +class AsyncLock { + lockAsync(callback: AsyncCB): Promise { + } +} + +export class AB { + private count_: number = 0 + public lock_: AsyncLock = new AsyncLock(); + + public async getCount(): Promise { + return this.lock_.lockAsync(() => { + return this.count_; //legal + }) + } +} + +class AG { +h?: number; +f(): number | null { + return 1; +} +} + +function check(obj?: AG) { +if (obj) { + console.log(obj.f()); // valid(guarded) +} +if (obj !== undefined) { + obj.f(); // valid(guarded) +} +} + +function check4(obj?: AG) { + +if (!obj) { + return; +} +obj.f(); // valid(guarded) +} +function check2(obj?: AG) { +obj.f(); // ERROR + +if (obj == null) return; +obj.f(); // valid(guarded) + +} +function check3(obj?: AG) { + +return obj ? obj.f() : null; // guarded in ternary + +} + +function check35(obj?: AG) { + +if (obj.h == 3) { //error + console.log('3'); +} + +} + +function check36(obj?: AG) { + +if (obj && obj.h == 3) { // valid(guarded) + console.log('3'); +} + +} + +function check43(obj?: AG) { +const val = obj.h; // NOT guarded +return val; +} + +} + +let NextID: number = 1; + +class downloadFilesData { + id: number; + url: string; + fileStatus: number; + downloadTime: number; + + constructor( + url: string = '', + fileStatus: number = 0, + downloadTime: number = 0, + ) { + this.id = NextID++; + this.url = url; + this.fileStatus = fileStatus; + this.downloadTime = downloadTime; + } +} + +class Downloader { + downloadFileArray: downloadFilesData[] = []; + + loadInitializationDataSource() { + let stringData = JSON.stringify([ + { + "url": "https://example.com/file1.zip", + "fileStatus": 1, + "downloadTime": 1734931200 + }, + { + "url": "https://example.com/file2.mp4", + "fileStatus": 0, + "downloadTime": 0 + }, + { + "url": "https://example.com/file3.pdf", + "fileStatus": 2, + "downloadTime": 1734931300 + } + ]); + + let data: [] = JSON.parse(stringData) as []; + + for (let i = 0; i < data.length; i++) { + const downloadItemData = data[i] as downloadFilesData; + let downloadData: downloadFilesData = new downloadFilesData( + downloadItemData.url, + downloadItemData.fileStatus, + downloadItemData.downloadTime + ); + this.downloadFileArray.push(downloadData); + } + } +} + +function isOperator(operator) { + return (operator === '+' || operator === "-") +} +function test(value: string) { + if (isOperator(value)) { //no error + console.log('5') + } } \ No newline at end of file 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 old mode 100755 new mode 100644 index ac0ca437fc37cfdeba0681473bb96adf041defe1..e62b41b88259ffcc40d2716fc777308e6fe69436 --- 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 @@ -1,57 +1,403 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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, + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 24, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 25, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 26, "problem": "NoTsLikeSmartType", "suggest": "", "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, { - "line": 17, + "line": 62, "column": 5, - "endLine": 17, - "endColumn": 46, - "problem": "ClassstaticInitialization", + "endLine": 62, + "endColumn": 26, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 12, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 77, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 10, + "endLine": 75, + "endColumn": 14, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 1, + "endLine": 82, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 11, + "endLine": 80, + "endColumn": 15, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 16, + "endLine": 87, + "endColumn": 47, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 66, + "endLine": 93, + "endColumn": 75, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 66, + "endLine": 93, + "endColumn": 75, + "problem": "BuiltinNarrowTypes", "suggest": "", - "rule": "The static property has no initializer (arkts-class-static-initialization)", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", "severity": "ERROR" }, { - "line": 32, + "line": 101, + "column": 54, + "endLine": 101, + "endColumn": 58, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 38, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 50, + "endLine": 109, + "endColumn": 54, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 114, "column": 9, - "endLine": 32, - "endColumn": 30, + "endLine": 114, + "endColumn": 47, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 10, "problem": "NoTsLikeSmartType", "suggest": "", "rule": "Smart type differences (arkts-no-ts-like-smart-type)", "severity": "ERROR" }, { - "line": 27, - "column": 12, - "endLine": 27, - "endColumn": 20, + "line": 143, + "column": 1, + "endLine": 147, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 7, + "endLine": 144, + "endColumn": 12, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 13, + "endLine": 151, + "endColumn": 18, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 6, + "endLine": 169, + "endColumn": 47, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 10, + "endLine": 170, + "endColumn": 4, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 13, + "endLine": 180, + "endColumn": 34, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 13, + "endLine": 193, + "endColumn": 26, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 261, + "column": 1, + "endLine": 268, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 6, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 10, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 18, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 337, + "column": 27, + "endLine": 337, + "endColumn": 36, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 337, + "column": 27, + "endLine": 337, + "endColumn": 36, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 357, + "column": 25, + "endLine": 357, + "endColumn": 36, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 369, + "column": 21, + "endLine": 369, + "endColumn": 29, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 369, + "column": 21, + "endLine": 369, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'b.a' is possibly 'undefined'.", + "rule": "'b.a' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 144, + "column": 7, + "endLine": 144, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 151, + "column": 13, + "endLine": 151, + "endColumn": 16, + "problem": "StrictDiagnostic", + "suggest": "'b.a' is possibly 'undefined'.", + "rule": "'b.a' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 191, + "column": 18, + "endLine": 191, + "endColumn": 25, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 16, "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.", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", "severity": "ERROR" } ] 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 old mode 100755 new mode 100644 index b9d40bdd285aa64170a36db11902a97e7d2644a9..996a2de958ed13a4bc7319d32937a07b7e84fb85 --- a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json @@ -1,27 +1,173 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR 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, + "line": 339, + "column": 9, + "endLine": 339, + "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": 340, + "column": 9, + "endLine": 340, + "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": 341, + "column": 9, + "endLine": 341, + "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": 344, + "column": 9, + "endLine": 344, + "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": 345, + "column": 9, + "endLine": 345, + "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": 346, + "column": 9, + "endLine": 346, + "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": 349, + "column": 9, + "endLine": 349, + "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": 350, + "column": 9, + "endLine": 350, + "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": 351, + "column": 9, + "endLine": 351, + "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": 369, + "column": 21, + "endLine": 369, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'b.a' is possibly 'undefined'.", + "rule": "'b.a' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 144, + "column": 7, + "endLine": 144, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 151, + "column": 13, + "endLine": 151, + "endColumn": 16, + "problem": "StrictDiagnostic", + "suggest": "'b.a' is possibly 'undefined'.", + "rule": "'b.a' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 191, + "column": 18, + "endLine": 191, + "endColumn": 25, + "problem": "StrictDiagnostic", + "suggest": "Function lacks ending return statement and return type does not include 'undefined'.", + "rule": "Function lacks ending return statement and return type does not include 'undefined'.", + "severity": "ERROR" + }, + { + "line": 278, + "column": 1, + "endLine": 278, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 292, + "column": 5, + "endLine": 292, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", + "severity": "ERROR" + }, + { + "line": 307, + "column": 13, + "endLine": 307, + "endColumn": 16, "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.", + "suggest": "'obj' is possibly 'undefined'.", + "rule": "'obj' is possibly 'undefined'.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets b/ets2panda/linter/test/main/no_tuples_arrays.ets index 93ab572c518a56e3ecb59350ba3da3ffacd46945..1ebcd176a478517a6d3e452b55fd97c9eed5e686 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets @@ -87,4 +87,44 @@ 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 +let array20: (number)[] = originalArray as (number)[] //error + +const inputArray: readonly [Record, [], () => void] = [ + {}, + [], + () => { + } +]; +const even = (element: Record | [] | (() => void)): boolean => { + return typeof element === 'function'; +}; +const res = inputArray.some(even); // error +console.log("res:" + JSON.stringify(res)); +console.log(''+inputArray.length) // error +console.log(inputArray.toString()) // error +typeof inputArray.toLocaleString(); // error +function getConcat() { + inputArray.concat(); // error + return inputArray.join(','); // error +} +class Demo{ + set(){ + inputArray.slice(1,2); // error + inputArray.indexOf([]); // error + } + get(){ + return inputArray.lastIndexOf([]); // error + } +} +inputArray.every(()=>{}) // error +inputArray.some(()=>{}) // error +inputArray.forEach(()=>{}) // error +inputArray.map(()=>{}) // error +inputArray.filter(()=>{}) // error +inputArray.reduce((acc, item) => acc + 1, 0); // error +inputArray.reduceRight((acc, item) => acc + 1, 0); // error +inputArray.find((item) => Array.isArray(item)); // error +inputArray.includes(() => {}); // error +inputArray.flat() // error +inputArray.flatMap((item) => [item]); // error +inputArray.findIndex((item) => typeof item === 'function'); // 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 b86a5ddb8048138ad9dac388e43b063f791fc0b7..2928b0dcbda2b118ad4d1be81a4d1d631e8b099a 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json @@ -35,13 +35,13 @@ "severity": "ERROR" }, { - "line": 25, - "column": 13, - "endLine": 25, - "endColumn": 59, - "problem": "ArrayTypeImmutable", + "line": 30, + "column": 16, + "endLine": 30, + "endColumn": 21, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -54,16 +54,6 @@ "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 types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 65, "column": 7, @@ -74,16 +64,6 @@ "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 types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 67, "column": 7, @@ -94,16 +74,6 @@ "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 types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 68, "column": 7, @@ -114,16 +84,6 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, - { - "line": 68, - "column": 7, - "endLine": 68, - "endColumn": 53, - "problem": "ArrayTypeImmutable", - "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 70, "column": 5, @@ -134,16 +94,6 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, - { - "line": 70, - "column": 5, - "endLine": 70, - "endColumn": 53, - "problem": "ArrayTypeImmutable", - "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 73, "column": 5, @@ -154,16 +104,6 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, - { - "line": 73, - "column": 5, - "endLine": 73, - "endColumn": 43, - "problem": "ArrayTypeImmutable", - "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 74, "column": 5, @@ -174,16 +114,6 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, - { - "line": 74, - "column": 5, - "endLine": 74, - "endColumn": 48, - "problem": "ArrayTypeImmutable", - "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 75, "column": 5, @@ -194,16 +124,6 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, - { - "line": 75, - "column": 5, - "endLine": 75, - "endColumn": 50, - "problem": "ArrayTypeImmutable", - "suggest": "", - "rule": "Array types follow the principle of invariance (arkts-array-type-immutable)", - "severity": "ERROR" - }, { "line": 78, "column": 35, @@ -274,6 +194,16 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 88, + "column": 17, + "endLine": 88, + "endColumn": 34, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, { "line": 89, "column": 34, @@ -293,6 +223,266 @@ "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" + }, + { + "line": 101, + "column": 13, + "endLine": 101, + "endColumn": 28, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 27, + "endLine": 102, + "endColumn": 36, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 27, + "endLine": 102, + "endColumn": 36, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 16, + "endLine": 103, + "endColumn": 33, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 13, + "endLine": 104, + "endColumn": 32, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 33, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 3, + "endLine": 107, + "endColumn": 20, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 10, + "endLine": 108, + "endColumn": 25, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 5, + "endLine": 112, + "endColumn": 21, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 5, + "endLine": 113, + "endColumn": 23, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 12, + "endLine": 116, + "endColumn": 34, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 1, + "endLine": 119, + "endColumn": 17, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 1, + "endLine": 120, + "endColumn": 16, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 1, + "endLine": 121, + "endColumn": 19, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 15, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 1, + "endLine": 123, + "endColumn": 18, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 1, + "endLine": 124, + "endColumn": 18, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 1, + "endLine": 125, + "endColumn": 23, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 1, + "endLine": 126, + "endColumn": 16, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 33, + "endLine": 126, + "endColumn": 40, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 1, + "endLine": 127, + "endColumn": 20, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 12, + "endLine": 128, + "endColumn": 16, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 1, + "endLine": 128, + "endColumn": 16, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 12, + "endLine": 129, + "endColumn": 19, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 1, + "endLine": 129, + "endColumn": 19, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 1, + "endLine": 130, + "endColumn": 21, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" } ] } \ 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 index 74f1bf97da9e34c1f36711bb6468ee900ae9664f..a8479c4635e10285b980707d889cd92f6e7f0088 100755 --- a/ets2panda/linter/test/main/numeric_bigint_compare.ets +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets @@ -31,4 +31,53 @@ n1 + n2 n1 - n2 n1 * n2 n1 / n2 -n1 % n2 \ No newline at end of file +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.arkts2.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json index 30d46ababf470e719634f542093610e798cbeb0d..f9f56938e8812e05d522f2528dce33763ae05180 100755 --- a/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json @@ -93,6 +93,356 @@ "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_semantics.ets b/ets2panda/linter/test/main/numeric_semantics.ets index e09d8b47cf7c1fe4bde0f446600b80eaa943059f..93b8ad6528e80e8ed23cc17c542f6511a86f8707 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets +++ b/ets2panda/linter/test/main/numeric_semantics.ets @@ -104,9 +104,9 @@ identity(42); let an_array = [1,2,3] -let g = an_array[] +let g2 = an_array[] -const a = 1 +const a2 = 1 enum Test { A = 1, // 显式赋值为 1 @@ -142,7 +142,8 @@ export class G{ const fingerprintPositionY = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; -private doCloseFolderBackgroundAnimation(): void { +class Layout { + private doCloseFolderBackgroundAnimation(): void { openFolderLayout.getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight; openFolderLayout.getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth; @@ -161,9 +162,10 @@ private doCloseFolderBackgroundAnimation(): void { openFolderLayout.getGridSwiperLayout().bgTranslateY = pos[1] + editModeTranslateY - openFolderLayout.getBackgroundLayout().closedHeight * 0.5 - openFolderLayout.getBackgroundLayout().openedMargin; } + } } -let f = 0.0; +let f2 = 0.0; let b5: number = 0; f = b5; // OK @@ -182,9 +184,9 @@ e = e | 3; // OK let arr1 = [1,2,3] e += arr1[0]; // OK -let a = 0.0; -a = fun1(); -a = fun2()!; +let a3 = 0.0; +a3 = fun1(); +a3 = fun2()!; function fun1():number{ return 1; @@ -196,10 +198,79 @@ function fun2():number|undefined{ import { ArrayList } from "@kit.ArkTS"; -let arr = new ArrayList() +let arr2 = new ArrayList() for (let i:number = 0; i < 100; i++) { - arr.add(i) + arr2.add(i) +} +let cancelIds:ArrayList = arr2.subArrayList(6, 86) +let arr3: Array = Array.from(cancelIds) +let arr4: Array = Array.from(new ArrayList()) + +let a4: number = 0.000; + +const b4: number = 0.000; + +export enum WalletStageValue { + DEFAULT = 0, + SWIPE_INIT = -1, + SELECT_CARD = 1, + SWIPE_DOING = 2, + SWIPE_SUCCEED = 3, + SWIPE_FAILED = 4, + SWIPE_FINISHED = 5, } -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 + +export enum AnimationStage { + INIT = 0, + ENTER = 1, + ROTATING = 2, + EXIT_START = 3, + EXIT_END = 4, +} + +class C { + public static readonly SIX_MONTH = 180 * 24 * 60 * 60 * 1000 +} + +function testIndentation(): void { + let a = (() => { + console.log('hello'); + return 0; + })(); +} + +@Sendable +export function add(a: number, b: number) { + console.log("SharedModule: Hap call ShareFile add"); + return a + b; +} +let a : [number, number, boolean] = [1, 1, true] +a = [2, 2, false] +a = [2.0/3, 3/4.0, false] + +let arr:number[] = [1, 2, 3] +arr = [2, 3, 4] +arr[0] = 2/3; +arr = [1/3, 2/3, 4] + +let arrT:Array = [1, 2, 3, 4] +let arrB:Array = arrT??[0] +let arr3:Array = [1, 2, 3, 4] + +let b:boolean = true +let arr:number[] = [1, 2, 3] +let arr1:int[] = [1, 2, 3] +let arr2:number[] = b? arr : [0, 1, 2] + +let arrE = [1, 2, 3, 4] +let arrA:Array = arrE||[1, 2, 3, 4] + +let a : [number, number, boolean] = [1, 1, true] +let b = 2 + +a = [b/3, 1/b, false] + +let arr:number[] = [1, 2, 3] +let a = 2 +arr[0] = a/3; +arr = [1/a, 2/3, a/3] \ 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 old mode 100755 new mode 100644 index 1c60c7069a211b8bbfcfcc317c24be08c56d5f6e..9ad06d0111700544d6270aeb6495bb332b348832 --- a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json @@ -1,678 +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": 18, - "column": 5, - "endLine": 18, - "endColumn": 10, - "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": 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": 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": 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": 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": 166, - "column": 5, - "endLine": 166, - "endColumn": 12, - "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": 182, - "column": 5, - "endLine": 182, - "endColumn": 19, - "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": 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": 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" - } - ] +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": "DefiniteAssignmentError", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 19, + "endLine": 92, + "endColumn": 24, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 26, + "endLine": 92, + "endColumn": 31, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 19, + "endLine": 107, + "endColumn": 19, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "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": 152, + "column": 9, + "endLine": 152, + "endColumn": 61, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 61, + "endLine": 161, + "endColumn": 67, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 61, + "endLine": 162, + "endColumn": 67, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 6, + "endLine": 185, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 1, + "endLine": 199, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 5, + "endLine": 201, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 16, + "endLine": 201, + "endColumn": 25, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 33, + "endLine": 206, + "endColumn": 37, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 33, + "endLine": 207, + "endColumn": 37, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 42, + "endLine": 207, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 242, + "column": 1, + "endLine": 242, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 10, + "endLine": 249, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 13, + "endLine": 249, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 253, + "column": 1, + "endLine": 253, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 253, + "column": 10, + "endLine": 253, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 253, + "column": 12, + "endLine": 253, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 8, + "endLine": 254, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 10, + "endLine": 254, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 13, + "endLine": 254, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 15, + "endLine": 254, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 33, + "endLine": 257, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 31, + "endLine": 263, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 34, + "endLine": 263, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 37, + "endLine": 263, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 33, + "endLine": 266, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 36, + "endLine": 266, + "endColumn": 37, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 39, + "endLine": 266, + "endColumn": 40, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 266, + "column": 42, + "endLine": 266, + "endColumn": 43, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 8, + "endLine": 271, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 11, + "endLine": 271, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 275, + "column": 1, + "endLine": 275, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 275, + "column": 12, + "endLine": 275, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 8, + "endLine": 276, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 13, + "endLine": 276, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 15, + "endLine": 276, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 20, + "endLine": 276, + "endColumn": 21, + "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": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 2, + "endLine": 118, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 4, + "endLine": 120, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 5, + "endLine": 129, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RelativeContainer\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 7, + "endLine": 130, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 46, + "endLine": 154, + "endColumn": 56, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 34, + "endLine": 156, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json index ea3285da99caa6e5cd5ba6bbcb174127c6a514bf..d9ef5529e7526267f44670cc306186743bbd979c 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json @@ -15,345 +15,191 @@ ], "result": [ { - "line": 18, + "line": 57, "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 - } - ], + "endLine": 57, + "endColumn": 15, + "problem": "DefiniteAssignmentError", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "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 - } - ], + "line": 92, + "column": 19, + "endLine": 92, + "endColumn": 24, + "problem": "ParameterType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "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 - } - ], + "line": 92, + "column": 26, + "endLine": 92, + "endColumn": 31, + "problem": "ParameterType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", "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 - } - ], + "line": 107, + "column": 19, + "endLine": 107, + "endColumn": 19, + "problem": "ArrayIndexExprType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "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 - } - ], + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 123, + "problem": "AnyType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 57, - "column": 5, - "endLine": 57, - "endColumn": 15, - "problem": "DefiniteAssignmentError", + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 61, + "problem": "AnyType", "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "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 - } - ], + "line": 161, + "column": 61, + "endLine": 161, + "endColumn": 67, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "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 - } - ], + "line": 162, + "column": 61, + "endLine": 162, + "endColumn": 67, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "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 - } - ], + "line": 185, + "column": 6, + "endLine": 185, + "endColumn": 13, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "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 - } - ], + "line": 199, + "column": 1, + "endLine": 199, + "endColumn": 40, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 67, + "line": 201, "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 - } - ], + "endLine": 201, + "endColumn": 35, + "problem": "AnyType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "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 - } - ], + "line": 201, + "column": 16, + "endLine": 201, + "endColumn": 25, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "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 - } - ], + "line": 206, + "column": 33, + "endLine": 206, + "endColumn": 37, + "problem": "BuiltinDisableApi", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API has been disabled (arkts-builtin-disable-api)", "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 - } - ], + "line": 207, + "column": 33, + "endLine": 207, + "endColumn": 37, + "problem": "BuiltinDisableApi", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API has been disabled (arkts-builtin-disable-api)", "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 - } - ], + "line": 207, + "column": 42, + "endLine": 207, + "endColumn": 51, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 14, - "problem": "NumericSemantics", + "line": 242, + "column": 1, + "endLine": 242, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", "autofix": [ { - "start": 2061, - "end": 2070, - "replacementText": "t3: number = -234", - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 14 + "start": 5687, + "end": 5696, + "replacementText": "", + "line": 242, + "column": 1, + "endLine": 242, + "endColumn": 10 } ], "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" }, { - "line": 87, - "column": 5, - "endLine": 87, - "endColumn": 26, + "line": 249, + "column": 10, + "endLine": 249, + "endColumn": 11, "problem": "NumericSemantics", "autofix": [ { - "start": 2079, - "end": 2100, - "replacementText": "num: number = Math.floor(4.8)", - "line": 87, - "column": 5, - "endLine": 87, - "endColumn": 26 + "start": 5898, + "end": 5899, + "replacementText": "3.0", + "line": 249, + "column": 10, + "endLine": 249, + "endColumn": 11 } ], "suggest": "", @@ -361,20 +207,20 @@ "severity": "ERROR" }, { - "line": 89, - "column": 5, - "endLine": 89, - "endColumn": 27, + "line": 249, + "column": 13, + "endLine": 249, + "endColumn": 14, "problem": "NumericSemantics", "autofix": [ { - "start": 2124, - "end": 2146, - "replacementText": "value: number = parseInt(\"42\")", - "line": 89, - "column": 5, - "endLine": 89, - "endColumn": 27 + "start": 5901, + "end": 5902, + "replacementText": "3.0", + "line": 249, + "column": 13, + "endLine": 249, + "endColumn": 14 } ], "suggest": "", @@ -382,41 +228,30 @@ "severity": "ERROR" }, { - "line": 92, + "line": 253, "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 - } - ], + "endLine": 253, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, + "line": 253, + "column": 10, + "endLine": 253, + "endColumn": 11, "problem": "NumericSemantics", "autofix": [ { - "start": 2195, - "end": 2200, - "replacementText": "y: number = 3", - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2 + "start": 5974, + "end": 5975, + "replacementText": "2.0", + "line": 253, + "column": 10, + "endLine": 253, + "endColumn": 11 } ], "suggest": "", @@ -424,20 +259,20 @@ "severity": "ERROR" }, { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, + "line": 253, + "column": 12, + "endLine": 253, + "endColumn": 13, "problem": "NumericSemantics", "autofix": [ { - "start": 2201, - "end": 2201, - "replacementText": ": number", - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2 + "start": 5976, + "end": 5977, + "replacementText": "3.0", + "line": 253, + "column": 12, + "endLine": 253, + "endColumn": 13 } ], "suggest": "", @@ -445,20 +280,20 @@ "severity": "ERROR" }, { - "line": 96, - "column": 1, - "endLine": 98, - "endColumn": 2, + "line": 254, + "column": 8, + "endLine": 254, + "endColumn": 9, "problem": "NumericSemantics", "autofix": [ { - "start": 2264, - "end": 2264, - "replacementText": ": number", - "line": 96, - "column": 1, - "endLine": 98, - "endColumn": 2 + "start": 5987, + "end": 5988, + "replacementText": "1.0", + "line": 254, + "column": 8, + "endLine": 254, + "endColumn": 9 } ], "suggest": "", @@ -466,20 +301,20 @@ "severity": "ERROR" }, { - "line": 103, - "column": 1, - "endLine": 103, - "endColumn": 13, + "line": 254, + "column": 10, + "endLine": 254, + "endColumn": 11, "problem": "NumericSemantics", "autofix": [ { - "start": 2347, - "end": 2359, - "replacementText": "identity(42)", - "line": 103, - "column": 1, - "endLine": 103, - "endColumn": 13 + "start": 5989, + "end": 5990, + "replacementText": "3.0", + "line": 254, + "column": 10, + "endLine": 254, + "endColumn": 11 } ], "suggest": "", @@ -487,20 +322,20 @@ "severity": "ERROR" }, { - "line": 105, - "column": 5, - "endLine": 105, - "endColumn": 23, + "line": 254, + "column": 13, + "endLine": 254, + "endColumn": 14, "problem": "NumericSemantics", "autofix": [ { - "start": 2368, - "end": 2386, - "replacementText": "an_array: number[] = [1, 2, 3]", - "line": 105, - "column": 5, - "endLine": 105, - "endColumn": 23 + "start": 5992, + "end": 5993, + "replacementText": "2.0", + "line": 254, + "column": 13, + "endLine": 254, + "endColumn": 14 } ], "suggest": "", @@ -508,20 +343,20 @@ "severity": "ERROR" }, { - "line": 107, - "column": 5, - "endLine": 107, - "endColumn": 19, + "line": 254, + "column": 15, + "endLine": 254, + "endColumn": 16, "problem": "NumericSemantics", "autofix": [ { - "start": 2394, - "end": 2408, - "replacementText": "g: number = an_array[]", - "line": 107, - "column": 5, - "endLine": 107, - "endColumn": 19 + "start": 5994, + "end": 5995, + "replacementText": "3.0", + "line": 254, + "column": 15, + "endLine": 254, + "endColumn": 16 } ], "suggest": "", @@ -529,30 +364,20 @@ "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, + "line": 257, + "column": 33, + "endLine": 257, + "endColumn": 34, "problem": "NumericSemantics", "autofix": [ { - "start": 2418, - "end": 2423, - "replacementText": "a: number = 1", - "line": 109, - "column": 7, - "endLine": 109, - "endColumn": 12 + "start": 6074, + "end": 6075, + "replacementText": "0.0", + "line": 257, + "column": 33, + "endLine": 257, + "endColumn": 34 } ], "suggest": "", @@ -560,20 +385,20 @@ "severity": "ERROR" }, { - "line": 115, - "column": 7, - "endLine": 115, - "endColumn": 20, + "line": 263, + "column": 31, + "endLine": 263, + "endColumn": 32, "problem": "NumericSemantics", "autofix": [ { - "start": 2493, - "end": 2506, - "replacementText": "test: number = Test.A", - "line": 115, - "column": 7, - "endLine": 115, - "endColumn": 20 + "start": 6226, + "end": 6227, + "replacementText": "0.0", + "line": 263, + "column": 31, + "endLine": 263, + "endColumn": 32 } ], "suggest": "", @@ -581,20 +406,20 @@ "severity": "ERROR" }, { - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 19, + "line": 263, + "column": 34, + "endLine": 263, + "endColumn": 35, "problem": "NumericSemantics", "autofix": [ { - "start": 2593, - "end": 2609, - "replacementText": "readonly c1: number = 1;", - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 19 + "start": 6229, + "end": 6230, + "replacementText": "1.0", + "line": 263, + "column": 34, + "endLine": 263, + "endColumn": 35 } ], "suggest": "", @@ -602,20 +427,20 @@ "severity": "ERROR" }, { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 21, + "line": 263, + "column": 37, + "endLine": 263, + "endColumn": 38, "problem": "NumericSemantics", "autofix": [ { - "start": 2620, - "end": 2638, - "replacementText": "readonly c4: number = 1.7;", - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 21 + "start": 6232, + "end": 6233, + "replacementText": "2.0", + "line": 263, + "column": 37, + "endLine": 263, + "endColumn": 38 } ], "suggest": "", @@ -623,20 +448,20 @@ "severity": "ERROR" }, { - "line": 123, - "column": 3, - "endLine": 123, - "endColumn": 23, + "line": 266, + "column": 33, + "endLine": 266, + "endColumn": 34, "problem": "NumericSemantics", "autofix": [ { - "start": 2651, - "end": 2671, - "replacementText": "readonly c5: number = 0x123;", - "line": 123, - "column": 3, - "endLine": 123, - "endColumn": 23 + "start": 6295, + "end": 6296, + "replacementText": "1.0", + "line": 266, + "column": 33, + "endLine": 266, + "endColumn": 34 } ], "suggest": "", @@ -644,20 +469,20 @@ "severity": "ERROR" }, { - "line": 124, - "column": 3, - "endLine": 124, - "endColumn": 23, + "line": 266, + "column": 36, + "endLine": 266, + "endColumn": 37, "problem": "NumericSemantics", "autofix": [ { - "start": 2683, - "end": 2703, - "replacementText": "readonly c6: number = 0o123;", - "line": 124, - "column": 3, - "endLine": 124, - "endColumn": 23 + "start": 6298, + "end": 6299, + "replacementText": "2.0", + "line": 266, + "column": 36, + "endLine": 266, + "endColumn": 37 } ], "suggest": "", @@ -665,20 +490,20 @@ "severity": "ERROR" }, { - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 23, + "line": 266, + "column": 39, + "endLine": 266, + "endColumn": 40, "problem": "NumericSemantics", "autofix": [ { - "start": 2713, - "end": 2733, - "replacementText": "readonly c7: number = 0b101;", - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 23 + "start": 6301, + "end": 6302, + "replacementText": "3.0", + "line": 266, + "column": 39, + "endLine": 266, + "endColumn": 40 } ], "suggest": "", @@ -686,20 +511,20 @@ "severity": "ERROR" }, { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 24, + "line": 266, + "column": 42, + "endLine": 266, + "endColumn": 43, "problem": "NumericSemantics", "autofix": [ { - "start": 2743, - "end": 2764, - "replacementText": "readonly c8: number[] = [1, 2, 3];", - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 24 + "start": 6304, + "end": 6305, + "replacementText": "4.0", + "line": 266, + "column": 42, + "endLine": 266, + "endColumn": 43 } ], "suggest": "", @@ -707,20 +532,20 @@ "severity": "ERROR" }, { - "line": 137, - "column": 7, - "endLine": 137, - "endColumn": 13, + "line": 271, + "column": 8, + "endLine": 271, + "endColumn": 9, "problem": "NumericSemantics", "autofix": [ { - "start": 2893, - "end": 2899, - "replacementText": "c1: number = 1", - "line": 137, - "column": 7, - "endLine": 137, - "endColumn": 13 + "start": 6380, + "end": 6381, + "replacementText": "3.0", + "line": 271, + "column": 8, + "endLine": 271, + "endColumn": 9 } ], "suggest": "", @@ -728,20 +553,20 @@ "severity": "ERROR" }, { - "line": 140, - "column": 3, - "endLine": 140, - "endColumn": 19, + "line": 271, + "column": 11, + "endLine": 271, + "endColumn": 12, "problem": "NumericSemantics", "autofix": [ { - "start": 2923, - "end": 2939, - "replacementText": "readonly a5: number = 4;", - "line": 140, - "column": 3, - "endLine": 140, - "endColumn": 19 + "start": 6383, + "end": 6384, + "replacementText": "1.0", + "line": 271, + "column": 11, + "endLine": 271, + "endColumn": 12 } ], "suggest": "", @@ -749,30 +574,30 @@ "severity": "ERROR" }, { - "line": 143, - "column": 7, - "endLine": 143, - "endColumn": 123, - "problem": "AnyType", + "line": 275, + "column": 1, + "endLine": 275, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 143, - "column": 30, - "endLine": 143, - "endColumn": 118, + "line": 275, + "column": 12, + "endLine": 275, + "endColumn": 13, "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 + "start": 6450, + "end": 6451, + "replacementText": "3.0", + "line": 275, + "column": 12, + "endLine": 275, + "endColumn": 13 } ], "suggest": "", @@ -780,238 +605,20 @@ "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": 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": 166, - "column": 5, - "endLine": 166, - "endColumn": 12, + "line": 276, + "column": 8, + "endLine": 276, + "endColumn": 9, "problem": "NumericSemantics", "autofix": [ { - "start": 4388, - "end": 4395, - "replacementText": "f: number = 0.0", - "line": 166, - "column": 5, - "endLine": 166, - "endColumn": 12 + "start": 6461, + "end": 6462, + "replacementText": "1.0", + "line": 276, + "column": 8, + "endLine": 276, + "endColumn": 9 } ], "suggest": "", @@ -1019,20 +626,20 @@ "severity": "ERROR" }, { - "line": 170, - "column": 5, - "endLine": 170, - "endColumn": 12, + "line": 276, + "column": 13, + "endLine": 276, + "endColumn": 14, "problem": "NumericSemantics", "autofix": [ { - "start": 4440, - "end": 4447, - "replacementText": "e: number = 0.0", - "line": 170, - "column": 5, - "endLine": 170, - "endColumn": 12 + "start": 6466, + "end": 6467, + "replacementText": "2.0", + "line": 276, + "column": 13, + "endLine": 276, + "endColumn": 14 } ], "suggest": "", @@ -1040,20 +647,20 @@ "severity": "ERROR" }, { - "line": 182, - "column": 5, - "endLine": 182, - "endColumn": 19, + "line": 276, + "column": 15, + "endLine": 276, + "endColumn": 16, "problem": "NumericSemantics", "autofix": [ { - "start": 4627, - "end": 4641, - "replacementText": "arr1: number[] = [1, 2, 3]", - "line": 182, - "column": 5, - "endLine": 182, - "endColumn": 19 + "start": 6468, + "end": 6469, + "replacementText": "3.0", + "line": 276, + "column": 15, + "endLine": 276, + "endColumn": 16 } ], "suggest": "", @@ -1061,66 +668,26 @@ "severity": "ERROR" }, { - "line": 185, - "column": 5, - "endLine": 185, - "endColumn": 12, + "line": 276, + "column": 20, + "endLine": 276, + "endColumn": 21, "problem": "NumericSemantics", "autofix": [ { - "start": 4670, - "end": 4677, - "replacementText": "a: number = 0.0", - "line": 185, - "column": 5, - "endLine": 185, - "endColumn": 12 + "start": 6473, + "end": 6474, + "replacementText": "3.0", + "line": 276, + "column": 20, + "endLine": 276, + "endColumn": 21 } ], "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": 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, @@ -1131,15 +698,15 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -1152,15 +719,15 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -1173,15 +740,15 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -1194,15 +761,15 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"RelativeContainer\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -1215,15 +782,15 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -1236,78 +803,78 @@ { "start": 738, "end": 738, - "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", - "line": 155, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 153, + "line": 154, "column": 46, - "endLine": 153, + "endLine": 154, "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, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 154, + "line": 155, "column": 33, - "endLine": 154, + "endLine": 155, "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, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 155, + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "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, + "replacementText": "\r\n\r\nimport {\n Entry,\n Component,\n State,\n RelativeContainer,\n Text,\n AppStorage,\n} from '@kit.ArkUI';\r\n", + "line": 156, "column": 34, - "endLine": 155, + "endLine": 156, "endColumn": 44 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.json b/ets2panda/linter/test/main/numeric_semantics.ets.json index 47737941ad04d6a390c617f5cd735c817853aba8..2104782a9f9aedaf0c50e2b0a6d5c1fd03818c0e 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.json @@ -34,40 +34,20 @@ "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, + "endColumn": 61, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 197, + "line": 199, "column": 1, - "endLine": 197, + "endLine": 199, "endColumn": 40, "problem": "ImportAfterStatement", "suggest": "", @@ -75,10 +55,10 @@ "severity": "ERROR" }, { - "line": 199, + "line": 201, "column": 5, - "endLine": 199, - "endColumn": 34, + "endLine": 201, + "endColumn": 35, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets index 9afe1bb1ba8e09470a91547241062e05ae050111..fdb28136f6fa9a3ae53ec3a7018f891425223564 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets @@ -1,211 +1,286 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT 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; - -a = 1; // OK -a = 1.5; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' - -a += 1; // OK -a += 1.5; // ArkTS: Result is integer value - -console.log(a + 1); // OK -console.log(a - 0.5); // OK -console.log(a / 2); // ArkTS: integer division is used, result is integer value -console.log(a / 2.5); // OK -console.log(2 / a); // ArkTS: integer division is used, result is integer value -console.log(2.5 / a); // OK - -let b: number = 1; -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; -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; - -let f: number = 1 - -let g: number[] = [1, 2, 3] - -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; - -const oo:number = 123; - -let o2: number = o; - -let o3: number = oo; - -class A{ - a: number = 1; - constructor() { - } -} - -let t2: number = +123; - -let t3: number = -234; - -let num: number = Math.floor(4.8); // num 可能是 int - -let value: number = parseInt("42"); // value 可能是 int - - -function multiply(x: number = 2, y: number = 3): number { - return x * y; -} - -function divide(x: number, y: number): number { - return x / y; -} - -function identity(value: T): T { - return value; -} -identity(42); - -let an_array: number[] = [1, 2, 3] - -let g: number = an_array[] - -const a: number = 1 - -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; // 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, 2, 3]; - -build() { - RelativeContainer() { - Text(this.message) - .onClick(() => { - }) - } - } -} - -const c1: number = 1; - -export class G{ - readonly a5: number = 4; -} - -const fingerprintPositionY: number = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 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 - }); - return undefined; -})() { - 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: number = 0.0; -let b5: number = 0; -f = b5; // OK - -let e: number = 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: number[] = [1, 2, 3] -e += arr1[0]; // OK - -let a: number = 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 +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 = 1; + +a = 1; // OK +a = 1.5; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' + +a += 1; // OK +a += 1.5; // ArkTS: Result is integer value + +console.log(a + 1); // OK +console.log(a - 0.5); // OK +console.log(a / 2); // ArkTS: integer division is used, result is integer value +console.log(a / 2.5); // OK +console.log(2 / a); // ArkTS: integer division is used, result is integer value +console.log(2.5 / a); // OK + +let b: number = 1; +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 = 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 = 2; +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 = 2; + +let f: number = 1 + +let g = [1, 2, 3] + +let x!: number + +let t8 = Infinity + +let t9 = -Infinity; + +let t10 = NaN; + +let t11 = Number.MAX_VALUE; + +let t12 = Number.MIN_VALUE; + +let o:number = 123; + +const oo:number = 123; + +let o2 = o; + +let o3 = oo; + +class A{ + a = 1; + constructor() { + } +} + +let t2 = +123; + +let t3 = -234; + +let num = Math.floor(4.8); // num 可能是 int + +let value = parseInt("42"); // value 可能是 int + + +function multiply(x = 2, y = 3) { + return x * y; +} + +function divide(x: number, y: number) { + return x / y; +} + +function identity(value: T): T { + return value; +} +identity(42); + +let an_array = [1,2,3] + +let g2 = an_array[] + +const a2 = 1 + +enum Test { + A = 1, // 显式赋值为 1 + B = 2 // 显式赋值为 2 +} +const test = Test.A; + +@Entry +@Component +struct Index2 { + @State message: string = 'Hello World'; + readonly c1 = 1; // int + readonly c4 = 1.7; // float + readonly c5 = 0x123; // 16进制 + readonly c6 = 0o123; //8进制 + readonly c7 = 0b101; //2进制 + readonly c8 = [1,2,3] + +build() { + RelativeContainer() { + Text(this.message) + .onClick(() => { + }) + } + } +} + +const c1 = 1; + +export class G{ + readonly a5 = 4; +} + +const fingerprintPositionY = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; + +class Layout { + 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 f2 = 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 a3 = 0.0; +a3 = fun1(); +a3 = fun2()!; + +function fun1():number{ + return 1; +} + +function fun2():number|undefined{ + return 1; +} + +import { ArrayList } from "@kit.ArkTS"; + +let arr2 = new ArrayList() +for (let i:number = 0; i < 100; i++) { + arr2.add(i) +} +let cancelIds:ArrayList = arr2.subArrayList(6, 86) +let arr3: Array = Array.from(cancelIds) +let arr4: Array = Array.from(new ArrayList()) + +let a4: number = 0.000; + +const b4: number = 0.000; + +export enum WalletStageValue { + DEFAULT = 0, + SWIPE_INIT = -1, + SELECT_CARD = 1, + SWIPE_DOING = 2, + SWIPE_SUCCEED = 3, + SWIPE_FAILED = 4, + SWIPE_FINISHED = 5, +} + +export enum AnimationStage { + INIT = 0, + ENTER = 1, + ROTATING = 2, + EXIT_START = 3, + EXIT_END = 4, +} + +class C { + public static readonly SIX_MONTH = 180 * 24 * 60 * 60 * 1000 +} + +function testIndentation(): void { + let a = (() => { + console.log('hello'); + return 0; + })(); +} + + +export function add(a: number, b: number) { + console.log("SharedModule: Hap call ShareFile add"); + return a + b; +} +let a : [number, number, boolean] = [1, 1, true] +a = [2, 2, false] +a = [2.0/3.0, 3.0/4.0, false] + +let arr:number[] = [1, 2, 3] +arr = [2, 3, 4] +arr[0] = 2.0/3.0; +arr = [1.0/3.0, 2.0/3.0, 4] + +let arrT:Array = [1, 2, 3, 4] +let arrB:Array = arrT??[0.0] +let arr3:Array = [1, 2, 3, 4] + +let b:boolean = true +let arr:number[] = [1, 2, 3] +let arr1:int[] = [1, 2, 3] +let arr2:number[] = b? arr : [0.0, 1.0, 2.0] + +let arrE = [1, 2, 3, 4] +let arrA:Array = arrE||[1.0, 2.0, 3.0, 4.0] + +let a : [number, number, boolean] = [1, 1, true] +let b = 2 + +a = [b/3.0, 1.0/b, false] + +let arr:number[] = [1, 2, 3] +let a = 2 +arr[0] = a/3.0; +arr = [1.0/a, 2.0/3.0, a/3.0] \ 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 index c86c2373e15de875d2b44d53c7a5dc66cf1713bf..cf68563bf6a9491008fe543192b0e7f222a31478 100644 --- a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 60, + "line": 67, "column": 5, - "endLine": 60, + "endLine": 67, "endColumn": 15, "problem": "DefiniteAssignmentError", "suggest": "", @@ -25,59 +25,89 @@ "severity": "ERROR" }, { - "line": 110, + "line": 102, + "column": 19, + "endLine": 102, + "endColumn": 24, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 102, "column": 26, - "endLine": 110, - "endColumn": 26, + "endLine": 102, + "endColumn": 31, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 19, + "endLine": 117, + "endColumn": 19, "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", + "line": 153, + "column": 7, + "endLine": 153, + "endColumn": 123, + "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": 155, + "line": 162, "column": 9, - "endLine": 155, - "endColumn": 20, - "problem": "ObjectLiteralProperty", + "endLine": 162, + "endColumn": 61, + "problem": "AnyType", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 155, - "column": 9, - "endLine": 155, - "endColumn": 11, - "problem": "InvalidIdentifier", + "line": 171, + "column": 61, + "endLine": 171, + "endColumn": 67, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 155, - "column": 12, - "endLine": 155, - "endColumn": 15, - "problem": "AnyType", + "line": 172, + "column": 61, + "endLine": 172, + "endColumn": 67, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 203, + "line": 195, + "column": 6, + "endLine": 195, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 209, "column": 1, - "endLine": 203, + "endLine": 209, "endColumn": 40, "problem": "ImportAfterStatement", "suggest": "", @@ -85,34 +115,154 @@ "severity": "ERROR" }, { - "line": 205, + "line": 211, "column": 5, - "endLine": 205, - "endColumn": 34, + "endLine": 211, + "endColumn": 35, "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, + "line": 211, + "column": 16, + "endLine": 211, + "endColumn": 25, "problem": "DynamicCtorCall", "suggest": "", "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 211, + "line": 216, + "column": 33, + "endLine": 216, + "endColumn": 37, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 33, + "endLine": 217, + "endColumn": 37, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 217, "column": 42, - "endLine": 211, + "endLine": 217, "endColumn": 51, "problem": "DynamicCtorCall", "suggest": "", "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" + }, + { + "line": 263, + "column": 1, + "endLine": 263, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 267, + "column": 33, + "endLine": 267, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 31, + "endLine": 273, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 36, + "endLine": 273, + "endColumn": 39, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 41, + "endLine": 273, + "endColumn": 44, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 33, + "endLine": 276, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 38, + "endLine": 276, + "endColumn": 41, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 43, + "endLine": 276, + "endColumn": 46, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 276, + "column": 48, + "endLine": 276, + "endColumn": 51, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 285, + "column": 1, + "endLine": 285, + "endColumn": 7, + "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/numeric_semantics2.ets b/ets2panda/linter/test/main/numeric_semantics2.ets new file mode 100755 index 0000000000000000000000000000000000000000..a0e35fcfbc7bc83e1b4e6332703bd76a251d3bbb --- /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)) +} 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/main/numeric_semantics2.ets.arkts2.json b/ets2panda/linter/test/main/numeric_semantics2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..12f28e66711f937726a80b38848564117619c283 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.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": 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": 20, + "endLine": 35, + "endColumn": 26, + "problem": "LiteralAsPropertyName", + "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", + "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", + "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": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 32, + "endLine": 37, + "endColumn": 33, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "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": 44, + "column": 17, + "endLine": 44, + "endColumn": 19, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 17, + "endLine": 45, + "endColumn": 23, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "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" + }, + { + "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" + } + ] +} \ No newline at end of file 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..d671e2706faab7c752d987cf09f2a6f24b173a4b --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.autofix.json @@ -0,0 +1,367 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 20, + "endLine": 35, + "endColumn": 26, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "name", + "start": 1117, + "end": 1123, + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 26 + }, + { + "replacementText": "name", + "start": 1210, + "end": 1216, + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 26 + } + ], + "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": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 32, + "endLine": 37, + "endColumn": 33, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "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": 44, + "column": 17, + "endLine": 44, + "endColumn": 19, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 17, + "endLine": 45, + "endColumn": 23, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "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" + }, + { + "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" + } + ] +} \ 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..8a8c673288e2c3df5153d902e0072cef1bc9a602 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.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": 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": 18, + "endLine": 37, + "endColumn": 24, + "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..1a3f3584ac9c3e187dd8a5e4bcef562e96e8591f --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.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)) +} 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..f2d1d9a281fa87364de772b606e7c77aca3299f3 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.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": 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": 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": 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": 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": 44, + "column": 17, + "endLine": 44, + "endColumn": 19, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 17, + "endLine": 45, + "endColumn": 23, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "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" + }, + { + "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" + } + ] +} \ No newline at end of file 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 5f107cd9acf91e6c0e34bb23e215062f712baa54..919b9ae1f271465ebb7ea8ec70df45ff071b7d1e 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json @@ -34,12 +34,20 @@ { "start": 1131, "end": 1131, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n}\n", + "line": 33, + "column": 12, + "endLine": 33, + "endColumn": 13 }, { "start": 1139, "end": 1139, - "replacementText": ": GeneratedObjectLiteralInterface_1" + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 33, + "column": 12, + "endLine": 33, + "endColumn": 13 } ], "suggest": "", @@ -56,12 +64,20 @@ { "start": 1146, "end": 1146, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n hello: string;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n hello: string;\n}\n", + "line": 34, + "column": 12, + "endLine": 34, + "endColumn": 13 }, { "start": 1154, "end": 1154, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_2", + "line": 34, + "column": 12, + "endLine": 34, + "endColumn": 13 } ], "suggest": "", @@ -88,12 +104,20 @@ { "start": 1177, "end": 1177, - "replacementText": "interface GeneratedObjectLiteralInterface_3 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_3 {\n a: number;\n b: number;\n}\n", + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 14 }, { "start": 1186, "end": 1186, - "replacementText": ": GeneratedObjectLiteralInterface_3" + "replacementText": ": GeneratedObjectLiteralInterface_3", + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 14 } ], "suggest": "", @@ -110,12 +134,20 @@ { "start": 1203, "end": 1203, - "replacementText": "interface GeneratedObjectLiteralInterface_5 {\n field: string;\n field1: number;\n field2: string;\n field3: number;\n field4: boolean;\n field5: boolean;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_5 {\n field: string;\n field1: number;\n field2: string;\n field3: number;\n field4: boolean;\n field5: boolean;\n}\n", + "line": 36, + "column": 12, + "endLine": 36, + "endColumn": 13 }, { "start": 1211, "end": 1211, - "replacementText": ": GeneratedObjectLiteralInterface_5" + "replacementText": ": GeneratedObjectLiteralInterface_5", + "line": 36, + "column": 12, + "endLine": 36, + "endColumn": 13 } ], "suggest": "", @@ -142,12 +174,20 @@ { "start": 1385, "end": 1385, - "replacementText": "interface GeneratedObjectLiteralInterface_6 {\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_6 {\n}\n", + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 9 }, { "start": 1464, "end": 1466, - "replacementText": "({} as GeneratedObjectLiteralInterface_6)" + "replacementText": "({} as GeneratedObjectLiteralInterface_6)", + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 9 } ], "suggest": "", @@ -164,12 +204,20 @@ { "start": 1385, "end": 1385, - "replacementText": "interface GeneratedObjectLiteralInterface_10 {\n a: number;\n b: string;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_10 {\n a: number;\n b: string;\n}\n", + "line": 52, + "column": 8, + "endLine": 52, + "endColumn": 9 }, { "start": 1475, "end": 1491, - "replacementText": "({ a: 1, b: '2' } as GeneratedObjectLiteralInterface_10)" + "replacementText": "({ a: 1, b: '2' } as GeneratedObjectLiteralInterface_10)", + "line": 52, + "column": 8, + "endLine": 52, + "endColumn": 9 } ], "suggest": "", @@ -186,12 +234,20 @@ { "start": 1385, "end": 1385, - "replacementText": "interface GeneratedObjectLiteralInterface_13 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_13 {\n q: number;\n w: number;\n}\n", + "line": 53, + "column": 8, + "endLine": 53, + "endColumn": 9 }, { "start": 1500, "end": 1536, - "replacementText": "({ q: 10,\n w: 20 } as GeneratedObjectLiteralInterface_13)" + "replacementText": "({ q: 10,\n w: 20 } as GeneratedObjectLiteralInterface_13)", + "line": 53, + "column": 8, + "endLine": 53, + "endColumn": 9 } ], "suggest": "", @@ -218,12 +274,20 @@ { "start": 1541, "end": 1541, - "replacementText": "interface GeneratedObjectLiteralInterface_14 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_14 {\n q: number;\n w: number;\n}\n", + "line": 61, + "column": 8, + "endLine": 61, + "endColumn": 9 }, { "start": 1583, "end": 1599, - "replacementText": "({ q: 10, w: 20 } as GeneratedObjectLiteralInterface_14)" + "replacementText": "({ q: 10, w: 20 } as GeneratedObjectLiteralInterface_14)", + "line": 61, + "column": 8, + "endLine": 61, + "endColumn": 9 } ], "suggest": "", @@ -240,12 +304,20 @@ { "start": 1541, "end": 1541, - "replacementText": "interface GeneratedObjectLiteralInterface_16 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_16 {\n q: number;\n w: number;\n}\n", + "line": 63, + "column": 8, + "endLine": 63, + "endColumn": 9 }, { "start": 1621, "end": 1637, - "replacementText": "({ q: 30, w: 40 } as GeneratedObjectLiteralInterface_16)" + "replacementText": "({ q: 30, w: 40 } as GeneratedObjectLiteralInterface_16)", + "line": 63, + "column": 8, + "endLine": 63, + "endColumn": 9 } ], "suggest": "", @@ -262,12 +334,20 @@ { "start": 1687, "end": 1687, - "replacementText": "interface GeneratedObjectLiteralInterface_17 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_17 {\n a: number;\n b: number;\n}\n", + "line": 67, + "column": 12, + "endLine": 67, + "endColumn": 13 }, { "start": 1698, "end": 1710, - "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_17)" + "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_17)", + "line": 67, + "column": 12, + "endLine": 67, + "endColumn": 13 } ], "suggest": "", @@ -284,12 +364,20 @@ { "start": 1687, "end": 1687, - "replacementText": "interface GeneratedObjectLiteralInterface_18 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_18 {\n a: number;\n b: number;\n}\n", + "line": 67, + "column": 29, + "endLine": 67, + "endColumn": 30 }, { "start": 1715, "end": 1727, - "replacementText": "({ a: 3, b: 4 } as GeneratedObjectLiteralInterface_18)" + "replacementText": "({ a: 3, b: 4 } as GeneratedObjectLiteralInterface_18)", + "line": 67, + "column": 29, + "endLine": 67, + "endColumn": 30 } ], "suggest": "", @@ -316,12 +404,20 @@ { "start": 1731, "end": 1731, - "replacementText": "interface GeneratedObjectLiteralInterface_19 {\n x: number;\n y: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_19 {\n x: number;\n y: number;\n}\n", + "line": 71, + "column": 9, + "endLine": 71, + "endColumn": 10 }, { "start": 1773, "end": 1783, - "replacementText": "{ x: 1, y: 2 } as GeneratedObjectLiteralInterface_19" + "replacementText": "{ x: 1, y: 2 } as GeneratedObjectLiteralInterface_19", + "line": 71, + "column": 9, + "endLine": 71, + "endColumn": 10 } ], "suggest": "", @@ -338,12 +434,20 @@ { "start": 1731, "end": 1731, - "replacementText": "interface GeneratedObjectLiteralInterface_20 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_20 {\n q: number;\n w: number;\n}\n", + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 13 }, { "start": 1797, "end": 1807, - "replacementText": "({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_20)" + "replacementText": "({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_20)", + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 13 } ], "suggest": "", @@ -360,12 +464,20 @@ { "start": 1731, "end": 1731, - "replacementText": "interface GeneratedObjectLiteralInterface_21 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_21 {\n q: number;\n w: number;\n}\n", + "line": 72, + "column": 27, + "endLine": 72, + "endColumn": 28 }, { "start": 1812, "end": 1822, - "replacementText": "({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_21)" + "replacementText": "({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_21)", + "line": 72, + "column": 27, + "endLine": 72, + "endColumn": 28 } ], "suggest": "", @@ -382,12 +494,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_22 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_22 {\n a: number;\n b: number;\n}\n", + "line": 77, + "column": 10, + "endLine": 77, + "endColumn": 11 }, { "start": 1890, "end": 1890, - "replacementText": ": GeneratedObjectLiteralInterface_22" + "replacementText": ": GeneratedObjectLiteralInterface_22", + "line": 77, + "column": 10, + "endLine": 77, + "endColumn": 11 } ], "suggest": "", @@ -404,12 +524,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_23 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_23 {\n a: number;\n b: number;\n}\n", + "line": 78, + "column": 11, + "endLine": 78, + "endColumn": 12 }, { "start": 1914, "end": 1914, - "replacementText": ": GeneratedObjectLiteralInterface_23" + "replacementText": ": GeneratedObjectLiteralInterface_23", + "line": 78, + "column": 11, + "endLine": 78, + "endColumn": 12 } ], "suggest": "", @@ -436,12 +564,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_24 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_24 {\n a: number;\n b: number;\n}\n", + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 12 }, { "start": 1938, "end": 1938, - "replacementText": ": GeneratedObjectLiteralInterface_24" + "replacementText": ": GeneratedObjectLiteralInterface_24", + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 12 } ], "suggest": "", @@ -458,12 +594,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_25 {\n c: number;\n d: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_25 {\n c: number;\n d: number;\n}\n", + "line": 80, + "column": 11, + "endLine": 80, + "endColumn": 12 }, { "start": 1965, "end": 1977, - "replacementText": "{ c: 3, d: 4 } as GeneratedObjectLiteralInterface_25" + "replacementText": "{ c: 3, d: 4 } as GeneratedObjectLiteralInterface_25", + "line": 80, + "column": 11, + "endLine": 80, + "endColumn": 12 } ], "suggest": "", @@ -480,12 +624,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_26 {\n e: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_26 {\n e: number;\n}\n", + "line": 81, + "column": 10, + "endLine": 81, + "endColumn": 11 }, { "start": 1989, "end": 1995, - "replacementText": "({ e: 5 } as GeneratedObjectLiteralInterface_26)" + "replacementText": "({ e: 5 } as GeneratedObjectLiteralInterface_26)", + "line": 81, + "column": 10, + "endLine": 81, + "endColumn": 11 } ], "suggest": "", @@ -502,12 +654,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_27 {\n f: number;\n g: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_27 {\n f: number;\n g: number;\n}\n", + "line": 81, + "column": 21, + "endLine": 81, + "endColumn": 22 }, { "start": 2000, "end": 2012, - "replacementText": "({ f: 6, g: 7 } as GeneratedObjectLiteralInterface_27)" + "replacementText": "({ f: 6, g: 7 } as GeneratedObjectLiteralInterface_27)", + "line": 81, + "column": 21, + "endLine": 81, + "endColumn": 22 } ], "suggest": "", @@ -524,12 +684,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_28 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_28 {\n a: number;\n b: number;\n}\n", + "line": 84, + "column": 17, + "endLine": 84, + "endColumn": 18 }, { "start": 2040, "end": 2040, - "replacementText": ": GeneratedObjectLiteralInterface_28" + "replacementText": ": GeneratedObjectLiteralInterface_28", + "line": 84, + "column": 17, + "endLine": 84, + "endColumn": 18 } ], "suggest": "", @@ -546,12 +714,20 @@ { "start": 1874, "end": 1874, - "replacementText": "interface GeneratedObjectLiteralInterface_29 {\n c: number;\n d: number;\n e: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_29 {\n c: number;\n d: number;\n e: number;\n}\n", + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 18 }, { "start": 2068, "end": 2068, - "replacementText": ": GeneratedObjectLiteralInterface_29" + "replacementText": ": GeneratedObjectLiteralInterface_29", + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 18 } ], "suggest": "", @@ -568,12 +744,20 @@ { "start": 2150, "end": 2150, - "replacementText": "interface GeneratedObjectLiteralInterface_30 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_30 {\n a: number;\n b: number;\n}\n", + "line": 90, + "column": 22, + "endLine": 90, + "endColumn": 23 }, { "start": 2168, "end": 2168, - "replacementText": ": GeneratedObjectLiteralInterface_30" + "replacementText": ": GeneratedObjectLiteralInterface_30", + "line": 90, + "column": 22, + "endLine": 90, + "endColumn": 23 } ], "suggest": "", @@ -610,12 +794,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_31 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_31 {\n a: number;\n b: number;\n}\n", + "line": 95, + "column": 13, + "endLine": 95, + "endColumn": 14 }, { "start": 2440, "end": 2440, - "replacementText": ": GeneratedObjectLiteralInterface_31" + "replacementText": ": GeneratedObjectLiteralInterface_31", + "line": 95, + "column": 13, + "endLine": 95, + "endColumn": 14 } ], "suggest": "", @@ -632,12 +824,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_32 {\n c: number;\n d: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_32 {\n c: number;\n d: number;\n}\n", + "line": 96, + "column": 13, + "endLine": 96, + "endColumn": 14 }, { "start": 2466, "end": 2466, - "replacementText": ": GeneratedObjectLiteralInterface_32" + "replacementText": ": GeneratedObjectLiteralInterface_32", + "line": 96, + "column": 13, + "endLine": 96, + "endColumn": 14 } ], "suggest": "", @@ -654,12 +854,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_33 {\n e: number;\n f: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_33 {\n e: number;\n f: number;\n}\n", + "line": 99, + "column": 17, + "endLine": 99, + "endColumn": 18 }, { "start": 2518, "end": 2518, - "replacementText": ": GeneratedObjectLiteralInterface_33" + "replacementText": ": GeneratedObjectLiteralInterface_33", + "line": 99, + "column": 17, + "endLine": 99, + "endColumn": 18 } ], "suggest": "", @@ -676,12 +884,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_34 {\n g: number;\n d: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_34 {\n g: number;\n d: number;\n}\n", + "line": 102, + "column": 13, + "endLine": 102, + "endColumn": 14 }, { "start": 2551, "end": 2551, - "replacementText": ": GeneratedObjectLiteralInterface_34" + "replacementText": ": GeneratedObjectLiteralInterface_34", + "line": 102, + "column": 13, + "endLine": 102, + "endColumn": 14 } ], "suggest": "", @@ -698,12 +914,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_35 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_35 {\n q: number;\n w: number;\n}\n", + "line": 102, + "column": 27, + "endLine": 102, + "endColumn": 28 }, { "start": 2568, "end": 2577, - "replacementText": "({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_35)" + "replacementText": "({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_35)", + "line": 102, + "column": 27, + "endLine": 102, + "endColumn": 28 } ], "suggest": "", @@ -720,12 +944,20 @@ { "start": 2408, "end": 2408, - "replacementText": "interface GeneratedObjectLiteralInterface_36 {\n q: number;\n w: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_36 {\n q: number;\n w: number;\n}\n", + "line": 102, + "column": 41, + "endLine": 102, + "endColumn": 42 }, { "start": 2582, "end": 2591, - "replacementText": "({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_36)" + "replacementText": "({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_36)", + "line": 102, + "column": 41, + "endLine": 102, + "endColumn": 42 } ], "suggest": "", @@ -752,6 +984,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 105, + "column": 22, + "endLine": 105, + "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": 106, "column": 13, @@ -852,12 +1094,20 @@ { "start": 3051, "end": 3051, - "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { }\n}\n\n" + "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { }\n}\n\n", + "line": 115, + "column": 13, + "endLine": 115, + "endColumn": 14 }, { "start": 3063, "end": 3073, - "replacementText": "new GeneratedObjectLiteralClass_1()" + "replacementText": "new GeneratedObjectLiteralClass_1()", + "line": 115, + "column": 13, + "endLine": 115, + "endColumn": 14 } ], "suggest": "", @@ -924,7 +1174,11 @@ { "start": 3759, "end": 3799, - "replacementText": "interface LocalType {\n a: number;\n b: string;\n}" + "replacementText": "interface LocalType {\n a: number;\n b: string;\n}", + "line": 134, + "column": 22, + "endLine": 134, + "endColumn": 23 } ], "suggest": "", @@ -1001,17 +1255,29 @@ { "start": 4281, "end": 4282, - "replacementText": "\"a\"" + "replacementText": "\"a\"", + "line": 145, + "column": 33, + "endLine": 145, + "endColumn": 34 }, { "start": 4291, "end": 4292, - "replacementText": "\"b\"" + "replacementText": "\"b\"", + "line": 145, + "column": 33, + "endLine": 145, + "endColumn": 34 }, { "start": 4301, "end": 4302, - "replacementText": "\"c\"" + "replacementText": "\"c\"", + "line": 145, + "column": 33, + "endLine": 145, + "endColumn": 34 } ], "suggest": "", @@ -1038,17 +1304,29 @@ { "start": 4356, "end": 4359, - "replacementText": "\"foo\"" + "replacementText": "\"foo\"", + "line": 151, + "column": 42, + "endLine": 151, + "endColumn": 43 }, { "start": 4368, "end": 4371, - "replacementText": "\"bar\"" + "replacementText": "\"bar\"", + "line": 151, + "column": 42, + "endLine": 151, + "endColumn": 43 }, { "start": 4410, "end": 4413, - "replacementText": "\"baz\"" + "replacementText": "\"baz\"", + "line": 151, + "column": 42, + "endLine": 151, + "endColumn": 43 } ], "suggest": "", @@ -1105,12 +1383,20 @@ { "start": 4701, "end": 4704, - "replacementText": "\"key\"" + "replacementText": "\"key\"", + "line": 171, + "column": 13, + "endLine": 171, + "endColumn": 14 }, { "start": 4719, "end": 4726, - "replacementText": "\"message\"" + "replacementText": "\"message\"", + "line": 171, + "column": 13, + "endLine": 171, + "endColumn": 14 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.json index ff838327c3663578824e6dc51fac496988831862..64ef2e22c1639978585dba7e13f3535698779448 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.json @@ -404,6 +404,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 105, + "column": 22, + "endLine": 105, + "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": 106, "column": 13, diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json index e69f8c28502e98e3389a8c244620b123c4cd1ca1..4526e7c2c56bcb761063266bd70ca5ff0a1936ba 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json @@ -84,6 +84,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 240, + "column": 22, + "endLine": 240, + "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": 241, "column": 13, diff --git a/ets2panda/linter/test/main/object_literals_properties.ets b/ets2panda/linter/test/main/object_literals_properties.ets index da4dacf6b6e45689b60d2deefe303a22360543ac..5c88953eb0847554c4dcfb3e311eb9a2963c80e1 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets +++ b/ets2panda/linter/test/main/object_literals_properties.ets @@ -242,4 +242,81 @@ class Derived3 extends Base3 { } let b3: Derived3 = { // Fixable m() { console.log(2); } -}; \ No newline at end of file +}; + +interface I4 { + map: Map; +} +let map:Map = new Map(); +let i4: I4 = {map}; + +class C6 { + map1: Map = new Map(); +} + +let map1:Map = new Map(); +let c6: C6 = {map1}; + +// Namespace typed object literals +namespace X { + export class C { + m() { + console.log("C - 1"); + } + } + + export interface I { + m(a: number, b: string): void; + } +} + +function test() { + let c: X.C = { + m() { + console.log("C - 2"); + } + } + + let i: X.I = { + m(): void { + console.log("I"); + } + } +} + +class FooBarBaz { + foo?: Map + bar?: string +} + +function baz(fooBar: Map) { + baz2({fooBar}); +} + +function baz2(fooBarBaz: FooBarBaz) { +} + +class JJ { + mm?: Map + aa?: string +} +const mm: Map = new Map(); +let nn: JJ = {mm} // no error + + +class DD { + tt?: Map + gg?: string +} +const tt: Map = new Map(); +let gg: DD = {tt} // error + +interface Q { + a:number; + foo():void; +} + +let w: Q = { + a:1.0, + foo(){} // no error +} \ 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 f9fc1047e86a36642e6e262c41779a581f640a7f..0b296788ca915485ba49fbc6dc37c45e1c5a1cc8 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.args.json @@ -1,21 +1,21 @@ { - "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." - ], - "mode": { - "arkts2": "", - "autofix": "--arkts-2", - "migrate": "--arkts-2" - } + "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." + ], + "mode": { + "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 8f19012800d443c8de18d3cf18e2da365f0defb2..8d07725babdcefd2208ae9c5eaa26c69641ac00e 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.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", @@ -74,16 +74,6 @@ "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": 33, "column": 17, @@ -214,36 +204,6 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "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": 13, - "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": 66, "column": 16, @@ -324,16 +284,6 @@ "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", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 91, "column": 12, @@ -374,36 +324,6 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "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": 104, - "column": 3, - "endLine": 104, - "endColumn": 11, - "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": 109, "column": 14, @@ -414,36 +334,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 111, - "column": 3, - "endLine": 111, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 3, - "endLine": 112, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 113, "column": 3, @@ -464,36 +354,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 117, - "column": 3, - "endLine": 117, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 3, - "endLine": 118, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 3, - "endLine": 119, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 120, "column": 3, @@ -524,36 +384,6 @@ "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": 126, - "column": 3, - "endLine": 126, - "endColumn": 11, - "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": 133, "column": 14, @@ -564,36 +394,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 134, - "column": 3, - "endLine": 134, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 3, - "endLine": 135, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 136, - "column": 3, - "endLine": 136, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 137, "column": 3, @@ -604,26 +404,6 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "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": 14, - "endLine": 141, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 142, "column": 25, @@ -724,6 +504,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 167, + "column": 3, + "endLine": 167, + "endColumn": 37, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 168, "column": 27, @@ -774,16 +564,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "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": 219, "column": 18, @@ -804,6 +584,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 226, + "column": 1, + "endLine": 228, + "endColumn": 2, + "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": 229, "column": 20, @@ -844,6 +634,76 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 274, + "column": 16, + "endLine": 274, + "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": 275, + "column": 5, + "endLine": 277, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 16, + "endLine": 280, + "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": 303, + "column": 32, + "endLine": 303, + "endColumn": 41, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 311, + "column": 32, + "endLine": 311, + "endColumn": 41, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 312, + "column": 15, + "endLine": 312, + "endColumn": 17, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 319, + "column": 12, + "endLine": 319, + "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": 187, "column": 3, diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json index de865a4411fa65c6c9208d8f2c65af44f481e221..f40bbbb04690836ee6bc229d258704e3f9dd725b 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 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", @@ -24,12 +24,20 @@ { "start": 637, "end": 637, - "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { console.log(1); } // Error, fixable\n}\n\n" + "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()" + "replacementText": "new GeneratedObjectLiteralClass_1()", + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15 } ], "suggest": "", @@ -56,12 +64,20 @@ { "start": 700, "end": 700, - "replacementText": "class GeneratedObjectLiteralClass_2 {\n get property() { return 2; } // Error, fixable\n}\n\n" + "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()" + "replacementText": "new GeneratedObjectLiteralClass_2()", + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18 } ], "suggest": "", @@ -88,12 +104,20 @@ { "start": 771, "end": 771, - "replacementText": "class GeneratedObjectLiteralClass_3 {\n set property(value: number) {\n console.log(value);\n }\n}\n\n" + "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()" + "replacementText": "new GeneratedObjectLiteralClass_3()", + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18 } ], "suggest": "", @@ -110,23 +134,6 @@ "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" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 33, "column": 17, @@ -147,7 +154,11 @@ { "start": 922, "end": 923, - "replacementText": "x: x" + "replacementText": "x: x", + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 4 } ], "suggest": "", @@ -164,7 +175,11 @@ { "start": 945, "end": 946, - "replacementText": "y: y" + "replacementText": "y: y", + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 4 } ], "suggest": "", @@ -181,7 +196,11 @@ { "start": 968, "end": 969, - "replacementText": "z: z" + "replacementText": "z: z", + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 4 } ], "suggest": "", @@ -228,12 +247,20 @@ { "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" + "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})" + "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": "", @@ -250,7 +277,11 @@ { "start": 1112, "end": 1113, - "replacementText": "x: x" + "replacementText": "x: x", + "line": 47, + "column": 3, + "endLine": 47, + "endColumn": 4 } ], "suggest": "", @@ -267,7 +298,11 @@ { "start": 1126, "end": 1127, - "replacementText": "y: y" + "replacementText": "y: y", + "line": 48, + "column": 3, + "endLine": 48, + "endColumn": 4 } ], "suggest": "", @@ -304,57 +339,6 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 11, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1351, - "end": 1357, - "replacementText": "x2: number = 1" - } - ], - "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" - } - ], - "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" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 66, "column": 16, @@ -375,7 +359,11 @@ { "start": 1425, "end": 1427, - "replacementText": "x2: x2" + "replacementText": "x2: x2", + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 5 } ], "suggest": "", @@ -392,7 +380,11 @@ { "start": 1449, "end": 1451, - "replacementText": "y2: y2" + "replacementText": "y2: y2", + "line": 70, + "column": 3, + "endLine": 70, + "endColumn": 5 } ], "suggest": "", @@ -409,7 +401,11 @@ { "start": 1473, "end": 1475, - "replacementText": "z2: z2" + "replacementText": "z2: z2", + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 5 } ], "suggest": "", @@ -456,28 +452,6 @@ "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" - }, - { - "start": 1610, - "end": 1658, - "replacementText": "new GeneratedObjectLiteralClass_5()" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 91, "column": 12, @@ -498,12 +472,20 @@ { "start": 1713, "end": 1713, - "replacementText": "class GeneratedObjectLiteralClass_6 extends C {\n m(): void {\n console.log(300);\n }\n}\n\n" + "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()" + "replacementText": "new GeneratedObjectLiteralClass_6()", + "line": 92, + "column": 3, + "endLine": 94, + "endColumn": 4 } ], "suggest": "", @@ -530,69 +512,26 @@ { "start": 1803, "end": 1803, - "replacementText": "class GeneratedObjectLiteralClass_7 extends C {\n m() { console.log(300); } // Fixable\n}\n\n" + "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()" + "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": 103, - "column": 3, - "endLine": 103, - "endColumn": 11, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1866, - "end": 1874, - "replacementText": "x2: number = 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;" - } - ], - "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;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 109, "column": 14, @@ -603,57 +542,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 1926, - "end": 1928, - "replacementText": "x2: x2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 111, - "column": 3, - "endLine": 111, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 1943, - "end": 1945, - "replacementText": "y2: y2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 3, - "endLine": 112, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 1960, - "end": 1962, - "replacementText": "z2: z2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 113, "column": 3, @@ -664,12 +552,20 @@ { "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" + "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})" + "replacementText": "new GeneratedObjectLiteralClass_8({\n x2: x2,\n y2: y2,\n z2: z2\n})", + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26 } ], "suggest": "", @@ -686,57 +582,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 117, - "column": 3, - "endLine": 117, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2034, - "end": 2036, - "replacementText": "x2: x2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 3, - "endLine": 118, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2051, - "end": 2053, - "replacementText": "y2: y2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 3, - "endLine": 119, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2068, - "end": 2070, - "replacementText": "z2: z2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 120, "column": 3, @@ -767,57 +612,6 @@ "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;" - } - ], - "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;" - } - ], - "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;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 133, "column": 14, @@ -828,57 +622,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "line": 134, - "column": 3, - "endLine": 134, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2289, - "end": 2291, - "replacementText": "x2: x2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 3, - "endLine": 135, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2306, - "end": 2308, - "replacementText": "y2: y2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 136, - "column": 3, - "endLine": 136, - "endColumn": 5, - "problem": "ObjectLiteralProperty", - "autofix": [ - { - "start": 2323, - "end": 2325, - "replacementText": "z2: z2" - } - ], - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 137, "column": 3, @@ -889,40 +632,6 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, - { - "line": 141, - "column": 7, - "endLine": 141, - "endColumn": 12, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2469, - "end": 2474, - "replacementText": "a: number = 1" - } - ], - "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" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 142, "column": 25, @@ -973,7 +682,11 @@ { "start": 2741, "end": 2781, - "replacementText": "interface LocalType {\n a: number;\n b: string;\n}" + "replacementText": "interface LocalType {\n a: number;\n b: string;\n}", + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21 } ], "suggest": "", @@ -1030,6 +743,16 @@ "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 167, + "column": 3, + "endLine": 167, + "endColumn": 37, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, { "line": 168, "column": 27, @@ -1080,16 +803,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "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": 219, "column": 18, @@ -1110,18 +823,36 @@ { "start": 4038, "end": 4038, - "replacementText": "class GeneratedObjectLiteralClass_9 extends Derived {\n m() { console.log(2); }\n}\n\n" + "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()" + "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": 226, + "column": 1, + "endLine": 228, + "endColumn": 2, + "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": 229, "column": 20, @@ -1162,18 +893,149 @@ { "start": 4443, "end": 4443, - "replacementText": "class GeneratedObjectLiteralClass_10 extends Derived3 {\n m() { console.log(2); }\n}\n\n" + "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()" + "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": 274, + "column": 16, + "endLine": 274, + "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": 275, + "column": 5, + "endLine": 277, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 4956, + "end": 4956, + "replacementText": "class GeneratedObjectLiteralClass_11 extends X.C {\n m() {\n console.log(\"C - 2\");\n }\n}\n\n", + "line": 275, + "column": 5, + "endLine": 277, + "endColumn": 6 + }, + { + "start": 4989, + "end": 5038, + "replacementText": "new GeneratedObjectLiteralClass_11()", + "line": 275, + "column": 5, + "endLine": 277, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 16, + "endLine": 280, + "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": 303, + "column": 32, + "endLine": 303, + "endColumn": 41, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 5382, + "end": 5382, + "replacementText": "", + "line": 303, + "column": 32, + "endLine": 303, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 311, + "column": 32, + "endLine": 311, + "endColumn": 41, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 5514, + "end": 5514, + "replacementText": "", + "line": 311, + "column": 32, + "endLine": 311, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 312, + "column": 15, + "endLine": 312, + "endColumn": 17, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 5532, + "end": 5534, + "replacementText": "tt: tt", + "line": 312, + "column": 15, + "endLine": 312, + "endColumn": 17 } ], "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 319, + "column": 12, + "endLine": 319, + "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": 187, "column": 3, diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.json b/ets2panda/linter/test/main/object_literals_properties.ets.json index c8d9bf18dc81b732a67d5bb6570894fd796d4f76..bd4222ae87a1590c4b67731567fb4fdf3c0bc053 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.json @@ -294,6 +294,36 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 274, + "column": 16, + "endLine": 274, + "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": 280, + "column": 16, + "endLine": 280, + "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": 319, + "column": 12, + "endLine": 319, + "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": 187, "column": 3, diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets index 1bbf9dbf43596f87971f1cbfc2187a676fbcb27c..26fdb0822040a3be91c797f4b2f4952ce3b8ca40 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets @@ -34,7 +34,7 @@ class GeneratedObjectLiteralClass_3 { let setMethod = new GeneratedObjectLiteralClass_3(); -let x: number = 1, y = '2', z = true; +let x = 1, y = '2', z = true; interface GeneratedObjectLiteralInterface_1 { x: number; @@ -93,7 +93,7 @@ let mixed = new GeneratedObjectLiteralClass_4({ y: y }); -let x2: number = 1, y2: number = 2, z2: number = 3; +let x2 = 1, y2 = 2, z2 = 3; let mixedBad = { // Not fixable a: 1, b: 2, @@ -108,13 +108,11 @@ let mixedBad = { // Not fixable interface I { m(): void; } -class GeneratedObjectLiteralClass_5 implements I { - m() { - console.log(100); - } -} - -let i: I = new GeneratedObjectLiteralClass_5(); +let i: I = { + m() { // Fixable + console.log(100); + } +}; class C { m(): void { @@ -137,9 +135,9 @@ class GeneratedObjectLiteralClass_7 extends C { foo(new GeneratedObjectLiteralClass_7()); class C2 { - x2: number = 10; - y2: number = 20; - z2: number = 30; + x2 = 10; + y2 = 20; + z2 = 30; m() {} } @@ -147,7 +145,7 @@ class GeneratedObjectLiteralClass_8 extends C2 { x2: number; y2: number; z2: number; - constructor(init: GeneratedObjectLiteralInitInterface_1) { + constructor(init: GeneratedObjectLiteralInitInterface_8) { super(); this.x2 = init.x2; this.y2 = init.y2; @@ -156,7 +154,7 @@ class GeneratedObjectLiteralClass_8 extends C2 { m() { console.log(1); } // Fixable } -interface GeneratedObjectLiteralInitInterface_1 { +interface GeneratedObjectLiteralInitInterface_8 { x2: number; y2: number; z2: number; @@ -169,31 +167,31 @@ let c2: C2 = new GeneratedObjectLiteralClass_8({ }); let c22: C2 = { - x2: x2, // Fixable - y2: y2, // Fixable - z2: z2, // Fixable + x2, // Fixable + y2, // Fixable + z2, // Fixable m() { console.log(1); }, // Not fixable, object has spread property ...shorthand // Not fixable }; class C3 { - x2: number = 10; - y2: number = 20; - z2: number = 30; + x2 = 10; + y2 = 20; + z2 = 30; m() {} constructor(a: number) {} } let c3: C3 = { - x2: x2, // Fixable - y2: y2, // Fixable - z2: z2, // Fixable + x2, // Fixable + y2, // Fixable + z2, // Fixable m() { console.log(1); } // Not fixable, class type has constructor with parameters }; function capturesFromLocalScope() { - let a: number = 1, b: number = 2; + let a = 1, b = 2; let captureLocalVal = { m() { // Not fixable, captures local values 'a' and 'b' console.log(a, b); @@ -304,4 +302,83 @@ class GeneratedObjectLiteralClass_10 extends Derived3 { m() { console.log(2); } } -let b3: Derived3 = new GeneratedObjectLiteralClass_10(); \ No newline at end of file +let b3: Derived3 = new GeneratedObjectLiteralClass_10(); + +interface I4 { + map: Map; +} +let map:Map = new Map(); +let i4: I4 = {map}; + +class C6 { + map1: Map = new Map(); +} + +let map1:Map = new Map(); +let c6: C6 = {map1}; + +// Namespace typed object literals +namespace X { + export class C { + m() { + console.log("C - 1"); + } + } + + export interface I { + m(a: number, b: string): void; + } +} + +class GeneratedObjectLiteralClass_11 extends X.C { + m() { + console.log("C - 2"); + } +} + +function test() { + let c: X.C = new GeneratedObjectLiteralClass_11() + + let i: X.I = { + m(): void { + console.log("I"); + } + } +} + +class FooBarBaz { + foo?: Map + bar?: string +} + +function baz(fooBar: Map) { + baz2({fooBar}); +} + +function baz2(fooBarBaz: FooBarBaz) { +} + +class JJ { + mm?: Map + aa?: string +} +const mm: Map = new Map(); +let nn: JJ = {mm} // no error + + +class DD { + tt?: Map + gg?: string +} +const tt: Map = new Map(); +let gg: DD = {tt: tt} // error + +interface Q { + a:number; + foo():void; +} + +let w: Q = { + a:1.0, + foo(){} // no error +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json index 05c3a0ea0afabb5997a61e67a3313ab008a370a8..dc8cbd98544dfe6389632f122547adf58f1192cd 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 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", @@ -85,9 +85,19 @@ "severity": "ERROR" }, { - "line": 171, + "line": 111, + "column": 12, + "endLine": 111, + "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": 169, "column": 15, - "endLine": 171, + "endLine": 169, "endColumn": 16, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -95,9 +105,9 @@ "severity": "ERROR" }, { - "line": 175, + "line": 173, "column": 3, - "endLine": 175, + "endLine": 173, "endColumn": 26, "problem": "ObjectLiteralProperty", "suggest": "", @@ -105,9 +115,9 @@ "severity": "ERROR" }, { - "line": 176, + "line": 174, "column": 3, - "endLine": 176, + "endLine": 174, "endColumn": 15, "problem": "ObjectLiteralProperty", "suggest": "", @@ -115,9 +125,9 @@ "severity": "ERROR" }, { - "line": 176, + "line": 174, "column": 3, - "endLine": 176, + "endLine": 174, "endColumn": 15, "problem": "SpreadOperator", "suggest": "", @@ -125,9 +135,9 @@ "severity": "ERROR" }, { - "line": 188, + "line": 186, "column": 14, - "endLine": 188, + "endLine": 186, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -135,9 +145,9 @@ "severity": "ERROR" }, { - "line": 192, + "line": 190, "column": 3, - "endLine": 192, + "endLine": 190, "endColumn": 26, "problem": "ObjectLiteralProperty", "suggest": "", @@ -145,9 +155,9 @@ "severity": "ERROR" }, { - "line": 197, + "line": 195, "column": 25, - "endLine": 197, + "endLine": 195, "endColumn": 26, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -155,9 +165,9 @@ "severity": "ERROR" }, { - "line": 198, + "line": 196, "column": 5, - "endLine": 200, + "endLine": 198, "endColumn": 6, "problem": "ObjectLiteralProperty", "suggest": "", @@ -165,9 +175,9 @@ "severity": "ERROR" }, { - "line": 203, + "line": 201, "column": 29, - "endLine": 203, + "endLine": 201, "endColumn": 30, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -175,9 +185,9 @@ "severity": "ERROR" }, { - "line": 204, + "line": 202, "column": 5, - "endLine": 206, + "endLine": 204, "endColumn": 6, "problem": "ObjectLiteralProperty", "suggest": "", @@ -185,9 +195,19 @@ "severity": "ERROR" }, { - "line": 214, + "line": 207, + "column": 3, + "endLine": 210, + "endColumn": 2, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 212, "column": 26, - "endLine": 214, + "endLine": 212, "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -195,9 +215,9 @@ "severity": "ERROR" }, { - "line": 215, + "line": 213, "column": 5, - "endLine": 217, + "endLine": 215, "endColumn": 6, "problem": "ObjectLiteralProperty", "suggest": "", @@ -205,9 +225,9 @@ "severity": "ERROR" }, { - "line": 219, + "line": 217, "column": 27, - "endLine": 219, + "endLine": 217, "endColumn": 28, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -215,9 +235,9 @@ "severity": "ERROR" }, { - "line": 220, + "line": 218, "column": 5, - "endLine": 222, + "endLine": 220, "endColumn": 6, "problem": "ObjectLiteralProperty", "suggest": "", @@ -225,9 +245,19 @@ "severity": "ERROR" }, { - "line": 226, + "line": 223, + "column": 3, + "endLine": 223, + "endColumn": 37, + "problem": "NoLocalClass", + "suggest": "", + "rule": "Creating local classes is not supported (arkts-no-local-class)", + "severity": "ERROR" + }, + { + "line": 224, "column": 27, - "endLine": 226, + "endLine": 224, "endColumn": 28, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -235,9 +265,9 @@ "severity": "ERROR" }, { - "line": 227, + "line": 225, "column": 5, - "endLine": 229, + "endLine": 227, "endColumn": 6, "problem": "ObjectLiteralProperty", "suggest": "", @@ -245,9 +275,9 @@ "severity": "ERROR" }, { - "line": 238, + "line": 236, "column": 14, - "endLine": 238, + "endLine": 236, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -255,9 +285,9 @@ "severity": "ERROR" }, { - "line": 249, + "line": 247, "column": 3, - "endLine": 249, + "endLine": 247, "endColumn": 9, "problem": "ObjectLiteralProperty", "suggest": "", @@ -265,9 +295,9 @@ "severity": "ERROR" }, { - "line": 256, + "line": 254, "column": 14, - "endLine": 256, + "endLine": 254, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -275,19 +305,19 @@ "severity": "ERROR" }, { - "line": 267, - "column": 3, - "endLine": 267, - "endColumn": 9, - "problem": "ObjectLiteralProperty", + "line": 284, + "column": 1, + "endLine": 286, + "endColumn": 2, + "problem": "MissingSuperCall", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "The subclass constructor must call the parent class's parametered constructor (arkts-subclass-must-call-super-constructor-with-args)", "severity": "ERROR" }, { - "line": 289, + "line": 287, "column": 20, - "endLine": 289, + "endLine": 287, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -295,9 +325,9 @@ "severity": "ERROR" }, { - "line": 290, + "line": 288, "column": 3, - "endLine": 290, + "endLine": 288, "endColumn": 26, "problem": "ObjectLiteralProperty", "suggest": "", @@ -305,9 +335,29 @@ "severity": "ERROR" }, { - "line": 245, + "line": 342, + "column": 16, + "endLine": 342, + "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": 381, + "column": 12, + "endLine": 381, + "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": 243, "column": 3, - "endLine": 245, + "endLine": 243, "endColumn": 4, "problem": "StrictDiagnostic", "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", diff --git a/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets index df9184137493b52f8f3387f4c5518985c9d24e5a..d1cf449eed7e5dee07f5d18779449cd8bf890260 100644 --- a/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets +++ b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets @@ -14,9 +14,26 @@ */ export namespace utils { + export namespace locks { + export class AsyncLock { + request(s: string): AsyncLock; + } + } namespace ASON { function stringify(value: Object | null | undefined): string; } } -export default utils; \ No newline at end of file +export default utils; + +export namespace ArkTSUtils { + export namespace locks { + export class AsyncLock { + constructor(); + } + } + + export namespace safeModule { + export function foo(): void; + } +} diff --git a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets index dd994ead622471b25a9e0e8a233865d567fac6b4..48d558071e75cded027b60394b4f0f0a53531920 100644 --- a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets +++ b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets @@ -16,4 +16,6 @@ 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 +export { taskpool } from '../oh_modules/@ohos.taskpool'; +export { ArkTSUtils } from '../oh_modules/@arkts.utils'; +export { process } from '../oh_modules/@ohos.process'; diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.app.ability.AbilityStage.d.ts b/ets2panda/linter/test/main/oh_modules/@ohos.app.ability.AbilityStage.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b55881d9048802032a602b6e48b83a8722ba7b5a --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@ohos.app.ability.AbilityStage.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 ApplicationContext from './ApplicationContext'; + +export default class AbilityStage { + + context: ApplicationContext; + + onCreate(): void; + +} + diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.process.d.ets b/ets2panda/linter/test/main/oh_modules/@ohos.process.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..33507584b01a912e7c694ca35bfebd4c42f89aa7 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@ohos.process.d.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 process { + function isAppUid(v: number): boolean; + function getUidForName(v: string): number; + function getThreadPriority(v: number): number; + function getSystemConfig(name: number): number; + function getEnvironmentVar(name: string): string; + function exit(code: number): void; + function kill(signal: number, pid: number): boolean; +} diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.util.HashMap.d.ets b/ets2panda/linter/test/main/oh_modules/@ohos.util.HashMap.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a82cdb9a8309a9f9144fb675f2657b9f7022437 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@ohos.util.HashMap.d.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 MapKit { + export class HashMap { + constructor(); + length: number; + keys(): IterableIterator; + hasKey(key: K): boolean; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/ApplicationContext.d.ts b/ets2panda/linter/test/main/oh_modules/ApplicationContext.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..838e34b98c58a262b5b7a8c175ee0e70ab88129a --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/ApplicationContext.d.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 default class ApplicationContext { + on(type: 'abilityLifecycle', callback: AbilityLifecycleCallback): number; + off(type: 'abilityLifecycle', callbackId: number, callback: AsyncCallback): void; + getApplicationContext(): ApplicationContext; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/common_ts_ets_api.d.ts b/ets2panda/linter/test/main/oh_modules/common_ts_ets_api.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..0be36a0a8eb13282a0468bccffd1145ad19fc6e1 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/common_ts_ets_api.d.ts @@ -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. + */ + +export declare interface IMonitor { + value(path?: string): IMonitorValue | undefined; +} +export declare interface IMonitorValue { + before: T; + now: T; + path: string; +} +export declare class LocalStorage { + get(propName: string): T | undefined; + ref(propName: string): AbstractProperty | undefined; + link(propName: string): SubscribedAbstractProperty | undefined; +} + +export declare class AppStorage { + static get(propName: string): T | undefined; + static ref(propName: string): AbstractProperty | undefined; + static link(propName: string): SubscribedAbstractProperty | undefined; +} + +export declare interface AbstractProperty { + get(): T; + set(newValue: T): void; + info(): string; +} +export declare abstract class SubscribedAbstractProperty { + info(): string; + abstract get(): T; + abstract set(newValue: T): void; + abstract aboutToBeDeleted(): void; +} \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/throwingFunctionCheck3.ets b/ets2panda/linter/test/main/optional_tuple_type.ets similarity index 34% rename from ets2panda/test/compiler/ets/throwingFunctionCheck3.ets rename to ets2panda/linter/test/main/optional_tuple_type.ets index 0559788039c919cfc8b46ce6f754d19e17f168e1..510267dad27953e642ffbe2e97dd962445a38d4f 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionCheck3.ets +++ b/ets2panda/linter/test/main/optional_tuple_type.ets @@ -13,21 +13,43 @@ * limitations under the License. */ -class TestClass { - constructor() throws {} - TestMethod(): void {} +// Test optional tuple type rule + +// Basic optional tuple type +type BasicOptionalTuple = [string, number?]; // Error: number? is optional + +// Optional element in nested tuple +type NestedOptionalTuple = [string, [number, string?]]; // Error: string? is optional + +// Optional tuple type in function parameters +function processOptionalTuple( + data: [string, number?] // Error: number? is optional +): void { + console.log(data); } -function TestFunction(): void throws { - let a = new TestClass(); +// Optional tuple property in interface +interface DataProcessor { + process(data: [string, number?]): void; // Error: number? is optional +} - try { - a.TestMethod(); - } catch (e: Exception) {} +// Optional tuple in type +let t: [number, boolean?] = [1]; // Error: boolean? is optional + +// Correct usage +type CorrectTuple1 = [string, number]; // Correct: all elements are required + +// Correct function parameter usage +function processCorrectTuple( + data: [string, number] // Correct: all elements are required +): void { + console.log(data); } -function main(): void { - try { - TestFunction(); - } catch (e) {} +// Correct interface usage +interface CorrectDataProcessor { + process(data: [string, number]): void; // Correct: all elements are required } + +// Correct type alias usage +type CorrectDataTuple = [string, number]; // Correct: all elements are required \ No newline at end of file diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.args.json b/ets2panda/linter/test/main/optional_tuple_type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4c5ee75ae13eb33a07ef6b198f7fdb637c8d84fc --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.args.json @@ -0,0 +1,19 @@ +{ + "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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json b/ets2panda/linter/test/main/optional_tuple_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9be7efa7bf6baa60e67973d9f06a094d379f1c2b --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_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": 19, + "column": 36, + "endLine": 19, + "endColumn": 43, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 53, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 25, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 33, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 17, + "endLine": 37, + "endColumn": 25, + "problem": "OptionalTupleType", + "suggest": "", + "rule": "No optional tuple type (arkts-no-optional-tuple-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/optional_tuple_type.ets.json b/ets2panda/linter/test/main/optional_tuple_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..2844fc25ba579f7e073c0d91f47b203c80c09683 --- /dev/null +++ b/ets2panda/linter/test/main/optional_tuple_type.ets.json @@ -0,0 +1,17 @@ +{ + "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": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json b/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json index 3c10baf0349059e215529a56589d24292d1a4984..343ff611b84b1889fb0c175ee6dedf04fcd59b80 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json @@ -44,6 +44,16 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 34, + "column": 33, + "endLine": 34, + "endColumn": 34, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, { "line": 34, "column": 26, diff --git a/ets2panda/linter/test/main/parameter_properties.ets.autofix.json b/ets2panda/linter/test/main/parameter_properties.ets.autofix.json index f0b0ffdba2e43b9e3057747928a86744f1e1aec2..d6e77be9c67c9b6594e6c2c831c311639c2d620e 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,63 @@ { "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": 34, + "column": 33, + "endLine": 34, + "endColumn": 34, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, { "line": 34, "column": 26, @@ -135,22 +205,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,22 +253,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": "", @@ -239,12 +341,20 @@ { "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": "", @@ -261,17 +371,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 +410,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 +467,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 +524,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,17 +581,29 @@ { "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": "", @@ -426,17 +620,29 @@ { "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": "", @@ -453,17 +659,29 @@ { "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": "", @@ -480,22 +698,38 @@ { "start": 2003, "end": 2003, - "replacementText": "public a?: number;\npublic b: number;\n" + "replacementText": "public a?: number;\npublic b: number;\n", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 }, { "start": 2015, "end": 2032, - "replacementText": "a?: number" + "replacementText": "a?: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 }, { "start": 2034, "end": 2050, - "replacementText": "b: number" + "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}" + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 } ], "suggest": "", @@ -512,22 +746,38 @@ { "start": 2003, "end": 2003, - "replacementText": "public a?: number;\npublic b: number;\n" + "replacementText": "public a?: number;\npublic b: number;\n", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 }, { "start": 2015, "end": 2032, - "replacementText": "a?: number" + "replacementText": "a?: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 }, { "start": 2034, "end": 2050, - "replacementText": "b: number" + "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}" + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 } ], "suggest": "", @@ -544,22 +794,38 @@ { "start": 2071, "end": 2071, - "replacementText": "public a?: number;\npublic b?: number;\n" + "replacementText": "public a?: number;\npublic b?: number;\n", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 }, { "start": 2083, "end": 2100, - "replacementText": "a?: number" + "replacementText": "a?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 }, { "start": 2102, "end": 2119, - "replacementText": "b?: number" + "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}" + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 } ], "suggest": "", @@ -576,22 +842,38 @@ { "start": 2071, "end": 2071, - "replacementText": "public a?: number;\npublic b?: number;\n" + "replacementText": "public a?: number;\npublic b?: number;\n", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 }, { "start": 2083, "end": 2100, - "replacementText": "a?: number" + "replacementText": "a?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 }, { "start": 2102, "end": 2119, - "replacementText": "b?: number" + "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}" + "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.migrate.json b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json index 03cac9f4e47f0a3b2f7cc5966991917f603ee4d0..f5bbbab5413b751bcc375dc9c7b788749e4839a7 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.migrate.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 43, + "column": 24, + "endLine": 43, + "endColumn": 25, + "problem": "DefaultArgsBehindRequiredArgs", + "suggest": "", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", + "severity": "ERROR" + }, { "line": 54, "column": 15, diff --git a/ets2panda/linter/test/main/persist_serial_1.ets b/ets2panda/linter/test/main/persist_serial_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..72a51f4537e70825aac96c0813e56c554555ac68 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.ets @@ -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. + */ + +import { PersistentStorage } from './ui_modules/common_ts_ets_api'; + +class MyClassA {} + +function MyGet1() { + if (1 > 0) { + return 1 + } else { + return 2 + } +} + +function MyGet2() { + if (1 > 0) { + return 0 + } else { + return new MyClassA() + } +} + +const a1 = new MyClassA(); +const a2 = new MyClassA(); +const myArr1: Array = new Array(1, 2); +const mySet1: Set = new Set([1, 2, 3]); +const myMap1: Map = new Map([["jack", 3], ["tom", 2]]); +const myMap2: Map = new Map([[1, a1], [2, a2]]); + +PersistentStorage.persistProp('PropA', 47); +PersistentStorage.persistProp('PropA', true); +PersistentStorage.persistProp('PropA', "Jack"); +PersistentStorage.persistProp('PropA', null); +PersistentStorage.persistProp('PropA', undefined); +PersistentStorage.persistProp('PropA', new Date()); +PersistentStorage.persistProp('PropA', a1); // error +PersistentStorage.persistProp('PropA', new MyClassA()); // error +PersistentStorage.persistProp('PropA', MyGet1()); +PersistentStorage.persistProp('PropA', MyGet2()); // error +PersistentStorage.persistProp('PropA', 1 < 0 ? 1 : new MyClassA()); // error + +PersistentStorage.persistProp('PropA', new Array(1, 2)); +PersistentStorage.persistProp('PropA', new Array("jack", "tom")); +PersistentStorage.persistProp('PropA', new Array(myArr1)); // error +PersistentStorage.persistProp('PropA', new Array(new MyClassA())); // error +PersistentStorage.persistProp('PropA', new Array(a1)); // error + +PersistentStorage.persistProp('PropA', new Set([1, 2])); +PersistentStorage.persistProp('PropA', new Set(["jack", "tom"])); +PersistentStorage.persistProp('PropA', mySet1); +PersistentStorage.persistProp('PropA', new Set([new MyClassA()])); // error +PersistentStorage.persistProp('PropA', new Set([a1])); // error + +PersistentStorage.persistProp('PropA', new Map([["jack", 3], ["tom", 2]])); +PersistentStorage.persistProp('PropA', new Map([[1, a1], [2, a2]])); // error +PersistentStorage.persistProp('PropA', myMap1); +PersistentStorage.persistProp('PropA', myMap2); // error diff --git a/ets2panda/linter/test/main/persist_serial_1.ets.args.json b/ets2panda/linter/test/main/persist_serial_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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/persist_serial_1.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e2c1626588a608dc77132b48ce71a7f8886c763f --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.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": 38, + "column": 35, + "endLine": 38, + "endColumn": 40, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 29, + "endLine": 39, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 37, + "endLine": 40, + "endColumn": 71, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 39, + "endLine": 41, + "endColumn": 66, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 44, + "endLine": 48, + "endColumn": 48, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 1, + "endLine": 49, + "endColumn": 43, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 55, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 1, + "endLine": 52, + "endColumn": 49, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 67, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 44, + "endLine": 55, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 40, + "endLine": 55, + "endColumn": 55, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 44, + "endLine": 56, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 40, + "endLine": 56, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 1, + "endLine": 57, + "endColumn": 58, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 44, + "endLine": 57, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 40, + "endLine": 57, + "endColumn": 57, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 1, + "endLine": 58, + "endColumn": 66, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 44, + "endLine": 58, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 40, + "endLine": 58, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 1, + "endLine": 59, + "endColumn": 54, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 44, + "endLine": 59, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 40, + "endLine": 59, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 40, + "endLine": 61, + "endColumn": 55, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 40, + "endLine": 62, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 66, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 40, + "endLine": 64, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 54, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 40, + "endLine": 65, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 40, + "endLine": 67, + "endColumn": 74, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 68, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 40, + "endLine": 68, + "endColumn": 67, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 47, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_1.ets.json b/ets2panda/linter/test/main/persist_serial_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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/persist_serial_2.ets b/ets2panda/linter/test/main/persist_serial_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..5f0214c5673ff0dca84f14772571116851161114 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.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. + */ + +import { PersistentStorage } from './ui_modules/common_ts_ets_api'; + +class MyClassA {} + +function MyGet1() { + if (1 > 0) { + return 1 + } else { + return 2 + } +} + +function MyGet2() { + if (1 > 0) { + return 0 + } else { + return new MyClassA() + } +} + +const a1 = new MyClassA(); +const a2 = new MyClassA(); +const myArr1: Array = new Array(1, 2); +const mySet1: Set = new Set([1, 2, 3]); +const myMap1: Map = new Map([["jack", 3], ["tom", 2]]); +const myMap2: Map = new Map([[1, a1], [2, a2]]); + +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: '0' }, { key: 'wightScore', defaultValue: '1' }]); +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: 0 }, { key: 'wightScore', defaultValue: 1 }]); +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: false }, { key: 'wightScore', defaultValue: true }]); + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new MyClassA() }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: 1 < 0 ? 1 : new MyClassA() }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: MyGet1() }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: MyGet2() }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(1, 2) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array("jack", "tom") }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(myArr1) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(new MyClassA()) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(a1) }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([1, 2]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set(["jack", "tom"]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: mySet1 }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([new MyClassA()]) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([a1]) }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Map([["jack", 3], ["tom", 2]]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Map([[1, a1], [2, a2]]) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: myMap1 }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: myMap2 }]); // error \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets.args.json b/ets2panda/linter/test/main/persist_serial_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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/persist_serial_2.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..1c0b6ba77cbe01dcd7cdbd065529a99ac6f911b4 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.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": 38, + "column": 35, + "endLine": 38, + "endColumn": 40, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 29, + "endLine": 39, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 37, + "endLine": 40, + "endColumn": 71, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 39, + "endLine": 41, + "endColumn": 66, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 1, + "endLine": 47, + "endColumn": 118, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 130, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 112, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 104, + "endLine": 52, + "endColumn": 109, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 100, + "endLine": 52, + "endColumn": 115, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 104, + "endLine": 53, + "endColumn": 109, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 100, + "endLine": 53, + "endColumn": 124, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 1, + "endLine": 54, + "endColumn": 121, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 104, + "endLine": 54, + "endColumn": 109, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 100, + "endLine": 54, + "endColumn": 117, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 1, + "endLine": 55, + "endColumn": 129, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 104, + "endLine": 55, + "endColumn": 109, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 100, + "endLine": 55, + "endColumn": 125, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 117, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 104, + "endLine": 56, + "endColumn": 109, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 100, + "endLine": 56, + "endColumn": 113, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 100, + "endLine": 58, + "endColumn": 115, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 100, + "endLine": 59, + "endColumn": 124, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 1, + "endLine": 61, + "endColumn": 129, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 100, + "endLine": 61, + "endColumn": 125, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 62, + "endColumn": 117, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 100, + "endLine": 62, + "endColumn": 113, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 100, + "endLine": 64, + "endColumn": 134, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 131, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 100, + "endLine": 65, + "endColumn": 127, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 110, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets.json b/ets2panda/linter/test/main/persist_serial_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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/persist_serial_3.ets b/ets2panda/linter/test/main/persist_serial_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..f314b869406c1ed70ab17236974b8cd2cbe9b32b --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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 { ConnectOptions, PersistenceV2, Type } from './ui_modules/@kit.ArkUI'; +import { contextConstant } from '@kit.AbilityKit'; + +PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => {}) + +@ObservedV2 +class SampleChild { + @Trace childId: number = 0; + groupId: number = 1; +} + +@ObservedV2 +class Sample { + @Type(SampleChild) + @Trace father: SampleChild = new SampleChild(); +} + +@Entry +@ComponentV2 +struct TestCase2 { + @Local p1: Sample | undefined = PersistenceV2.globalConnect({type: Sample, defaultCreator:() => new Sample()}); // error + + @Local p2: Sample | undefined = PersistenceV2.globalConnect({type: Sample, key: 'global1', defaultCreator:() => new Sample(), areaMode: contextConstant.AreaMode.EL1}); // error + + options: ConnectOptions = {type: Sample, key: 'global2', defaultCreator:() => new Sample()}; + @Local p3: Sample | undefined = PersistenceV2.globalConnect(this.options); // error + + @Local p4: Sample | undefined = PersistenceV2.globalConnect({type: Sample, key: 'global1', defaultCreator:() => new Sample(), areaMode: 3}); // error + + @Local p5: Sample | undefined = PersistenceV2.connect(Sample, () => new Sample()); // error + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets.args.json b/ets2panda/linter/test/main/persist_serial_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_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/persist_serial_3.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..151971eb234021de3a50c2110398f41caac4855e --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 41, + "endLine": 16, + "endColumn": 45, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 35, + "endLine": 36, + "endColumn": 113, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 35, + "endLine": 36, + "endColumn": 113, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 35, + "endLine": 38, + "endColumn": 169, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 35, + "endLine": 38, + "endColumn": 169, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 44, + "endLine": 40, + "endColumn": 50, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 35, + "endLine": 41, + "endColumn": 76, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 35, + "endLine": 41, + "endColumn": 76, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 35, + "endLine": 43, + "endColumn": 142, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 35, + "endLine": 43, + "endColumn": 142, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 35, + "endLine": 45, + "endColumn": 84, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"connect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 35, + "endLine": 45, + "endColumn": 84, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ObservedV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 4, + "endLine": 23, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Trace\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 2, + "endLine": 27, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ObservedV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Trace\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 2, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 4, + "endLine": 36, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 4, + "endLine": 38, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 4, + "endLine": 43, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets.json b/ets2panda/linter/test/main/persist_serial_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..097b66ff3c436ef1e2f9b8373703c5bb650894de --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.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": 40, + "column": 44, + "endLine": 40, + "endColumn": 50, + "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/prop_decorator_and_interfaces_1.ets b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.args.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_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/prop_decorator_and_interfaces_1.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.arkts2.json similarity index 51% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.arkts2.json index eda4a3c782419fa3f42038746047f40637c8b8ec..4b6736a764995f2afd56883a9b0cb363eb6f640e 100644 --- a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.arkts2.json @@ -19,9 +19,9 @@ "column": 3, "endLine": 24, "endColumn": 33, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropDecoratorNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", "severity": "ERROR" }, { @@ -29,9 +29,9 @@ "column": 3, "endLine": 34, "endColumn": 49, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "StoragePropDecoratorNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"@StorageProp\" decorator is not supported (arkui-no-storageprop-decorator)", "severity": "ERROR" }, { @@ -39,9 +39,9 @@ "column": 3, "endLine": 35, "endColumn": 54, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "LocalStoragePropDecoratorNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"@LocalStorageProp\" decorator is not supported (arkui-no-localstorageprop-decorator)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,17 +61,7 @@ "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)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +71,7 @@ "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"StorageLink\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +81,7 @@ "endColumn": 20, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorageLink\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,27 +91,7 @@ "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)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.autofix.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f794b3a42665e31add7fcf0192710bf620b853cb --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.autofix.json @@ -0,0 +1,186 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 3, + "endLine": 24, + "endColumn": 33, + "problem": "PropDecoratorNotSupported", + "autofix": [ + { + "start": 705, + "end": 709, + "replacementText": "PropRef", + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 49, + "problem": "StoragePropDecoratorNotSupported", + "autofix": [ + { + "start": 896, + "end": 907, + "replacementText": "StoragePropRef", + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "\"@StorageProp\" decorator is not supported (arkui-no-storageprop-decorator)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 54, + "problem": "LocalStoragePropDecoratorNotSupported", + "autofix": [ + { + "start": 945, + "end": 961, + "replacementText": "LocalStoragePropRef", + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "\"@LocalStorageProp\" decorator is not supported (arkui-no-localstorageprop-decorator)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n StorageLink,\n LocalStorageLink,\n} from '@kit.ArkUI';", + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n StorageLink,\n LocalStorageLink,\n} from '@kit.ArkUI';", + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n StorageLink,\n LocalStorageLink,\n} from '@kit.ArkUI';", + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"StorageLink\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 20, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n StorageLink,\n LocalStorageLink,\n} from '@kit.ArkUI';", + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"LocalStorageLink\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n StorageLink,\n LocalStorageLink,\n} from '@kit.ArkUI';", + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_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_decorators_and_interfaces_1.ets.migrate.ets b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b38c7a7c44b87c8f30b0ee2fcdc63fe06e7418b --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.migrate.ets @@ -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. + */ + +import { + PropRef, + StoragePropRef, + LocalStoragePropRef, +} from '@kit.ArkUI'; + +import { + Entry, + Component, + StorageLink, + LocalStorageLink, +} from '@kit.ArkUI'; + +class User { + name: string = "" + age: number = 0 +} + +@Entry +@Component +struct FatherComponent { + @PropRef user1: User = new User() + @StorageLink("user2") user2: User = new User() + @LocalStorageLink("user3") user3: User = new User() + + build() { + } +} + +@Component +struct ChildComponent { + @StoragePropRef("user2") user2: User = new User() + @LocalStoragePropRef("user3") user3: User = new User() + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.migrate.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e03a31e43e674f46b9dd392f7638beff8289ece4 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_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": 37, + "column": 3, + "endLine": 37, + "endColumn": 11, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 3, + "endLine": 47, + "endColumn": 27, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 3, + "endLine": 48, + "endColumn": 32, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + } + ] +} \ 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_decorators_and_interfaces_2.ets similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.args.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_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/main/prop_decorator_and_interfaces_2.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.arkts2.json similarity index 63% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.arkts2.json index a34c53714857c59f1233360467e425e46bc04227..323e9a92a4463fc2e0ffadcf9d5ad802d45067b5 100644 --- a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.arkts2.json @@ -29,9 +29,9 @@ "column": 5, "endLine": 22, "endColumn": 42, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -49,9 +49,9 @@ "column": 5, "endLine": 23, "endColumn": 44, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -69,9 +69,9 @@ "column": 5, "endLine": 24, "endColumn": 53, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -89,9 +89,9 @@ "column": 5, "endLine": 25, "endColumn": 70, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -99,9 +99,9 @@ "column": 5, "endLine": 26, "endColumn": 72, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -109,9 +109,9 @@ "column": 5, "endLine": 27, "endColumn": 81, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -119,9 +119,9 @@ "column": 5, "endLine": 30, "endColumn": 45, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -134,24 +134,14 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, - { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 45, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 31, "column": 5, "endLine": 31, "endColumn": 47, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -169,9 +159,9 @@ "column": 5, "endLine": 32, "endColumn": 56, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -189,9 +179,9 @@ "column": 5, "endLine": 33, "endColumn": 74, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -199,9 +189,9 @@ "column": 5, "endLine": 34, "endColumn": 76, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -209,9 +199,9 @@ "column": 5, "endLine": 35, "endColumn": 85, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -229,9 +219,9 @@ "column": 13, "endLine": 43, "endColumn": 52, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -249,9 +239,9 @@ "column": 13, "endLine": 44, "endColumn": 80, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { @@ -261,7 +251,7 @@ "endColumn": 26, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -271,7 +261,7 @@ "endColumn": 45, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -281,7 +271,7 @@ "endColumn": 38, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -291,7 +281,7 @@ "endColumn": 38, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -301,7 +291,7 @@ "endColumn": 38, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -311,7 +301,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -321,7 +311,7 @@ "endColumn": 23, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -331,7 +321,7 @@ "endColumn": 23, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -341,7 +331,7 @@ "endColumn": 23, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -351,7 +341,7 @@ "endColumn": 39, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -361,7 +351,7 @@ "endColumn": 60, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -371,7 +361,7 @@ "endColumn": 39, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -381,7 +371,7 @@ "endColumn": 62, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -391,7 +381,7 @@ "endColumn": 39, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -401,7 +391,7 @@ "endColumn": 71, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"AppStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -411,7 +401,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -421,7 +411,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -431,7 +421,7 @@ "endColumn": 35, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -441,7 +431,7 @@ "endColumn": 46, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"SubscribedAbstractProperty\" should be imported before it is used (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_decorators_and_interfaces_2.ets.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_2.ets.json diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets b/ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.args.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_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_decorators_and_interfaces_3.ets.arkts2.json similarity index 68% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.arkts2.json index aae50874a93b096af39198a74ec4c1311c7aeb9e..3bb6b25fa4a3129263ec851c7bca2f676f7cebd1 100644 --- a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.arkts2.json @@ -29,9 +29,9 @@ "column": 5, "endLine": 44, "endColumn": 53, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -49,9 +49,9 @@ "column": 5, "endLine": 45, "endColumn": 53, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -69,9 +69,9 @@ "column": 5, "endLine": 46, "endColumn": 64, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -89,9 +89,9 @@ "column": 5, "endLine": 47, "endColumn": 65, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -109,9 +109,9 @@ "column": 5, "endLine": 48, "endColumn": 73, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -129,9 +129,9 @@ "column": 5, "endLine": 49, "endColumn": 56, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -149,9 +149,9 @@ "column": 5, "endLine": 50, "endColumn": 43, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -169,9 +169,9 @@ "column": 5, "endLine": 51, "endColumn": 48, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -189,9 +189,9 @@ "column": 5, "endLine": 52, "endColumn": 46, - "problem": "PropDecoratorsAndInterfacesAreNotSupported", + "problem": "SetAndPropFunctionNotSupported", "suggest": "", - "rule": "The \"Prop\", \"StorageProp\", and \"LocalStorageProp\" decorators, as well as the \"prop\" and \"setAndProp\" interfaces, are not supported (arkui-no-specific-prop-decorators-and-interfaces)", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 26, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 45, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"LocalStorage\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -231,7 +231,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -241,7 +241,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.json similarity index 100% rename from ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json rename to ets2panda/linter/test/main/prop_decorators_and_interfaces_3.ets.json diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..4f8c44b2269e78ee952f21c78af4d88ffe23815e --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 ChildComponentOptions { + count: number; +} + +@Component +struct SuperComponent1 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent1({ options1: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct SuperComponent2 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent2({ options2: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct SuperComponent3 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent3({ options3: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct ChildComponent1 { + @Prop options1: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options1.count}`) + Blank() + Button('+').onClick(() => { + this.options1.count++; + }) + Button('-').onClick(() => { + this.options1.count--; + }) + } + } +} + +@Component +struct ChildComponent2 { + @Prop options2: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options2.count}`) + Blank() + Button('change1').onClick(() => { + this.options2.count = 1; + }) + Button('change2').onClick(() => { + this.options2.count = 1; + }) + } + } +} + +@Component +struct ChildComponent3 { + @Prop options3: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options3.count}`) + Blank() + Button('+').onClick(() => { + ++this.options3.count; + }) + Button('-').onClick(() => { + --this.options3.count; + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.args.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.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/prop_decorators_and_interfaces_4.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d52174ddca98d2f071b93899e665d66e93bdef3a --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.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": 26, + "column": 25, + "endLine": 26, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 25, + "endLine": 38, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 25, + "endLine": 50, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 3, + "endLine": 76, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 2, + "endLine": 44, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 2, + "endLine": 56, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 7, + "endLine": 62, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 7, + "endLine": 63, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 7, + "endLine": 64, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 7, + "endLine": 67, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 2, + "endLine": 74, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 7, + "endLine": 80, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 7, + "endLine": 81, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 7, + "endLine": 82, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 7, + "endLine": 85, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 2, + "endLine": 92, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 5, + "endLine": 97, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 7, + "endLine": 98, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 7, + "endLine": 99, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.autofix.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ad78eb8703b102661cdda0a2a27fc6b57d5bb300 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.autofix.json @@ -0,0 +1,741 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 25, + "endLine": 26, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 25, + "endLine": 38, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 25, + "endLine": 50, + "endColumn": 52, + "problem": "PropNeedCallMethodForDeepCopy", + "suggest": "", + "rule": "Parameters decorated with \"@Prop\" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "autofix": [ + { + "start": 1397, + "end": 1401, + "replacementText": "PropRef", + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 3, + "endLine": 76, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "autofix": [ + { + "start": 1711, + "end": 1715, + "replacementText": "PropRef", + "line": 76, + "column": 3, + "endLine": 76, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 41, + "problem": "PropDecoratorNotSupported", + "autofix": [ + { + "start": 2041, + "end": 2045, + "replacementText": "PropRef", + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 2, + "endLine": 44, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 2, + "endLine": 56, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 7, + "endLine": 62, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 7, + "endLine": 63, + "endColumn": 12, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 7, + "endLine": 64, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 7, + "endLine": 67, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 2, + "endLine": 74, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 7, + "endLine": 80, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 7, + "endLine": 81, + "endColumn": 12, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 7, + "endLine": 82, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 7, + "endLine": 85, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 2, + "endLine": 92, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 5, + "endLine": 97, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 7, + "endLine": 98, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 7, + "endLine": 99, + "endColumn": 12, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Blank\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Component,\n State,\n Column,\n Text,\n Row,\n Blank,\n Button,\n} from '@kit.ArkUI';", + "line": 103, + "column": 7, + "endLine": 103, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.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_decorators_and_interfaces_4.ets.migrate.ets b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..11f23a80cd016ecbfb67d1a20d83b439528578da --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.migrate.ets @@ -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. + */ + +import { PropRef } from '@kit.ArkUI'; + +import { + Component, + State, + Column, + Text, + Row, + Blank, + Button, +} from '@kit.ArkUI'; + +interface ChildComponentOptions { + count: number; +} + +@Component +struct SuperComponent1 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent1({ options1: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct SuperComponent2 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent2({ options2: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct SuperComponent3 { + @State countOptions: ChildComponentOptions = { count: 0 } + + build() { + Column() { + ChildComponent3({ options3: this.countOptions }) + Text(`${this.countOptions.count}`) + } + } +} + +@Component +struct ChildComponent1 { + @PropRef options1: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options1.count}`) + Blank() + Button('+').onClick(() => { + this.options1.count++; + }) + Button('-').onClick(() => { + this.options1.count--; + }) + } + } +} + +@Component +struct ChildComponent2 { + @PropRef options2: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options2.count}`) + Blank() + Button('change1').onClick(() => { + this.options2.count = 1; + }) + Button('change2').onClick(() => { + this.options2.count = 1; + }) + } + } +} + +@Component +struct ChildComponent3 { + @PropRef options3: ChildComponentOptions; + + build() { + Row() { + Text(`${this.options3.count}`) + Blank() + Button('+').onClick(() => { + ++this.options3.count; + }) + Button('-').onClick(() => { + --this.options3.count; + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.migrate.json b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..21425e4ffe167579f7e2e8c470111199c823c06a --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorators_and_interfaces_4.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": 70, + "column": 3, + "endLine": 70, + "endColumn": 11, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 3, + "endLine": 88, + "endColumn": 11, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 3, + "endLine": 106, + "endColumn": 11, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'options1' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'options1' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 88, + "column": 12, + "endLine": 88, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'options2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'options2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 106, + "column": 12, + "endLine": 106, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'options3' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'options3' 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/property_access_by_index.ets b/ets2panda/linter/test/main/property_access_by_index.ets index a19d0154802a6a02c685d077909c66a95a19c687..ad7089dbc81bbbbd6493095b8e232bc5e34f117f 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets +++ b/ets2panda/linter/test/main/property_access_by_index.ets @@ -182,3 +182,28 @@ class MyClass extends collections.BitVector { } } } + +class AA { + i: number = 1.0; + func(b: number) {} +} +let a: object = new AA(); +let b: AA = new AA(); +b[i] = 1.0; +a["i"] = 2.0; +(b as object)["i"] = 2.0; +(b as object)["func"](1.0); +(b as object)["func1"](1.0); + +class A1 { + foo1() {} + static foo() {} + aa: number = 1.0; +} +class B1{ + a: A1 = new A1(); +} +let b1: B1 = new B1(); +(b1 as object)["a"]["foo1"](); +(b1 as object)["a"]["foo"](); +(b1 as object)["a"]["aa"]; 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 7341e330faa243cfdd4795226601488b62c2f729..25a9f93078835dbe3acbe3159154fe49f5a70b35 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 @@ -14,8 +14,8 @@ "limitations under the License." ], "mode": { - "autofix": "", + "autofix": "--arkts-2", "arkts2": "", - "migrate": "" + "migrate": "--arkts-2" } } 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 ea96b93ba8af3b0c1fad7546875a92aea9916318..b9634f30d18a08ef975eff602844951a86e5900b 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,16 +14,6 @@ "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, @@ -45,33 +35,33 @@ "severity": "ERROR" }, { - "line": 33, - "column": 5, - "endLine": 33, - "endColumn": 23, - "problem": "NumericSemantics", + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 41, - "column": 7, - "endLine": 41, - "endColumn": 24, - "problem": "NumericSemantics", + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 42, - "column": 5, - "endLine": 42, - "endColumn": 25, - "problem": "NumericSemantics", + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 7, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { @@ -95,33 +85,33 @@ "severity": "ERROR" }, { - "line": 53, + "line": 57, "column": 5, - "endLine": 53, - "endColumn": 19, - "problem": "NumericSemantics", + "endLine": 57, + "endColumn": 27, + "problem": "AnyType", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 54, - "column": 5, - "endLine": 54, - "endColumn": 25, - "problem": "NumericSemantics", + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 23, + "problem": "BuiltinNewCtor", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { "line": 57, - "column": 5, + "column": 14, "endLine": 57, "endColumn": 27, - "problem": "AnyType", + "problem": "GenericCallNoTypeArgs", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, { @@ -129,9 +119,199 @@ "column": 14, "endLine": 57, "endColumn": 27, - "problem": "GenericCallNoTypeArgs", + "problem": "UninitializedArrayElements", "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 1, + "endLine": 74, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 1, + "endLine": 78, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 1, + "endLine": 79, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 1, + "endLine": 82, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 1, + "endLine": 84, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 18, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 1, + "endLine": 98, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 1, + "endLine": 99, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", "severity": "ERROR" }, { @@ -169,9 +349,9 @@ "column": 17, "endLine": 108, "endColumn": 40, - "problem": "AvoidUnionTypes", + "problem": "BuiltinIteratorResultValue", "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", "severity": "ERROR" }, { @@ -179,9 +359,19 @@ "column": 15, "endLine": 112, "endColumn": 38, - "problem": "AvoidUnionTypes", + "problem": "BuiltinIteratorResultValue", "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", "severity": "ERROR" }, { @@ -219,9 +409,9 @@ "column": 15, "endLine": 118, "endColumn": 36, - "problem": "AvoidUnionTypes", + "problem": "BuiltinIteratorResultValue", "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", "severity": "ERROR" }, { @@ -229,9 +419,9 @@ "column": 13, "endLine": 121, "endColumn": 34, - "problem": "AvoidUnionTypes", + "problem": "BuiltinIteratorResultValue", "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", "severity": "ERROR" }, { @@ -241,7 +431,27 @@ "endColumn": 31, "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 16, + "endLine": 139, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 23, + "endLine": 150, + "endColumn": 29, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", "severity": "ERROR" }, { @@ -285,24 +495,94 @@ "severity": "ERROR" }, { - "line": 177, - "column": 23, - "endLine": 177, - "endColumn": 34, - "problem": "NoNeedStdLibSendableContainer", + "line": 176, + "column": 1, + "endLine": 176, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", "suggest": "", - "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" }, { - "line": 180, - "column": 14, - "endLine": 180, + "line": 192, + "column": 1, + "endLine": 192, + "endColumn": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 1, + "endLine": 193, + "endColumn": 7, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 1, + "endLine": 194, "endColumn": 19, - "problem": "NumericSemantics", + "problem": "PropertyAccessByIndex", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 1, + "endLine": 195, + "endColumn": 22, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 196, + "column": 1, + "endLine": 196, + "endColumn": 23, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 1, + "endLine": 207, + "endColumn": 20, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 1, + "endLine": 208, + "endColumn": 20, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 1, + "endLine": 209, + "endColumn": 20, + "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_access_by_index.ets.autofix.json b/ets2panda/linter/test/main/property_access_by_index.ets.autofix.json index f1ca92fec988d00ac08f6046bf68933a27b0ca0a..81759dc802bad675bf52dadb44e0de23ff3ea5b0 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.autofix.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.autofix.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-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,6 +34,46 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "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, @@ -54,6 +94,246 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 23, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 14, + "endLine": 57, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 14, + "endLine": 57, + "endColumn": 27, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 1, + "endLine": 74, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 1, + "endLine": 78, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 1, + "endLine": 79, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 1, + "endLine": 82, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 1, + "endLine": 84, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 18, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 1, + "endLine": 98, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 1, + "endLine": 99, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 24, + "endLine": 107, + "endColumn": 39, + "problem": "ArrayIndexExprType", + "suggest": "", + "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, @@ -64,6 +344,56 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 108, + "column": 17, + "endLine": 108, + "endColumn": 40, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 15, + "endLine": 112, + "endColumn": 38, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 20, + "endLine": 117, + "endColumn": 35, + "problem": "ArrayIndexExprType", + "suggest": "", + "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, @@ -74,6 +404,56 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 118, + "column": 15, + "endLine": 118, + "endColumn": 36, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 13, + "endLine": 121, + "endColumn": 34, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "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": 139, + "column": 16, + "endLine": 139, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 23, + "endLine": 150, + "endColumn": 29, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, { "line": 159, "column": 3, @@ -83,6 +463,181 @@ "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" + }, + { + "line": 176, + "column": 1, + "endLine": 176, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", + "autofix": [ + { + "start": 3701, + "end": 3710, + "replacementText": "", + "line": 176, + "column": 1, + "endLine": 176, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 1, + "endLine": 192, + "endColumn": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 1, + "endLine": 193, + "endColumn": 7, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 1, + "endLine": 194, + "endColumn": 19, + "problem": "PropertyAccessByIndex", + "autofix": [ + { + "replacementText": "b.i", + "start": 3992, + "end": 4010, + "line": 194, + "column": 1, + "endLine": 194, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 1, + "endLine": 195, + "endColumn": 22, + "problem": "PropertyAccessByIndex", + "autofix": [ + { + "replacementText": "b.func", + "start": 4018, + "end": 4039, + "line": 195, + "column": 1, + "endLine": 195, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 196, + "column": 1, + "endLine": 196, + "endColumn": 23, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 1, + "endLine": 207, + "endColumn": 20, + "problem": "PropertyAccessByIndex", + "autofix": [ + { + "replacementText": "b1.a.foo1", + "start": 4194, + "end": 4221, + "line": 207, + "column": 1, + "endLine": 207, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 1, + "endLine": 208, + "endColumn": 20, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 1, + "endLine": 209, + "endColumn": 20, + "problem": "PropertyAccessByIndex", + "autofix": [ + { + "replacementText": "b1.a.aa", + "start": 4255, + "end": 4280, + "line": 209, + "column": 1, + "endLine": 209, + "endColumn": 20 + } + ], + "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_access_by_index.ets.json b/ets2panda/linter/test/main/property_access_by_index.ets.json index f1ca92fec988d00ac08f6046bf68933a27b0ca0a..18153ecebacd4a6737b2d4af02623fe7c41582df 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.json @@ -83,6 +83,16 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" + }, + { + "line": 192, + "column": 1, + "endLine": 192, + "endColumn": 5, + "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_access_by_index.ets.migrate.ets b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets index a19d0154802a6a02c685d077909c66a95a19c687..5c3daa1efb77df425212300003507ef2b8ce2a65 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets @@ -173,6 +173,11 @@ mmap1[1]; mmap2['222']; mmap3["kkr"]; + + + + + @Sendable class MyClass extends collections.BitVector { constructor() { @@ -182,3 +187,28 @@ class MyClass extends collections.BitVector { } } } + +class AA { + i: number = 1.0; + func(b: number) {} +} +let a: object = new AA(); +let b: AA = new AA(); +b[i] = 1.0; +a["i"] = 2.0; +b.i = 2.0; +b.func(1.0); +(b as object)["func1"](1.0); + +class A1 { + foo1() {} + static foo() {} + aa: number = 1.0; +} +class B1{ + a: A1 = new A1(); +} +let b1: B1 = new B1(); +b1.a.foo1(); +(b1 as object)["a"]["foo"](); +b1.a.aa; diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json index e700885404cdb3909d85aea7ff974569658ce43f..aaf5bc6ce17f19367788bc5ab6df81d7487b8d3d 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json @@ -34,6 +34,46 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 1, + "endLine": 38, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 1, + "endLine": 39, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "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, @@ -54,6 +94,246 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 23, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 14, + "endLine": 57, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 14, + "endLine": 57, + "endColumn": 27, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 1, + "endLine": 74, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 1, + "endLine": 75, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 1, + "endLine": 78, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 1, + "endLine": 79, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 1, + "endLine": 82, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 1, + "endLine": 84, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 18, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 1, + "endLine": 98, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 1, + "endLine": 99, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 24, + "endLine": 107, + "endColumn": 39, + "problem": "ArrayIndexExprType", + "suggest": "", + "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, @@ -64,6 +344,56 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 108, + "column": 17, + "endLine": 108, + "endColumn": 40, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 15, + "endLine": 112, + "endColumn": 38, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 20, + "endLine": 117, + "endColumn": 35, + "problem": "ArrayIndexExprType", + "suggest": "", + "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, @@ -74,6 +404,56 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 118, + "column": 15, + "endLine": 118, + "endColumn": 36, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 13, + "endLine": 121, + "endColumn": 34, + "problem": "BuiltinIteratorResultValue", + "suggest": "", + "rule": "The property of IteratorResult is not supported (arkts-builtin-iterator-result-value)", + "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": 139, + "column": 16, + "endLine": 139, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 23, + "endLine": 150, + "endColumn": 29, + "problem": "BuiltinFinalClass", + "suggest": "", + "rule": "API is not support use class in this API (arkts-builtin-final-class)", + "severity": "ERROR" + }, { "line": 159, "column": 3, @@ -83,6 +463,86 @@ "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" + }, + { + "line": 181, + "column": 1, + "endLine": 181, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 5, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 1, + "endLine": 198, + "endColumn": 7, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 1, + "endLine": 201, + "endColumn": 23, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 1, + "endLine": 213, + "endColumn": 20, + "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/props_by_index.ets b/ets2panda/linter/test/main/props_by_index.ets new file mode 100644 index 0000000000000000000000000000000000000000..63c685415bf91a103d34a61f88715c5016af29df --- /dev/null +++ b/ets2panda/linter/test/main/props_by_index.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. + */ + +enum TEST { + A, + B, + C +} +const arr = ['a', 'b', 'c']; + +const val = TEST[1]; //error +const value: number = TEST.A; +const arrVal = arr[1]; +let a = 1; +let b = 2.3; +let c = "str"; +let d3 = TEST[TEST.A]; +let d4 = TEST[a]; //error +let d5 = TEST[b]; //error +let d2 = TEST['A']; //error +enum E { A, B, C } +console.log(E[E.A]); +function foo(e: E) { + console.log(E[e]); +} +foo(E.B); +console.log(E[2 as E]); +enum Color { Red, Green = 10, Blue } +enum E1 { One = 1, one = 1, oNe = 1 } +console.log(E1[1 as E1]) +let c1: Color = Color.Green; +console.log(c1.toString()) +console.log(Color[c1]); +enum G { + A = 1, + B = 2 +} +console.log(G[G.A]); \ No newline at end of file diff --git a/ets2panda/linter/test/main/props_by_index.ets.args.json b/ets2panda/linter/test/main/props_by_index.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/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/main/props_by_index.ets.arkts2.json b/ets2panda/linter/test/main/props_by_index.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..98832b1b5448b7c29133b137760fca2bd896d65d --- /dev/null +++ b/ets2panda/linter/test/main/props_by_index.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": 23, + "column": 13, + "endLine": 23, + "endColumn": 20, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 16, + "endLine": 25, + "endColumn": 22, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 10, + "endLine": 31, + "endColumn": 17, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 10, + "endLine": 32, + "endColumn": 19, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-enum-no-props-by-index)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/props_by_index.ets.json b/ets2panda/linter/test/main/props_by_index.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/props_by_index.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/provide_annotation_1.ets.arkts2.json b/ets2panda/linter/test/main/provide_annotation_1.ets.arkts2.json index a11e915085f45661608340affe7a0f9687cdf9f6..e8bb63999f47ea6908931a670a4e1b089891cb0d 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.arkts2.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", @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json index 499fa5b2964077f05d7b44e759e4cc617cc850c0..67135c7a114922a3f1d5f50fa017c744c51ff8c3 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "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", @@ -24,7 +24,11 @@ { "start": 727, "end": 744, - "replacementText": "@Provide({ alias: \"value\" })" + "replacementText": "@Provide({ alias: \"value\" })", + "line": 28, + "column": 3, + "endLine": 29, + "endColumn": 17 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 830, "end": 864, - "replacementText": "@Provide({ alias: \"value\", allowOverride: true })" + "replacementText": "@Provide({ alias: \"value\", allowOverride: true })", + "line": 38, + "column": 3, + "endLine": 39, + "endColumn": 17 } ], "suggest": "", @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -194,11 +234,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets index ba3e7877529a70f08c4e368f72f937afb629de7e..c51f5678f72925749a0418ba9313bbce4104e80b 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets @@ -13,7 +13,11 @@ * limitations under the License. */ -import { Component, Provide, Column } from '@kit.ArkUI'; +import { + Component, + Provide, + Column, +} from '@kit.ArkUI'; @Component struct Index { diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json index 2817e72894d499711b29674c52d22fb304b2bd01..71463836c011a647af3e14dfa9f2006b1e147a7a 100644 --- a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", + "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", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 21, + "line": 25, "column": 3, - "endLine": 21, + "endLine": 25, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 35, "column": 3, - "endLine": 31, + "endLine": 35, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 45, "column": 3, - "endLine": 41, + "endLine": 45, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json b/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json index 5683673096519aab356d8c5e39f24523630fc5f8..2b7ce66f0b867689a319db6eeb32f13a0bade09c 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json index f828839e124ace4ad3d38b7f2893c16b7f4d09d7..249ef42308798e8739f02587cf64b89de1b82468 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json @@ -24,11 +24,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,11 +45,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Provide\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n Provide,\n Column,\n} from '@kit.ArkUI';", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets index ba3e7877529a70f08c4e368f72f937afb629de7e..c51f5678f72925749a0418ba9313bbce4104e80b 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets @@ -13,7 +13,11 @@ * limitations under the License. */ -import { Component, Provide, Column } from '@kit.ArkUI'; +import { + Component, + Provide, + Column, +} from '@kit.ArkUI'; @Component struct Index { diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json index 2817e72894d499711b29674c52d22fb304b2bd01..4a6bd5efbe2d3be6c307e6c666694b9135c37fb8 100644 --- a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 21, + "line": 25, "column": 3, - "endLine": 21, + "endLine": 25, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 35, "column": 3, - "endLine": 31, + "endLine": 35, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 45, "column": 3, - "endLine": 41, + "endLine": 45, "endColumn": 8, "problem": "StrictDiagnostic", "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets b/ets2panda/linter/test/main/repeat_virtualscroll.ets new file mode 100644 index 0000000000000000000000000000000000000000..62dcc3104ad0cf3c21f69ec908f3bb2b23b37851 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Entry +@ComponentV2 +struct RepeatExampleWithTemplates { + @Local dataArr: Array = []; + + aboutToAppear(): void { + for (let i = 0; i < 50; i++) { + this.dataArr.push(`data_${i}`); + } + } + + build() { + Column() { + List() { + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + + Repeat(this.dataArr) + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..b6272423c4fa316906e1100ef22d4a88842f487f --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.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": 36, + "column": 62, + "endLine": 36, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 62, + "endLine": 36, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 62, + "endLine": 46, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 62, + "endLine": 46, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 22, + "endLine": 41, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 22, + "endLine": 49, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..b06ce8f88287a5cb6e95231d593fb3beac48a855 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json @@ -0,0 +1,499 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 62, + "endLine": 36, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 62, + "endLine": 36, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1494, + "end": 1494, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 62, + "endLine": 46, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 62, + "endLine": 46, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1717, + "end": 1717, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1755, + "end": 1755, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 22, + "endLine": 41, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 22, + "endLine": 49, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..167e6d4f74d5fd4df4bd1482ed5bb9f08c55d25b --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entry, + ComponentV2, + Local, + Column, + List, + Repeat, + RepeatItem, + ListItem, + Text, +} from '@kit.ArkUI'; + +@Entry +@ComponentV2 +struct RepeatExampleWithTemplates { + @Local dataArr: Array = []; + + aboutToAppear(): void { + for (let i = 0; i < 50; i++) { + this.dataArr.push(`data_${i}`); + } + } + + build() { + Column() { + List() { + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .virtualScroll({ disableVirtualScroll: true }) + + Repeat(this.dataArr) + .virtualScroll({ disableVirtualScroll: true }) + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e82e1454e9345d1cc59e56980159bd2c2615ecd3 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.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": 48, + "column": 62, + "endLine": 48, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 62, + "endLine": 48, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 62, + "endLine": 58, + "endColumn": 71, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 62, + "endLine": 58, + "endColumn": 71, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "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 index 435c6ac0e6817708630365cdac50f50fdb0b8e78..6e495cef33dd66ac99f04d97ca86c94df3990aee 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets +++ b/ets2panda/linter/test/main/runtime_array_bound.ets @@ -86,5 +86,237 @@ newIndex = 22; arr10[newIndex]; +let arr = [0, 1, 2, 3, 4, 5] +for(let i = 0; i < arr.length; i++) { +arr[i] = arr[i] + 1; +} +for(let i = 0; i < arr.length; i++) { +i = 10; +arr[i] = arr[i] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 2; +if(idx > 0 && idx < arr.length) { +arr[idx] = arr[idx] + 1; +} +if(idx > 0 && idx < arr.length) { +idx = 10; +arr[idx] = arr[idx] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 0; +while(idx > 0 && idx < arr.length) { +arr[idx] = arr[idx] + 1; +idx++; +idx = 10; +} +while(idx > 0 && idx < arr.length) { +idx = 10; +arr[idx] = arr[idx] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 0; +arr[idx]; +arr[10]; +if (arr.length > 10) { +arr[10] = 10; +} + +function foo():int{ +return 1; +} + +arr[44/3]; +arr[foo()]; +arr[()=>{return 1}]; +if(arr.length > foo()) { +arr[foo()]; +} +if(arr.length > 44/3) { +arr[4*4/3]; +} + +let arr1:number[] = [1, 1.5,45,2] + +function foo(i:number):number{ + return i; +} + +arr1[3*5] = 23; +arr1[parseInt("16")] = 23; +arr1[foo(16)] = 23 + +let arr1:number[] = [1, 1.5,45,2] + +arr1[Number.MAX_VALUE] = 23; +arr1[Number.MAX_SAFE_INTEGER] = 23; + +let arr1:number[] = [1, 1.5,45,2] +function foo(i:number):number{ + return i; +} +arr1[(24)] = 23; +arr1[+24] = 23; +enum TE{ + AA = 12 +} +arr1[TE.AA] = 12; + +let a: string[] = []; +let b: Array = new Array(a.length); +for (let i = 0; i < a.length; i++) { + b[i]; +} + +function test1(arr: object[]) { + if (arr.length == 1 && arr[0] instanceof Array) {} +} + +function test2(arr: object[]) { + const str = arr.length < 2 ? arr[0] : arr[1]; +} + +function test3(arr: object[]) { + let index = 1; + if (index < arr.length) { + const value = arr[index++]; + } + + if (index > arr.length) { + const value = arr[++index]; + } +} + +function test4(arr?: object[]) { + if (arr && arr.length > 0) { + const a = arr[0]; + } +} + +function test5(arrA: object[], arrB: object[]) { + const length = Math.max(arrA.length, arrB.length); + for (let i = 0; i < length; i++) { + let numA = arrA[i] || 0; + let numB = arrB[i] || 0; + } +} + +function test6(arr: object[]) { + if(arr.length < 2){ + arr[0] + } +} + +let arr:number[]=[]; +if(arr.length > 1){ + arr[1] +} + +let arr1 = [0, 1, 2, 3, 4, 5] +let arr2 = new Array(); +let arr3 = new Array(10) + +let index1 = 0 +let index2 = 1 +let index3 = 2 + + +arr1[index1] + +if (index1 >= 0 && index1 < arr1.length) { + arr1[index1] +} + +arr1[3] + +if (arr1.length > 3) { + arr1[3] +} + +for(let i = 0; i < arr1.length; i++) { + arr1[i]; +} + +let i = 0; +while(i < arr1.length) { + arr1[i]; +} + +if (index1 >= 0 && index1 < arr1.length) { + index1 = 100 + arr1[index1] +} + +let a: string[] = []; +let b: Array = new Array(a.length); +for (let i = 0; i < a.length; i++) { + b[i]; +} + +for (let i = 0; i < a.length; i++) { + b.push("abc"); + b[i]; +} + +for (let i = 0; i < a.length; i++) { + b.pop(); + b[i]; +} + +let arr_len = 8; +let b: Array = new Array(arr_len); +for (let i = 0; i < arr_len; i++) { + b[i]; +} + +function test7(config: Record, name: string) { + if (config[name][getValue()]) { + + } +} + +function getValue(): string { + return ''; +} + +const arr: Record = {}; +let keys: string[] = Object.keys(arr); +let values: string[] = Object.values(arr); +for (let i = 0; i < keys.length; i++) { + values[i]; +} + +const arr: Map = new Map(); +let keys: string[] = Object.keys(arr); +let values: string[] = Object.values(arr); +for (let i = 0; i < keys.length; i++) { + values[i]; +} + +let concatArray: ConcatArray = new Array(1.0, 2.0, 3.0); + +let tempNum: number = concatArray[5]; + + +for (let i = 0; i < concatArray.length; i++) { + concatArray[i] +}; + +if (concatArray.length > 10) { + concatArray[10] +}; + +class DummyClass { + public a1: Array = new Array(); + + foo() { + this.a1[123] = 123; + } +} +let dc = new DummyClass(); +dc.a1[123] = 1234; diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.args.json b/ets2panda/linter/test/main/runtime_array_bound.ets.args.json index 8a4be28991e8164c0366b8b3ad0dffbc04910a27..18566d7d5af12119eda3f7c6a7d4859530d7b726 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.args.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.args.json @@ -1,20 +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" - } + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT 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 index 134de695ab064c209275b6d0d13585cd29425c75..ee1c3bc9cd211b99eebaa197824dfab56ab5353b 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json @@ -1,123 +1,383 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT 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": 19, - "column": 10, - "endLine": 19, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 13, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 23, - "column": 10, - "endLine": 23, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 13, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 29, + "line": 45, "column": 5, - "endLine": 29, - "endColumn": 13, + "endLine": 45, + "endColumn": 12, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 28, + "line": 59, + "column": 1, + "endLine": 59, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, "column": 10, - "endLine": 28, - "endColumn": 15, - "problem": "NumericSemantics", + "endLine": 95, + "endColumn": 16, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 34, + "line": 105, + "column": 1, + "endLine": 105, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 12, + "endLine": 105, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 1, + "endLine": 117, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 12, + "endLine": 117, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 1, + "endLine": 123, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 1, + "endLine": 125, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 1, + "endLine": 130, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 1, + "endLine": 132, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 132, "column": 5, - "endLine": 34, - "endColumn": 13, + "endLine": 132, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 1, + "endLine": 133, + "endColumn": 11, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 33, - "column": 10, - "endLine": 33, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 134, + "column": 1, + "endLine": 134, + "endColumn": 20, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 40, + "line": 134, "column": 5, - "endLine": 40, - "endColumn": 12, + "endLine": 134, + "endColumn": 19, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 1, + "endLine": 136, + "endColumn": 11, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 39, - "column": 10, - "endLine": 39, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 139, + "column": 1, + "endLine": 139, + "endColumn": 11, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 45, + "line": 139, "column": 5, - "endLine": 45, - "endColumn": 12, + "endLine": 139, + "endColumn": 10, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 1, + "endLine": 146, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 1, + "endLine": 148, + "endColumn": 10, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 44, - "column": 10, - "endLine": 44, - "endColumn": 15, - "problem": "NumericSemantics", + "line": 149, + "column": 1, + "endLine": 149, + "endColumn": 21, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 6, + "endLine": 149, + "endColumn": 20, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 1, + "endLine": 150, + "endColumn": 14, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 6, + "endLine": 150, + "endColumn": 13, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 1, + "endLine": 154, + "endColumn": 23, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 6, + "endLine": 154, + "endColumn": 22, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 1, + "endLine": 155, + "endColumn": 30, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 6, + "endLine": 155, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 1, + "endLine": 160, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 1, + "endLine": 161, + "endColumn": 11, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 67, + "line": 162, "column": 1, - "endLine": 67, + "endLine": 162, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 1, + "endLine": 166, "endColumn": 12, "problem": "RuntimeArrayCheck", "suggest": "", @@ -125,19 +385,119 @@ "severity": "ERROR" }, { - "line": 71, - "column": 5, - "endLine": 71, - "endColumn": 16, + "line": 169, + "column": 28, + "endLine": 169, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 24, + "endLine": 169, + "endColumn": 43, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 24, + "endLine": 169, + "endColumn": 43, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 185, + "column": 23, + "endLine": 185, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 19, + "endLine": 189, + "endColumn": 31, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 76, + "line": 189, + "column": 23, + "endLine": 189, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 16, + "endLine": 219, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 16, + "endLine": 220, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 12, + "endLine": 220, + "endColumn": 33, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 227, + "column": 1, + "endLine": 227, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 1, + "endLine": 233, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 250, "column": 5, - "endLine": 76, + "endLine": 250, "endColumn": 17, "problem": "RuntimeArrayCheck", "suggest": "", @@ -145,24 +505,164 @@ "severity": "ERROR" }, { - "line": 80, + "line": 254, + "column": 28, + "endLine": 254, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 24, + "endLine": 254, + "endColumn": 43, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 24, + "endLine": 254, + "endColumn": 43, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 266, + "column": 3, + "endLine": 266, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 270, + "column": 28, + "endLine": 270, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 270, + "column": 24, + "endLine": 270, + "endColumn": 42, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 270, + "column": 24, + "endLine": 270, + "endColumn": 42, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 276, + "column": 7, + "endLine": 276, + "endColumn": 31, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 287, "column": 5, - "endLine": 80, - "endColumn": 18, - "problem": "NumericSemantics", + "endLine": 287, + "endColumn": 42, + "problem": "ArrayTypeImmutable", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, { - "line": 87, - "column": 1, - "endLine": 87, + "line": 292, + "column": 34, + "endLine": 292, + "endColumn": 43, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 5, + "endLine": 294, + "endColumn": 42, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 299, + "column": 44, + "endLine": 299, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 301, + "column": 23, + "endLine": 301, + "endColumn": 37, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 36, + "endLine": 313, + "endColumn": 41, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 9, + "endLine": 316, "endColumn": 16, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" + }, + { + "line": 322, + "column": 1, + "endLine": 322, + "endColumn": 6, + "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 index bd1b7140ca95b67336908f5fca6dec77fb46b2c0..9f305c86d7ff705098b1e480818e125d5e6e3a4a 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.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": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES 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 index 261214843c9393f03bfda1d5d7f9dcb868660b31..9bce28bb8e79180278cc024b015009c47d4ed40a 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets @@ -16,32 +16,32 @@ const arr: int[] = [1, 2, 3, 4]; -for (let i: number = 0; i < arr.length; i++) { +for (let i = 0; i < arr.length; i++) { arr[i]; //legal } -for (let i: number = 0; i < 100; i++) { +for (let i = 0; i < 100; i++) { console.log(i); //legal } const arr2: int[] = [1, 2, 3, 4]; -for (let i: number = 0; i < 100; i++) { +for (let i = 0; i < 100; i++) { arr2[10] //should report } const arr3: int[] = [1, 2, 3, 4]; -for (let i: number = 0; i < arr3.length; i++) { +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: number = 0; i < arr4.length; i++) { +for (let i = 0; i < arr4.length; i++) { arr4[x]; //should report } const arr5: int[] = [1, 2, 3, 4]; -for (let i: number = 0; i < 10; i++) { +for (let i = 0; i < 10; i++) { arr5[i]; //should report } @@ -77,7 +77,7 @@ if (index > 0) { } const arr10: int[] = [1, 2, 3, 4]; -let newIndex: number = 10; +let newIndex = 10; if (arr10.length > newIndex) { return; } @@ -86,5 +86,237 @@ newIndex = 22; arr10[newIndex]; +let arr = [0, 1, 2, 3, 4, 5] +for(let i = 0; i < arr.length; i++) { +arr[i] = arr[i] + 1; +} +for(let i = 0; i < arr.length; i++) { +i = 10; +arr[i] = arr[i] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 2; +if(idx > 0 && idx < arr.length) { +arr[idx] = arr[idx] + 1; +} +if(idx > 0 && idx < arr.length) { +idx = 10; +arr[idx] = arr[idx] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 0; +while(idx > 0 && idx < arr.length) { +arr[idx] = arr[idx] + 1; +idx++; +idx = 10; +} +while(idx > 0 && idx < arr.length) { +idx = 10; +arr[idx] = arr[idx] + 1; +} + +let arr = [0, 1, 2, 3, 4, 5] +let idx = 0; +arr[idx]; +arr[10]; +if (arr.length > 10) { +arr[10] = 10; +} + +function foo():int{ +return 1; +} + +arr[(44/3) as int]; +arr[foo()]; +arr[()=>{return 1}]; +if(arr.length > foo()) { +arr[foo()]; +} +if(arr.length > 44/3) { +arr[(4*4/3) as int]; +} + +let arr1:number[] = [1, 1.5,45,2] + +function foo(i:number):number{ + return i; +} + +arr1[3*5] = 23; +arr1[parseInt("16") as int] = 23; +arr1[foo(16) as int] = 23 + +let arr1:number[] = [1, 1.5,45,2] + +arr1[Number.MAX_VALUE as int] = 23; +arr1[Number.MAX_SAFE_INTEGER as int] = 23; + +let arr1:number[] = [1, 1.5,45,2] +function foo(i:number):number{ + return i; +} +arr1[(24)] = 23; +arr1[+24] = 23; +enum TE{ + AA = 12 +} +arr1[TE.AA] = 12; + +let a: string[] = []; +let b: Array = new Array(a.length); +for (let i = 0; i < a.length; i++) { + b[i]; +} + +function test1(arr: object[]) { + if (arr.length == 1 && arr[0] instanceof Array) {} +} + +function test2(arr: object[]) { + const str = arr.length < 2 ? arr[0] : arr[1]; +} + +function test3(arr: object[]) { + let index = 1; + if (index < arr.length) { + const value = arr[index++ as int]; + } + + if (index > arr.length) { + const value = arr[++index as int]; + } +} + +function test4(arr?: object[]) { + if (arr && arr.length > 0) { + const a = arr[0]; + } +} + +function test5(arrA: object[], arrB: object[]) { + const length = Math.max(arrA.length, arrB.length); + for (let i = 0; i < length; i++) { + let numA = arrA[i] || 0; + let numB = arrB[i] || 0; + } +} + +function test6(arr: object[]) { + if(arr.length < 2){ + arr[0] + } +} + +let arr:number[]=[]; +if(arr.length > 1){ + arr[1] +} + +let arr1 = [0, 1, 2, 3, 4, 5] +let arr2 = new Array(); +let arr3 = new Array(10) + +let index1 = 0 +let index2 = 1 +let index3 = 2 + + +arr1[index1] + +if (index1 >= 0 && index1 < arr1.length) { + arr1[index1] +} + +arr1[3] + +if (arr1.length > 3) { + arr1[3] +} + +for(let i = 0; i < arr1.length; i++) { + arr1[i]; +} + +let i = 0; +while(i < arr1.length) { + arr1[i]; +} + +if (index1 >= 0 && index1 < arr1.length) { + index1 = 100 + arr1[index1] +} + +let a: string[] = []; +let b: Array = new Array(a.length); +for (let i = 0; i < a.length; i++) { + b[i]; +} + +for (let i = 0; i < a.length; i++) { + b.push("abc"); + b[i]; +} + +for (let i = 0; i < a.length; i++) { + b.pop(); + b[i]; +} + +let arr_len = 8; +let b: Array = new Array(arr_len); +for (let i = 0; i < arr_len; i++) { + b[i]; +} + +function test7(config: Record, name: string) { + if (config[name][getValue()]) { + + } +} + +function getValue(): string { + return ''; +} + +const arr: Record = {}; +let keys: string[] = Object.keys(arr); +let values: string[] = Object.values(arr); +for (let i = 0; i < keys.length; i++) { + values[i]; +} + +const arr: Map = new Map(); +let keys: string[] = Object.keys(arr); +let values: string[] = Object.values(arr); +for (let i = 0; i < keys.length; i++) { + values[i]; +} + +let concatArray: ConcatArray = new Array(1.0, 2.0, 3.0); + +let tempNum: number = concatArray[5]; + + +for (let i = 0; i < concatArray.length; i++) { + concatArray[i] +}; + +if (concatArray.length > 10) { + concatArray[10] +}; + +class DummyClass { + public a1: Array = new Array(); + + foo() { + this.a1[123] = 123; + } +} +let dc = new DummyClass(); +dc.a1[123] = 1234; diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json index d472b1c6cc9d61f69619525ff8267eee0e555d22..9998799a22d5f58e07afaf62deed8976c7696032 100644 --- a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 45, "column": 5, - "endLine": 40, + "endLine": 45, "endColumn": 12, "problem": "RuntimeArrayCheck", "suggest": "", @@ -45,19 +45,219 @@ "severity": "ERROR" }, { - "line": 45, + "line": 59, + "column": 1, + "endLine": 59, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 10, + "endLine": 95, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 1, + "endLine": 105, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 12, + "endLine": 105, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 1, + "endLine": 117, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 12, + "endLine": 117, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 1, + "endLine": 123, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 1, + "endLine": 125, + "endColumn": 8, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 1, + "endLine": 130, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 1, + "endLine": 133, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 1, + "endLine": 134, + "endColumn": 20, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 134, "column": 5, - "endLine": 45, - "endColumn": 12, + "endLine": 134, + "endColumn": 19, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 1, + "endLine": 136, + "endColumn": 11, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 67, + "line": 144, "column": 1, - "endLine": 67, + "endLine": 146, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 1, + "endLine": 148, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 1, + "endLine": 160, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 1, + "endLine": 161, + "endColumn": 11, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 1, + "endLine": 162, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 1, + "endLine": 166, "endColumn": 12, "problem": "RuntimeArrayCheck", "suggest": "", @@ -65,19 +265,79 @@ "severity": "ERROR" }, { - "line": 71, - "column": 5, - "endLine": 71, - "endColumn": 16, + "line": 169, + "column": 28, + "endLine": 169, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 24, + "endLine": 169, + "endColumn": 51, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 219, + "column": 16, + "endLine": 219, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 16, + "endLine": 220, + "endColumn": 21, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 12, + "endLine": 220, + "endColumn": 33, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 227, + "column": 1, + "endLine": 227, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 233, + "column": 1, + "endLine": 233, + "endColumn": 8, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 76, + "line": 250, "column": 5, - "endLine": 76, + "endLine": 250, "endColumn": 17, "problem": "RuntimeArrayCheck", "suggest": "", @@ -85,14 +345,134 @@ "severity": "ERROR" }, { - "line": 87, - "column": 1, - "endLine": 87, + "line": 254, + "column": 28, + "endLine": 254, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 254, + "column": 24, + "endLine": 254, + "endColumn": 51, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 266, + "column": 3, + "endLine": 266, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 270, + "column": 28, + "endLine": 270, + "endColumn": 33, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 270, + "column": 24, + "endLine": 270, + "endColumn": 50, + "problem": "UninitializedArrayElements", + "suggest": "", + "rule": "Please init elements of array before read elements. If not, there will be a runtime error. We recommend you to use Array.create(len, T) (arkts-builtin-uninitialized-element)", + "severity": "WARNING" + }, + { + "line": 276, + "column": 7, + "endLine": 276, + "endColumn": 31, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 5, + "endLine": 287, + "endColumn": 42, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 5, + "endLine": 294, + "endColumn": 42, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 299, + "column": 44, + "endLine": 299, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 301, + "column": 23, + "endLine": 301, + "endColumn": 37, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 36, + "endLine": 313, + "endColumn": 41, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 9, + "endLine": 316, "endColumn": 16, "problem": "RuntimeArrayCheck", "suggest": "", "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" + }, + { + "line": 322, + "column": 1, + "endLine": 322, + "endColumn": 6, + "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/sdk_ability_asynchronous_lifecycle.ets b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3af1c4b7764f50f47272f85f4e3c83fe158323d --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets @@ -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 { UIAbility } from '@kit.AbilityKit'; +import { UIExtensionAbility } from '@kit.AbilityKit'; +import { AutoFillExtensionAbility } from '@kit.AbilityKit'; +import { ServiceExtensionAbility } from '@kit.AbilityKit'; + +function sleep(ms: number): Promise { + return new Promise((resolve, reject) => { + setTimeout(resolve, ms) + }) +} + +function sleep1(ms: number): void { + return void +} + +export default class MyUIAbility1 extends UIAbility { + async onDestroy(): Promise { // use UIAbility onDestroy, should report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +export default class MyUIAbility2 extends UIExtensionAbility { + async onDestroy(): Promise { // use UIExtensionAbility onDestroy, should report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +export default class MyUIAbility3 extends AutoFillExtensionAbility { + async onDestroy(): Promise { // use AutoFillExtensionAbility onDestroy, should report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +export default class MyUIAbility4 extends ServiceExtensionAbility { + async onDisconnect(): Promise { // use UIAbility onDestroy, should report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +export default class MyUIAbility5 extends UIAbility { + onDestroy() { // use UIAbility onDestroy with Promise return, should report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +export default class MyUIAbility6 extends UIAbility { + onDestroy() { // use UIAbility onDestroy with void return, should not report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep1(1000); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.args.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.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/sdk_ability_asynchronous_lifecycle.ets.arkts2.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..cfda66c38c923c0288d93859a6879749f93edc94 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.arkts2.json @@ -0,0 +1,128 @@ +{ + "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." + ], + "result": [ + { + "line": 22, + "column": 10, + "endLine": 24, + "endColumn": 5, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 14, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 35, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 18, + "problem": "SdkAbilityAsynchronousLifecycle", + "suggest": "", + "rule": "1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 42, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 9, + "endLine": 39, + "endColumn": 18, + "problem": "SdkAbilityAsynchronousLifecycle", + "suggest": "", + "rule": "1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 9, + "endLine": 46, + "endColumn": 18, + "problem": "SdkAbilityAsynchronousLifecycle", + "suggest": "", + "rule": "1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 21, + "problem": "SdkAbilityAsynchronousLifecycle", + "suggest": "", + "rule": "1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 63, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 12, + "problem": "SdkAbilityAsynchronousLifecycle", + "suggest": "", + "rule": "1.2 Void cannot be combined. OnDestroy/onDisconnect (The return type of the method is now void | Promise) needs to be split into two interfaces. (sdk-ability-asynchronous-lifecycle)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 70, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle.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/sdk_ability_asynchronous_lifecycle_2.ets b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d480eb33021fa05682128f0e7e3b3f00db3e9aa9 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_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 { ServiceExtensionAbility } from '@kit.AbilityKit'; + +function sleep(ms: number): Promise { + return new Promise((resolve, reject) => { + setTimeout(resolve, ms) + }) +} + +export default class MyUIAbility1 extends ServiceExtensionAbility { + async onDestroy(): Promise { // use ServiceExtensionAbility onDestroy, should not report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} + +class UIAbility {} +export default class MyUIAbility2 extends UIAbility { + async onDestroy(): Promise { // use UIAbility not from SDK, should not report error + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + return sleep(1000); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.args.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.arkts2.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e5053ea0726600fdba5c8c82e7f4d5d199ecc6b6 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_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": 10, + "endLine": 21, + "endColumn": 5, + "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/sdk_ability_asynchronous_lifecycle_2.ets.json b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_asynchronous_lifecycle_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/sdk_ability_lifecycle_monitor.ets b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3c46a743715c647bfe939c22f9f54d46d4dd7d6 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets @@ -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 AbilityStage from './oh_modules/@ohos.app.ability.AbilityStage'; +import ApplicationContext from './oh_modules/ApplicationContext'; + +class MyAbilityStage extends AbilityStage { + onCreate() { + let abilityLifecycleCallback: AbilityLifecycleCallback = { + onAbilityCreate(ability) { + }, + onWindowStageCreate: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageActive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageInactive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageDestroy: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onAbilityDestroy: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityForeground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityBackground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityContinue: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + } + } + let applicationContext = this.context.getApplicationContext(); + let lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback); // report error normally + } +} + +class MyAbilityStage extends AbilityStage { + onCreate() { + let abilityLifecycleCallback: AbilityLifecycleCallback = { + onAbilityCreate(ability) { + }, + onWindowStageCreate: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageActive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageInactive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageDestroy: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onAbilityDestroy: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityForeground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityBackground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityContinue: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + } + } + let applicationContext = new ApplicationContext(); + let lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback); // report error normally + } +} + diff --git a/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets.args.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b214d57430c6b63de949705fe4fc0db53c4bb327 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.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/sdk_ability_lifecycle_monitor.ets.arkts2.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2eff60dbc93b5e7dab7c3462f48f250aade94026 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.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": 22, + "column": 7, + "endLine": 23, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 23, + "endLine": 22, + "endColumn": 30, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 23, + "endLine": 22, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 23, + "endLine": 50, + "endColumn": 90, + "problem": "SdkAbilityLifecycleMonitor", + "suggest": "", + "rule": "The UIAbility of 1.2 needs to be listened by the new StaticAbilityLifecycleCallback. The original AbilityLifecycleCallback can only listen to the UIAbility of 1.1 (sdk-ability-lifecycle-monitor)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 7, + "endLine": 58, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 23, + "endLine": 57, + "endColumn": 30, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 23, + "endLine": 57, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 23, + "endLine": 85, + "endColumn": 90, + "problem": "SdkAbilityLifecycleMonitor", + "suggest": "", + "rule": "The UIAbility of 1.2 needs to be listened by the new StaticAbilityLifecycleCallback. The original AbilityLifecycleCallback can only listen to the UIAbility of 1.1 (sdk-ability-lifecycle-monitor)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..81beed97c616587a30286ec0e80e1fd643531b12 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor.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": 22, + "column": 23, + "endLine": 22, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 23, + "endLine": 57, + "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/sdk_ability_lifecycle_monitor_2.ets b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a16dab7436ce3fba442cfd7d0e0729ca4b569bf --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.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 AbilityStage { + context: ApplicationContext; + onCreate(): void; +} + +class ApplicationContext { + on(type: 'abilityLifecycle', callback: AbilityLifecycleCallback): number; + off(type: 'abilityLifecycle', callbackId: number, callback: AsyncCallback): void; + getApplicationContext(): ApplicationContext; +} +class MyAbilityStage extends AbilityStage { + onCreate() { + let abilityLifecycleCallback: AbilityLifecycleCallback = { + onAbilityCreate(ability) { + }, + onWindowStageCreate: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageActive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageInactive: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onWindowStageDestroy: (ability: UIAbility, windowStage: window.WindowStage): void => { + throw new Error('Function not implemented.'); + }, + onAbilityDestroy: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityForeground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityBackground: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + }, + onAbilityContinue: (ability: UIAbility): void => { + throw new Error('Function not implemented.'); + } + } + let applicationContext = this.context.getApplicationContext(); + let lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback); // No report error for the source is not target + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.args.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b214d57430c6b63de949705fe4fc0db53c4bb327 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } + } diff --git a/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.arkts2.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4833d12f26b6736d4545e18ed3814a558cd51cb7 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.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": 29, + "column": 7, + "endLine": 30, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 30, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'context' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'context' 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/sdk_ability_lifecycle_monitor_2.ets.json b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..20ef67fcd05fda79aa98cd3c55147ad84eae4786 --- /dev/null +++ b/ets2panda/linter/test/main/sdk_ability_lifecycle_monitor_2.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": 29, + "column": 23, + "endLine": 29, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'context' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'context' 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/stdlib_array.ets.arkts2.json b/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json index bcc25e7c3a7315356c27b440db185baaf050ffd0..c519ba8f6343cafcfe6b82ed9043ba3c5dc16fcf 100644 --- a/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json +++ b/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json @@ -14,6 +14,56 @@ "limitations under the License." ], "result": [ + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 23, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 18, + "endLine": 21, + "endColumn": 31, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 18, + "endLine": 25, + "endColumn": 29, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 27, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 18, + "endLine": 36, + "endColumn": 23, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, { "line": 36, "column": 28, @@ -34,6 +84,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 31, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, { "line": 37, "column": 36, @@ -54,6 +114,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 38, + "column": 18, + "endLine": 38, + "endColumn": 29, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, { "line": 38, "column": 34, @@ -74,6 +144,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 39, + "column": 18, + "endLine": 39, + "endColumn": 27, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, { "line": 39, "column": 32, @@ -95,13 +175,33 @@ "severity": "ERROR" }, { - "line": 43, - "column": 1, - "endLine": 50, - "endColumn": 2, - "problem": "NumericSemantics", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 19, + "endLine": 49, + "endColumn": 23, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 26, + "endLine": 49, + "endColumn": 30, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/structural_identity.ets b/ets2panda/linter/test/main/structural_identity.ets index eae4133097d265060b89928949fb24982901a27b..48def206813476e25f0cf507c80d32dab50be190 100644 --- a/ets2panda/linter/test/main/structural_identity.ets +++ b/ets2panda/linter/test/main/structural_identity.ets @@ -681,15 +681,19 @@ class MyObj3 { } interface goodPerson extends IPerson { - like: MyObj2, - like1: MyObj3 - } + like: MyObj2, + like1: MyObj3 +} + +let lily: goodPerson = { + like: new MyObj1(), + name: 'Alice', + age: 30, + sayHello:()=> { + return new MyObj2() + } +} - let lily:goodPerson = { - like: new MyObj1(), - name: 'Alice', - age: 30, - sayHello:()=> { - return new MyObj2() - } - } \ No newline at end of file +function foo2(rule:Record){ + let b:Array = rule['123'] as Array +} \ 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 a3b9b0c1a18acbcb484dd177dbc136b68056466c..8be66d073644657941aafc7487bf95bb9ddc7647 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -65,19 +65,19 @@ "severity": "ERROR" }, { - "line": 57, - "column": 13, - "endLine": 57, - "endColumn": 23, - "problem": "StructuralIdentity", + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 10, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 66, + "line": 57, "column": 13, - "endLine": 66, + "endLine": 57, "endColumn": 23, "problem": "StructuralIdentity", "suggest": "", @@ -424,246 +424,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 244, - "column": 1, - "endLine": 244, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 245, - "column": 1, - "endLine": 245, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 246, - "column": 1, - "endLine": 246, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 247, - "column": 1, - "endLine": 247, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 248, - "column": 1, - "endLine": 248, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 249, - "column": 1, - "endLine": 249, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 250, - "column": 1, - "endLine": 250, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 251, - "column": 1, - "endLine": 251, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 252, - "column": 1, - "endLine": 252, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 253, - "column": 1, - "endLine": 253, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 254, - "column": 1, - "endLine": 254, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 255, - "column": 1, - "endLine": 255, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 281, - "column": 1, - "endLine": 281, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 282, - "column": 1, - "endLine": 282, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 283, - "column": 1, - "endLine": 283, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 284, - "column": 1, - "endLine": 284, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 285, - "column": 1, - "endLine": 285, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 286, - "column": 1, - "endLine": 286, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 287, - "column": 1, - "endLine": 287, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 288, - "column": 1, - "endLine": 288, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 289, - "column": 1, - "endLine": 289, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 290, - "column": 1, - "endLine": 290, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 291, - "column": 1, - "endLine": 291, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 292, - "column": 1, - "endLine": 292, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 329, "column": 10, @@ -764,86 +524,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 400, - "column": 3, - "endLine": 400, - "endColumn": 11, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 401, - "column": 3, - "endLine": 401, - "endColumn": 19, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 402, - "column": 3, - "endLine": 402, - "endColumn": 19, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 406, - "column": 3, - "endLine": 406, - "endColumn": 32, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 413, - "column": 3, - "endLine": 413, - "endColumn": 13, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 414, - "column": 3, - "endLine": 414, - "endColumn": 21, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 415, - "column": 3, - "endLine": 415, - "endColumn": 21, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 419, - "column": 3, - "endLine": 419, - "endColumn": 36, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 451, "column": 3, @@ -854,36 +534,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 452, - "column": 3, - "endLine": 452, - "endColumn": 20, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 453, - "column": 3, - "endLine": 453, - "endColumn": 15, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 457, - "column": 3, - "endLine": 457, - "endColumn": 46, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 460, "column": 3, @@ -974,6 +624,26 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 480, + "column": 1, + "endLine": 480, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", + "severity": "ERROR" + }, + { + "line": 485, + "column": 1, + "endLine": 485, + "endColumn": 10, + "problem": "LimitedStdLibNoSendableDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", + "severity": "ERROR" + }, { "line": 502, "column": 7, @@ -1194,6 +864,16 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 574, + "column": 44, + "endLine": 574, + "endColumn": 49, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, { "line": 575, "column": 44, @@ -1204,6 +884,36 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 575, + "column": 44, + "endLine": 575, + "endColumn": 49, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 576, + "column": 38, + "endLine": 576, + "endColumn": 43, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 577, + "column": 38, + "endLine": 577, + "endColumn": 43, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, { "line": 578, "column": 38, @@ -1214,6 +924,26 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 578, + "column": 38, + "endLine": 578, + "endColumn": 43, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 579, + "column": 44, + "endLine": 579, + "endColumn": 49, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, { "line": 580, "column": 44, @@ -1224,6 +954,16 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 580, + "column": 44, + "endLine": 580, + "endColumn": 49, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, { "line": 590, "column": 10, @@ -1324,6 +1064,16 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 622, + "column": 45, + "endLine": 622, + "endColumn": 49, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, { "line": 626, "column": 5, @@ -1524,16 +1274,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 688, - "column": 6, - "endLine": 695, - "endColumn": 3, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 688, "column": 24, @@ -1545,4 +1285,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_2.ets b/ets2panda/linter/test/main/structural_identity_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..95729d873f528b33e3955a6fa3923ef60609f66c --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A {} +class B {} +class C extends A {} + +function test1(ab?: A | B) { + const a = ab as A ?? new A(); // No error in ArkTS 1.2 + const b = ab as B ?? new B(); // No error in ArkTS 1.2 +} + +function test2(): A | null { + return new B(); // Error in ArkTS 1.2 +} + +function test3(a: A): C | undefined { + return a ? a as C : undefined; // No error in ArkTS 1.2 +} + +function test4(): void { + console.log(new A() as B); // Error in ArkTS 1.2 + console.log(new B() as C); // Error in ArkTS 1.2 + console.log(new A() as C); // No error in ArkTS 1.2 + console.log(new C() as A); // No error in ArkTS 1.2 +} + +interface I { + a?: A; +} +let i: I = { + a: new A() // No error in ArkTS 1.2 +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.args.json b/ets2panda/linter/test/main/structural_identity_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..822b39271030b39ef5c7261d1e574d8bce8f6a43 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [ + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 17, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 15, + "endLine": 34, + "endColumn": 27, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 15, + "endLine": 35, + "endColumn": 27, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.json b/ets2panda/linter/test/main/structural_identity_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json index 521013f4fb2cdc4b4ebe21988ac696440c671c69..f4b9ec6f673f71b7b10f6292500d03544b9017e9 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 @@ -16,12 +16,22 @@ "result": [ { "line": 49, - "column": 5, + "column": 15, "endLine": 49, - "endColumn": 30, - "problem": "NumericSemantics", + "endColumn": 20, + "problem": "BuiltinNewCtor", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 18, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets b/ets2panda/linter/test/main/structural_identity_promise.ets new file mode 100644 index 0000000000000000000000000000000000000000..59edca4ff0a7985fdf09f1c14fb832e4c6ffbce9 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.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 X {} + +async function foo(): Promise{ + return new Promise(() => { }); // No error in ArkTS 1.2 +} + +async function bar(): Promise{ + return new X(); // No error in ArkTS 1.2 +} + +class PromiseTest { + protected async foo(): Promise { + let arr: X[] = []; + return arr; + } + + public async bar(): Promise { + return this.foo(); // No error in ArkTS 1.2 + } +} + +function sleep(ms: number): PromiseLike { + return new Promise( + (resolve: (value: T | PromiseLike) => void): number => setTimeout(resolve, ms) + ); +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.args.json b/ets2panda/linter/test/main/structural_identity_promise.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8687ce3be3eff8ee38ebbf2aca224f013d9fd2c3 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.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": 39, + "column": 6, + "endLine": 39, + "endColumn": 50, + "problem": "IncompationbleFunctionType", + "suggest": "", + "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.json b/ets2panda/linter/test/main/structural_identity_promise.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "result": [] +} \ No newline at end of file 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 1bf55e2d4c97c0d7db9df4c1ae69dad934df5d31..f0ee3292934303d11726ce662cd591bae822f2b6 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 @@ -19,9 +19,9 @@ "column": 18, "endLine": 40, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 31, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 d6ed03103fd54f9bb04c15856abb4d54290c9a0c..043d6203d878b0c97aee65a71fe0dd05914f51f8 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 @@ -19,16 +19,20 @@ "column": 18, "endLine": 40, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "autofix": [ { "start": 767, "end": 1035, - "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 }" + "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)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -41,11 +45,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -58,11 +66,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -75,11 +87,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -92,11 +108,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -109,11 +129,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n CommonMethod,\n Color,\n} from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 26b949ad3751a102e09f12b6e79ffb87396fb64e..f938ef2f11d7a0e4537511c6e362c4e1d48ac195 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets @@ -13,7 +13,15 @@ * limitations under the License. */ -import { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; +import { + Entry, + Component, + BuilderParam, + Require, + Button, + CommonMethod, + Color, +} from '@kit.ArkUI'; @Entry @Component 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 775283b08efecf00adb1b66e1f9ce188f305b031..a9dff46cc564c67d4e22cb069c80b524372e91e0 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 @@ -51,7 +51,7 @@ "endColumn": 23, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -71,7 +71,7 @@ "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 17, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 31, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 18, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 e7bb004c0391b3b8e3aa2fcf6f52b5518e8b9664..4c69417566f6bd3eae6549334026da9c37c54e0e 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,17 +24,29 @@ { "start": 640, "end": 835, - "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}" + "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": 929, "end": 941, - "replacementText": "applyStyles(cardStyle1)" + "replacementText": "applyStyles(cardStyle1)", + "line": 18, + "column": 1, + "endLine": 29, + "endColumn": 2 }, { "start": 961, "end": 973, - "replacementText": "applyStyles(cardStyle1)" + "replacementText": "applyStyles(cardStyle1)", + "line": 18, + "column": 1, + "endLine": 29, + "endColumn": 2 } ], "suggest": "", @@ -51,7 +63,11 @@ { "start": 1019, "end": 1086, - "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" + "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}", + "line": 42, + "column": 1, + "endLine": 45, + "endColumn": 2 } ], "suggest": "", @@ -68,7 +84,11 @@ { "start": 1088, "end": 1156, - "replacementText": "function PressedStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" + "replacementText": "function PressedStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}", + "line": 47, + "column": 1, + "endLine": 50, + "endColumn": 2 } ], "suggest": "", @@ -85,11 +105,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -102,11 +126,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -119,11 +147,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -136,11 +168,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -153,11 +189,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -170,11 +210,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -187,11 +231,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -204,11 +252,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -221,11 +273,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Component,\n Column,\n Text,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index fd272fd000da58d98840d17fbb58c3de7fc89e21..a4140d86f2013a0d800b73ffe7a2e595df2fceb1 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets @@ -13,7 +13,18 @@ * limitations under the License. */ -import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; +import { applyStyles } from '@kit.ArkUI'; + +import { + CommonMethod, + Color, + Component, + Column, + Text, + BuilderParam, + Require, + Button, +} from '@kit.ArkUI'; const mycolor: string = "#ffff00" diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets b/ets2panda/linter/test/main/styles_decorator_global_2.ets index fd272fd000da58d98840d17fbb58c3de7fc89e21..a6aa7a73dd8b09e704803a3902b984998f7df84d 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import { applyStyles } from '@kit.ArkUI'; + import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; const mycolor: string = "#ffff00" @@ -20,11 +22,11 @@ const mycolor: string = "#ffff00" function cardStyle1(instance: CommonMethod): void { instance.backgroundColor(mycolor); instance.borderColor(Color.Red); - instance.borderRadius(8); - instance.padding(8); + instance.borderRadius(8.0); + instance.padding(8.0); instance.backgroundImagePosition({ - x: 0, - y: 0 + x: 0.0, + y: 0.0 }); } 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 index fd272fd000da58d98840d17fbb58c3de7fc89e21..a6aa7a73dd8b09e704803a3902b984998f7df84d 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import { applyStyles } from '@kit.ArkUI'; + import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; const mycolor: string = "#ffff00" @@ -20,11 +22,11 @@ const mycolor: string = "#ffff00" function cardStyle1(instance: CommonMethod): void { instance.backgroundColor(mycolor); instance.borderColor(Color.Red); - instance.borderRadius(8); - instance.padding(8); + instance.borderRadius(8.0); + instance.padding(8.0); instance.backgroundImagePosition({ - x: 0, - y: 0 + x: 0.0, + y: 0.0 }); } diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json index b0c53b4c8e59d1cb200b077428a1b0c7d7cf5173..41dee5dfe6a55734d4865153b3d4d35c71e9533b 100644 --- a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json @@ -39,9 +39,9 @@ "column": 18, "endLine": 43, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -49,9 +49,9 @@ "column": 18, "endLine": 62, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -59,9 +59,9 @@ "column": 20, "endLine": 76, "endColumn": 8, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -69,9 +69,9 @@ "column": 20, "endLine": 90, "endColumn": 8, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -81,7 +81,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 31, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 31, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -231,7 +231,7 @@ "endColumn": 33, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -241,7 +241,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -261,7 +261,7 @@ "endColumn": 33, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index a84810a9e76f91e0a4988d7bb703da2ca2631e99..ed6bb9b66eb5d4a873d2bb929b435270ce3bfea5 100644 --- a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 605, "end": 673, - "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(Color.Blue);\n}" + "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(Color.Blue);\n}", + "line": 16, + "column": 1, + "endLine": 19, + "endColumn": 2 } ], "suggest": "", @@ -41,7 +45,11 @@ { "start": 765, "end": 830, - "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };" + "replacementText": "PressedStyles: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };", + "line": 28, + "column": 3, + "endLine": 31, + "endColumn": 4 } ], "suggest": "", @@ -53,16 +61,20 @@ "column": 18, "endLine": 43, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "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 }" + "replacementText": "{\n pressed: this.PressedStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }", + "line": 37, + "column": 18, + "endLine": 43, + "endColumn": 6 } ], "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -70,16 +82,20 @@ "column": 18, "endLine": 62, "endColumn": 6, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "autofix": [ { "start": 1214, "end": 1312, - "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }", + "line": 57, + "column": 18, + "endLine": 62, + "endColumn": 6 } ], "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -87,16 +103,20 @@ "column": 20, "endLine": 76, "endColumn": 8, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "autofix": [ { "start": 1407, "end": 1514, - "replacementText": "{\n normal: NormalStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n }\n }" + "replacementText": "{\n normal: NormalStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n }\n }", + "line": 71, + "column": 20, + "endLine": 76, + "endColumn": 8 } ], "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -104,16 +124,20 @@ "column": 20, "endLine": 90, "endColumn": 8, - "problem": "StylesDecoratorNotSupported", + "problem": "StateStylesBlockNeedArrowFunc", "autofix": [ { "start": 1609, "end": 1716, - "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }", + "line": 85, + "column": 20, + "endLine": 90, + "endColumn": 8 } ], "suggest": "", - "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "rule": "The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)", "severity": "ERROR" }, { @@ -126,11 +150,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -143,11 +171,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -160,11 +192,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -177,11 +213,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -194,11 +234,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,11 +255,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -228,11 +276,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -245,11 +297,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -262,11 +318,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -279,11 +339,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -296,11 +360,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -313,11 +381,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -330,11 +402,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -347,11 +423,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -364,11 +444,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -381,11 +465,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -398,11 +486,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -415,11 +507,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -432,11 +528,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n CommonMethod,\n Color,\n Entry,\n Component,\n BuilderParam,\n Require,\n Button,\n} from '@kit.ArkUI';", + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 4e9c2b35e023074c8d1813a6a7c22a487bd97e25..0829910761501f079a1d9eedf80ec39394d1170e 100644 --- a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets @@ -13,7 +13,17 @@ * limitations under the License. */ -import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; +import { CustomStyles } from '@kit.ArkUI'; + +import { + CommonMethod, + Color, + Entry, + Component, + BuilderParam, + Require, + Button, +} from '@kit.ArkUI'; function NormalStyles(instance: CommonMethod): void { instance.backgroundColor(Color.Blue); @@ -26,7 +36,7 @@ struct MyButton1 { @Require content: () => void; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets b/ets2panda/linter/test/main/styles_decorator_mix_2.ets index 4e9c2b35e023074c8d1813a6a7c22a487bd97e25..3980b18277bc24ffc33621d2f04f09515a63e424 100644 --- a/ets2panda/linter/test/main/styles_decorator_mix_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import { CustomStyles } from '@kit.ArkUI'; + import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; function NormalStyles(instance: CommonMethod): void { @@ -26,7 +28,7 @@ struct MyButton1 { @Require content: () => void; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; 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 index 4e9c2b35e023074c8d1813a6a7c22a487bd97e25..3980b18277bc24ffc33621d2f04f09515a63e424 100644 --- a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import { CustomStyles } from '@kit.ArkUI'; + import { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; function NormalStyles(instance: CommonMethod): void { @@ -26,7 +28,7 @@ struct MyButton1 { @Require content: () => void; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; 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 7c09951b771c9d6b27fd76b5762aa06dd34596ed..50f72ada9e20aa847b0bdafe9f1df2b082ca16dd 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 @@ -81,7 +81,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -91,7 +91,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -101,7 +101,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -111,7 +111,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -121,7 +121,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -131,7 +131,7 @@ "endColumn": 28, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -141,7 +141,7 @@ "endColumn": 17, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -151,7 +151,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -161,7 +161,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -171,7 +171,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -181,7 +181,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -191,7 +191,7 @@ "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -201,7 +201,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -211,7 +211,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -221,7 +221,7 @@ "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -231,7 +231,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -241,7 +241,7 @@ "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -251,7 +251,7 @@ "endColumn": 37, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"CustomBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 aeedca2d7d6aaf5a377682d2d3c52cded5b91662..67362091ff081e0ccf0e4b362ade85a0cde99560 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,17 +24,29 @@ { "start": 635, "end": 716, - "replacementText": "cardStyle1 = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };" + "replacementText": "cardStyle1: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 }, { "start": 764, "end": 776, - "replacementText": "applyStyles(this.cardStyle1)" + "replacementText": "applyStyles(this.cardStyle1)", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 }, { "start": 788, "end": 800, - "replacementText": "applyStyles(this.cardStyle1)" + "replacementText": "applyStyles(this.cardStyle1)", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 } ], "suggest": "", @@ -51,17 +63,29 @@ { "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 };" + "replacementText": "cardStyle2: CustomStyles = (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)" + "replacementText": "applyStyles(this.cardStyle2)", + "line": 35, + "column": 3, + "endLine": 42, + "endColumn": 4 }, { "start": 1192, "end": 1204, - "replacementText": "applyStyles(this.cardStyle2)" + "replacementText": "applyStyles(this.cardStyle2)", + "line": 35, + "column": 3, + "endLine": 42, + "endColumn": 4 } ], "suggest": "", @@ -78,7 +102,11 @@ { "start": 1326, "end": 1388, - "replacementText": "NormalStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n };" + "replacementText": "NormalStyles: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n };", + "line": 67, + "column": 3, + "endLine": 70, + "endColumn": 4 } ], "suggest": "", @@ -95,7 +123,11 @@ { "start": 1392, "end": 1457, - "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };" + "replacementText": "PressedStyles: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };", + "line": 72, + "column": 3, + "endLine": 75, + "endColumn": 4 } ], "suggest": "", @@ -112,7 +144,11 @@ { "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 };" + "replacementText": "imageStyle: CustomStyles = (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": "", @@ -139,11 +175,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -156,11 +196,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -173,11 +217,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -190,11 +238,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -207,11 +259,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -224,11 +280,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -241,11 +301,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -258,11 +322,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -275,11 +343,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -292,11 +364,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -309,11 +385,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -326,11 +406,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"BuilderParam\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -343,11 +427,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Require\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -360,11 +448,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -377,11 +469,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -394,11 +490,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Button\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -411,11 +511,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -428,11 +532,15 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';" + "replacementText": "\n\nimport {\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n BuilderParam,\n Require,\n Button,\n CustomBuilder,\n} from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"CustomBuilder\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] 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 index 31fb825cee110c0a92e0531cd375c90a965e6ec2..c1a55415d0a5a764bfbc5510037dfa9e7c9a513b 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets @@ -13,11 +13,26 @@ * limitations under the License. */ -import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; +import { + CustomStyles, + applyStyles, +} from '@kit.ArkUI'; + +import { + Component, + CommonMethod, + Column, + Text, + Color, + BuilderParam, + Require, + Button, + CustomBuilder, +} from '@kit.ArkUI'; @Component struct MyCard1 { - cardStyle1 = (instance: CommonMethod): void => { + cardStyle1: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor('#ffffff'); instance.borderRadius(8); }; @@ -33,7 +48,7 @@ struct MyCard1 { @Component struct MyCard2 { - cardStyle2 = (instance: CommonMethod): void => { + cardStyle2: CustomStyles = (instance: CommonMethod): void => { instance.border({ color: this.getColor(), width: this.getWidth() @@ -64,11 +79,11 @@ struct MyButton { @Require content: () => void; - NormalStyles = (instance: CommonMethod): void => { + NormalStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); }; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; @@ -100,7 +115,7 @@ struct imageTest { private previewUri: string | undefined; private DragBuilder: CustomBuilder | undefined; - imageStyle = (instance: CommonMethod): void => { + imageStyle: CustomStyles = (instance: CommonMethod): void => { instance.draggable(this.isShowLongPressMenu() && this.isPC()); instance.onDragStart(() => { console.info(TAG, 'onDragStart'); 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 index 0e17a7dad5ec718d7915c535975cf8c692eecda6..309824bb24ffc2af087747a532a9645fd52770ab 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 105, + "line": 120, "column": 26, - "endLine": 113, + "endLine": 128, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets b/ets2panda/linter/test/main/styles_decorator_struct_2.ets index 31fb825cee110c0a92e0531cd375c90a965e6ec2..18cbf48fc39351347660bc7f25d67587e4c9f848 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets @@ -13,13 +13,15 @@ * limitations under the License. */ +import { CustomStyles, applyStyles } from '@kit.ArkUI'; + import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; @Component struct MyCard1 { - cardStyle1 = (instance: CommonMethod): void => { + cardStyle1: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor('#ffffff'); - instance.borderRadius(8); + instance.borderRadius(8.0); }; build() { @@ -33,7 +35,7 @@ struct MyCard1 { @Component struct MyCard2 { - cardStyle2 = (instance: CommonMethod): void => { + cardStyle2: CustomStyles = (instance: CommonMethod): void => { instance.border({ color: this.getColor(), width: this.getWidth() @@ -46,7 +48,7 @@ struct MyCard2 { } private getWidth(): number { - return 10 + return 10.0 } build() { @@ -64,11 +66,11 @@ struct MyButton { @Require content: () => void; - NormalStyles = (instance: CommonMethod): void => { + NormalStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); }; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; @@ -100,7 +102,7 @@ struct imageTest { private previewUri: string | undefined; private DragBuilder: CustomBuilder | undefined; - imageStyle = (instance: CommonMethod): void => { + imageStyle: CustomStyles = (instance: CommonMethod): void => { instance.draggable(this.isShowLongPressMenu() && this.isPC()); instance.onDragStart(() => { console.info(TAG, 'onDragStart'); 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 0e17a7dad5ec718d7915c535975cf8c692eecda6..4e818a87e4df71b7cb588336adf463716520d14f 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,9 +15,9 @@ ], "result": [ { - "line": 105, + "line": 107, "column": 26, - "endLine": 113, + "endLine": 115, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", 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 0e17a7dad5ec718d7915c535975cf8c692eecda6..4e818a87e4df71b7cb588336adf463716520d14f 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,9 +15,9 @@ ], "result": [ { - "line": 105, + "line": 107, "column": 26, - "endLine": 113, + "endLine": 115, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", 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 0e17a7dad5ec718d7915c535975cf8c692eecda6..4e818a87e4df71b7cb588336adf463716520d14f 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 105, + "line": 107, "column": 26, - "endLine": 113, + "endLine": 115, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", 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 index 31fb825cee110c0a92e0531cd375c90a965e6ec2..18cbf48fc39351347660bc7f25d67587e4c9f848 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets @@ -13,13 +13,15 @@ * limitations under the License. */ +import { CustomStyles, applyStyles } from '@kit.ArkUI'; + import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; @Component struct MyCard1 { - cardStyle1 = (instance: CommonMethod): void => { + cardStyle1: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor('#ffffff'); - instance.borderRadius(8); + instance.borderRadius(8.0); }; build() { @@ -33,7 +35,7 @@ struct MyCard1 { @Component struct MyCard2 { - cardStyle2 = (instance: CommonMethod): void => { + cardStyle2: CustomStyles = (instance: CommonMethod): void => { instance.border({ color: this.getColor(), width: this.getWidth() @@ -46,7 +48,7 @@ struct MyCard2 { } private getWidth(): number { - return 10 + return 10.0 } build() { @@ -64,11 +66,11 @@ struct MyButton { @Require content: () => void; - NormalStyles = (instance: CommonMethod): void => { + NormalStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); }; - PressedStyles = (instance: CommonMethod): void => { + PressedStyles: CustomStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); }; @@ -100,7 +102,7 @@ struct imageTest { private previewUri: string | undefined; private DragBuilder: CustomBuilder | undefined; - imageStyle = (instance: CommonMethod): void => { + imageStyle: CustomStyles = (instance: CommonMethod): void => { instance.draggable(this.isShowLongPressMenu() && this.isPC()); instance.onDragStart(() => { console.info(TAG, 'onDragStart'); 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 index 0e17a7dad5ec718d7915c535975cf8c692eecda6..4e818a87e4df71b7cb588336adf463716520d14f 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 105, + "line": 107, "column": 26, - "endLine": 113, + "endLine": 115, "endColumn": 6, "problem": "LimitedReturnTypeInference", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_3.ets b/ets2panda/linter/test/main/styles_decorator_struct_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..6fbf3a64088c6ad10c47addf56fdf8df79d3c3de --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_3.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. + */ + +@Entry +@Component +struct MyCard { + @Styles + private cardStyle1() { + .backgroundColor('#ffffff') + .borderRadius(8) + } + + @Styles + public cardStyle2() { + .backgroundColor('#ffffff') + .borderRadius(8) + } + + build() { + Column() { + Text('Card').cardStyle1() + } + .cardStyle2() + .backgroundColor(Color.Red) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_3.ets.args.json b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_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/styles_decorator_struct_3.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9dd446edf1c5250165caac5baa50b380bcc4daae --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_3.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": 19, + "column": 3, + "endLine": 23, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 29, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_3.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..492938fec47bcd63f14b1f6af2136e4c40b4721a --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.autofix.json @@ -0,0 +1,183 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 23, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 641, + "end": 730, + "replacementText": "private cardStyle1: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };", + "line": 19, + "column": 3, + "endLine": 23, + "endColumn": 4 + }, + { + "start": 870, + "end": 882, + "replacementText": "applyStyles(this.cardStyle1)", + "line": 19, + "column": 3, + "endLine": 23, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 29, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 734, + "end": 822, + "replacementText": "public cardStyle2: CustomStyles = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };", + "line": 25, + "column": 3, + "endLine": 29, + "endColumn": 4 + }, + { + "start": 894, + "end": 906, + "replacementText": "applyStyles(this.cardStyle2)", + "line": 25, + "column": 3, + "endLine": 29, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n} from '@kit.ArkUI';", + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n} from '@kit.ArkUI';", + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n} from '@kit.ArkUI';", + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n} from '@kit.ArkUI';", + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n Component,\n CommonMethod,\n Column,\n Text,\n Color,\n} from '@kit.ArkUI';", + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_3.ets.json b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_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/styles_decorator_struct_3.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d218743918f8728cb282639102ac3d10de1a3e7 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.migrate.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 { + CustomStyles, + applyStyles, +} from '@kit.ArkUI'; + +import { + Entry, + Component, + CommonMethod, + Column, + Text, + Color, +} from '@kit.ArkUI'; + +@Entry +@Component +struct MyCard { + private cardStyle1: CustomStyles = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8); + }; + + public cardStyle2: CustomStyles = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_3.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_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/main/subclass_super_call.ets b/ets2panda/linter/test/main/subclass_super_call.ets index d275725c9ced20f3df8eb301562897c1f14e3845..20947157c1a6348aa37089a8069ee2c13b87a991 100644 --- a/ets2panda/linter/test/main/subclass_super_call.ets +++ b/ets2panda/linter/test/main/subclass_super_call.ets @@ -36,4 +36,89 @@ class E extends A { // NO ERROR constructor is called } } -class F extends B {} // NO ERROR +class Base { + constructor(a?: string) {} + constructor(a: string, b:string, c?:string) {} +} + +class Foo extends Base { + constructor() { + super() + } +} + +class Bar extends Base { + constructor() { + super("foo") + } +} + +class FooTheSecond extends Base { + constructor() { + super("Foo", "Bar", "Baz") + } +} + +class FaultyBar extends Base { + constructor() { + super(12) // should error + } +} + + +class FaultyFooTheSecond extends Base { + constructor() { + super("foo", "bar", false) // should error + } +} + +class EpicFoo extends Error { + constructor() { + super() + } +} + +class EpicBar extends Error { + constructor() { + super("foo") + } +} + +export enum EEE { + E1, + E2, +} + +export class A { + protected _e:EEE + constructor(e: EEE) { + this._e = e; + } +} + +class B extends A { + constructor() { + super(EEE.E1) + } +} + +class A2 { + constructor() { + console.log("Parent constructor") + } +} + +class C2 extends A2 { + // ok 不用报 +} + +class A3 {} + +class C3 extends A3 { + constructor() { + super() + } +} + +class C4 extends A3 { +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/subclass_super_call.ets.args.json b/ets2panda/linter/test/main/subclass_super_call.ets.args.json index 948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c..bc4d2071daf6e9354e711c3b74b6be2b56659066 100644 --- a/ets2panda/linter/test/main/subclass_super_call.ets.args.json +++ b/ets2panda/linter/test/main/subclass_super_call.ets.args.json @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "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 index 289a83337b8aabfabe08c43a0ade753e39dfbf7b..212ef9dc06d6f9175b74d0cc5e0ab091bcaef83e 100644 --- a/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json +++ b/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json @@ -1,38 +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": 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" - } - ] -} + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 1, + "endLine": 27, + "endColumn": 21, + "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": 1, + "endLine": 31, + "endColumn": 2, + "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": 40, + "column": 5, + "endLine": 40, + "endColumn": 31, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 51, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 66, + "endColumn": 2, + "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": 69, + "column": 1, + "endLine": 73, + "endColumn": 2, + "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" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/swicth_expr.ets b/ets2panda/linter/test/main/swicth_expr.ets index bdef6cc461c22f0c2d47d00bab87ad647f132bf4..f44ab3e8e278572230b170104e0cbdd99d03e9c1 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets +++ b/ets2panda/linter/test/main/swicth_expr.ets @@ -193,7 +193,6 @@ switch (num1) { console.log('Other number'); } -1.0 let num111 = 1.0; switch (num111) { case 1.0: @@ -230,7 +229,7 @@ switch (isnum1) { default: console.log('F'); } -// 整型 5.2fail + type sw1 = number function FunSw4(): sw1 { @@ -245,7 +244,6 @@ switch (FunSw4()) { console.log('F'); } -// 浮点 5.2fail type sw2 = number | string function FunSw5(): sw2 { @@ -299,7 +297,6 @@ switch (FunSw2()) { console.log('F'); } -// 正无穷 let number4 = Infinity; switch (number4) { case Infinity: @@ -309,7 +306,6 @@ switch (number4) { console.log("Default case"); } -// 负无穷 let number5 = -Infinity; switch (number5) { case -Infinity: @@ -319,7 +315,6 @@ switch (number5) { console.log("Default case"); } -// NaN let number6 = NaN; switch (number6) { case NaN: @@ -338,7 +333,6 @@ switch (num111) { console.log('Other number'); } -// let声明整型,case浮点 let number33: number = 1; switch (number33) { case 1.1: @@ -354,7 +348,6 @@ switch (number33) { console.log("Default case"); } -// const声明,整型number,有类型 const num11: number = 2; switch (num11) { case 1: { @@ -367,7 +360,6 @@ switch (num11) { } } -// let声明,整型number,有类型 let num00: number = 2; switch (num00) { case 1: { @@ -378,4 +370,42 @@ switch (num00) { console.log('Two'); break; } -} \ No newline at end of file +} + +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: + } +} + +function foo(index: number) { + switch (index) { + case 0: + break; + } +} + diff --git a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json old mode 100755 new mode 100644 index bd61cc7b008e4b7ac18bb2d6dc0cc53e732449fe..c5a72fe0733c4592f3e91717aec57c4e928607dd --- a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json @@ -1,458 +1,108 @@ { - "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, - "endLine": 17, - "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": 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": 28, - "column": 9, - "endLine": 28, - "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": 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": 36, - "column": 5, - "endLine": 36, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 9, - "endLine": 38, - "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": 56, - "column": 7, - "endLine": 56, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 7, - "endLine": 70, - "endColumn": 20, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 7, - "endLine": 80, - "endColumn": 21, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 9, - "endLine": 81, - "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": 90, - "column": 7, - "endLine": 90, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 9, - "endLine": 91, - "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": 100, - "column": 7, - "endLine": 100, - "endColumn": 33, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 9, - "endLine": 101, - "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": 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": 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": 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": 163, - "column": 5, - "endLine": 163, - "endColumn": 13, - "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": 187, - "column": 5, - "endLine": 187, - "endColumn": 13, - "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": 216, - "column": 13, - "endLine": 216, - "endColumn": 32, - "problem": "CreatingPrimitiveTypes", - "suggest": "", - "rule": "ArkTS creating primitive types is not supported (arkts-primitive-type-normalization)", - "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": 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": 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": 279, - "column": 7, - "endLine": 279, - "endColumn": 27, - "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": 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": 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": 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": 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" - } -] + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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, + "endLine": 17, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", + "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": 28, + "column": 9, + "endLine": 28, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", + "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": 38, + "column": 9, + "endLine": 38, + "endColumn": 19, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 9, + "endLine": 81, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 9, + "endLine": 112, + "endColumn": 12, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type number, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 13, + "endLine": 215, + "endColumn": 32, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 17, + "endLine": 215, + "endColumn": 23, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets index 05ec4e2f14809d6685c63f0ff9c89f60bb817001..8a089d224cfb8b9a91c97b0bb3968b59a2f42082 100644 --- a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets @@ -13,10 +13,54 @@ * limitations under the License. */ 'use static' +import ArrayBuffer,{ taskpool,ArrayList } from '@kit.ArkTS' +import { taskpool as tp } from '@kit.ArkTS' +import * as arkts from '@kit.ArkTS'; +import { task as task7,Task } from './taskpool_deprecated_usages3'; let baseInstance1: BaseClass = new BaseClass(); -let array1 = new Array(); -array1.push(baseInstance1); +let array = new Array(); +array.push(baseInstance1); +let task = new taskpool.Task(testFunc, array, 10); +task.setCloneList(array); //error +task.setTransferList(array); //error + +function testFunc(){} +function test1():void {} + +const array1: number[] =[1] +const transfer: ArrayBuffer[] =[] let task1 = new taskpool.Task(testFunc, array1, 10); -task1.setCloneList(array1); -task1.setTransferList(array1); +task1.setCloneList(array1); //error +task1.setTransferList(transfer); //error + +let task2 = new tp.Task(test1) +task2.setCloneList([]) //error +task2.setCloneList(transfer) //error + +let test3 = new tp.Task(test1) +test3.setCloneList([]) //error +test3.setCloneList([transfer]) //error + +let task4 = new tp.Task(test1) +task4.setTransferList() //error +task4.setTransferList([]) //error +task4.setTransferList(transfer) //error + +let test5 = new tp.Task(test1) +test5.setTransferList() //error +test5.setTransferList([]) //error +test5.setTransferList(transfer) //error + +let task6 = new arkts.taskpool.Task(test1); +task6.setCloneList([]) //error +task6.setCloneList([transfer]) //error + +task7.setCloneList(array1) //error +task7.setTransferList(transfer) //error +new task7.setTransferList(transfer) //error +new task7.setCloneList(array1) //error +new Task(test1).setTransferList(transfer) +new Task(test1).setCloneList(array1) +const task8 = new Task(testFunc); +task8.setCloneList(array1) \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json index f2b6fbc104278c5a2db8b9a60b4bc29891c48fea..4fbd4f4e2c599fdf8d9a9d09ba9c5535b5903e57 100644 --- a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json @@ -1,68 +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": 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": 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" - } - ] -} + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 60, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 30, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 44, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 24, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 37, + "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": 68, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 36, + "endLine": 21, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 22, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 29, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 6, + "endLine": 25, + "endColumn": 18, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 6, + "endLine": 26, + "endColumn": 21, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 30, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 7, + "endLine": 35, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 17, + "endLine": 37, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 17, + "endLine": 41, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 7, + "endLine": 42, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 7, + "endLine": 43, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 17, + "endLine": 45, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 7, + "endLine": 46, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 7, + "endLine": 47, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 7, + "endLine": 48, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 17, + "endLine": 50, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 7, + "endLine": 53, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 17, + "endLine": 55, + "endColumn": 36, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 7, + "endLine": 56, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 7, + "endLine": 57, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 7, + "endLine": 59, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 7, + "endLine": 60, + "endColumn": 22, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 26, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 11, + "endLine": 61, + "endColumn": 26, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 5, + "endLine": 62, + "endColumn": 23, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 11, + "endLine": 62, + "endColumn": 23, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "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 index 1c17b59df7a1612ee61e9a9368eed3b136b9bcfc..619623e56042c24574b9b22c8c7871014101b08e 100644 --- a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json @@ -15,14 +15,114 @@ ], "result": [ { - "line": 20, + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 60, + "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": 44, + "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": 37, + "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": 68, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 24, "column": 5, - "endLine": 20, + "endLine": 24, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, "endColumn": 52, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 43, + "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/taskpool_deprecated_usages2.ets b/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets new file mode 100755 index 0000000000000000000000000000000000000000..f79e1e32cc64a6ffae5b07d437702edd7c6aece3 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages2.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. + */ + +import taskpool from '@ohos.taskpool'; +import { otherTaskPool as taskpool1 } from './@ohos.taskpool'; +import { taskpool as taskpool2 } from './@ohos.taskpool'; +function test1(){} +const array1: number[] =[1] +const transfer: ArrayBuffer[] =[] +let task = new taskpool1.Task(test1); +task.setCloneList(array1) +task.setTransferList(transfer) +new taskpool1.Task(test1).setTransferList(transfer); +function test(){ + const task3 = new taskpool2.Task(test1); + typeof task3.setTransferList(transfer); + return new taskpool2.Task(test1).setTransferList(); +} +let task4 = new taskpool.Task(test1); +task4.setCloneList([]) //error +task4.setCloneList(transfer) //error \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets.args.json b/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages2.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/taskpool_deprecated_usages2.ets.arkts2.json b/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..6ce4bf741deb7f714e67208f588f9b3725d08444 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages2.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": 8, + "endLine": 16, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 31, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 41, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 17, + "endLine": 31, + "endColumn": 30, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 19, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets.json b/ets2panda/linter/test/main/taskpool_deprecated_usages2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..14da023dd0b347f06e79a6a58ed2a965ad18f232 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages2.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": 31, + "column": 5, + "endLine": 31, + "endColumn": 37, + "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/taskpool_deprecated_usages3.ets b/ets2panda/linter/test/main/taskpool_deprecated_usages3.ets new file mode 100755 index 0000000000000000000000000000000000000000..99eafb82960a351e05fd6a90c0cd45a937879983 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages3.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. + */ +import taskpool from '@ohos.taskpool'; +function test1(){} +export const task = new taskpool.Task(test1); +export class Task { + constructor(func: Function, ...args: Object[]){} + setTransferList(transfer?: ArrayBuffer[]): void{} + setCloneList(cloneList: Object[] | ArrayBuffer[]): void{} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages3.ets.args.json b/ets2panda/linter/test/main/taskpool_deprecated_usages3.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages3.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/taskpool_deprecated_usages3.ets.arkts2.json b/ets2panda/linter/test/main/taskpool_deprecated_usages3.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..75c06b28547989681f9a67799700779003f0b2c3 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages3.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": 15, + "column": 8, + "endLine": 15, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 15, + "endLine": 17, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 26, + "endLine": 17, + "endColumn": 39, + "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/taskpool_deprecated_usages3.ets.json b/ets2panda/linter/test/main/taskpool_deprecated_usages3.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..4fdd338ef26a4ff2a3ff6c93f48a14fd8c8c295d --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages3.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": 15, + "endLine": 17, + "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/ts-like-catch-type.ets b/ets2panda/linter/test/main/ts-like-catch-type.ets index 76d4be8122a044cab26465f3b6e83eb567e024a6..1f16edc96f4fbfdb718a594c5328f327d9cfa53c 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets @@ -13,18 +13,203 @@ * limitations under the License. */ -function test() { +import { BusinessError } from '@ohos.base'; +import { AError, AError1, BError, BError1 } from "./ts-like-catch-type111"; + +try { + throw new Error(); +} catch(e) { + e.message; + e.prop; +} + +try { + throw new Error(); +} catch(e) { +} + +try { + let that = 123; +} catch (err: BusinessError) { + console.log(err.toString()); +} + +class RpcException { + msg: string; + code: number; +} + +class RpcException1 { + msg: string; + code: number; +} + +// not extends Error +function a1() { + try { + throw new RpcException('msg', 1); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof RpcException) { // error + errorMsg = e.msg; // not check + errorCode = e.code; // not check + } else if (e instanceof RpcException1) { // error + errorMsg = e.msg; // not check + errorCode = e.code; // not check + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + // e instanceof RpcException / e.prop error + e instanceof RpcException ? e.msg : e.prop; + // e instanceof RpcException / e.prop error + e instanceof RpcException ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); + // e instanceof RpcException / e instanceof RpcException1 / e.prop error + e instanceof RpcException ? console.log('when true: ' + (e instanceof RpcException1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException1 ? e.msg : e.prop)); + // e instanceof RpcException / e instanceof RpcException1 + e instanceof RpcException ? console.log('when true: ' + (e instanceof RpcException1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException1 ? e.msg : e.message)); // error * 2 + console.log(errorMsg); + (e as RpcException).msg; // error + console.log('errorMsg: ' + (e as RpcException).msg); // error + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as RpcException; // error + temp1.msg; // not check + temp1.message; // not check + console.log('errorMsg: ' + temp1.message); // not check + } +} + +// import / not extends Error +function a2() { + try { + throw new BError('msg', 1); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof BError) { // error + errorMsg = e.a; // not check + errorCode = e.code; // not check + } else if (e instanceof BError1) { // error + errorMsg = e.b; // not check + errorCode = e.message; // not check + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + // e instanceof BError / e.prop error + e instanceof BError ? e.msg : e.prop; + // e instanceof BError / e.prop error + e instanceof BError ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); + // e instanceof BError / e instanceof BError1 / e.prop error + e instanceof BError ? console.log('when true: ' + (e instanceof BError1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof BError1 ? e.msg : e.prop)); + // e instanceof BError / e instanceof BError1 + e instanceof BError ? console.log('when true: ' + (e instanceof BError1 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof BError1 ? e.msg : e.message)); + console.log(errorMsg); + (e as BError).msg; // error + console.log('errorMsg: ' + (e as BError).msg); // error + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as BError; // error + temp1.msg; // not check + temp1.message; // not check + console.log('errorMsg: ' + temp1.message); // not check + } +} + +class RpcException2 extends Error { + msg: string; + code: number; + constructor(msg: string, code: number) { + super(msg); + this.msg = msg; + this.code = code; + } +} + +class RpcException3 extends Error { + msg: string; + code: number; + constructor(msg: string, code: number) { + super(msg); + this.msg = msg; + this.code = code; + } +} + +// extends Error +function a3() { try { - let a: number = 1; + throw new RpcException2(); } catch (e) { - console.log('catch') + let errorCode = 1; + let errorMsg = ''; + if (e instanceof RpcException2) { + errorMsg = e.msg; + errorCode = e.code; + console.log('a3: ' + e.prop); // error + } else if (e instanceof RpcException3) { + errorMsg = e.msg; + errorCode = e.code; + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + e instanceof RpcException2 ? e.msg : e.prop; // e.prop error + e instanceof RpcException2 ? console.log('when true: ' + e.msg) : console.log('when false: ' + e.prop); // e.prop error + // e.msg1 / e.prop error + e instanceof RpcException2 ? console.log('when true: ' + (e instanceof RpcException3 ? e.msg1 : e.code)) : console.log('when false: ' + (e instanceof RpcException3 ? e.msg : e.prop)); + e instanceof RpcException2 ? console.log('when true: ' + (e instanceof RpcException3 ? e.msg : e.code)) : console.log('when false: ' + (e instanceof RpcException3 ? e.msg : e.message)); + console.log(errorMsg); + (e as RpcException2).msg; // ok + console.log('errorMsg: ' + (e as RpcException2).msg); // ok + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as RpcException2; + temp1.msg; // ok + temp1.message; // ok + console.log('errorMsg: ' + temp1.message); // ok + console.log('errorMsg: ' + temp1.prop); // error } } -function test2() { +// import / extends Error +function a4() { try { - let a: number = 1; - } catch (e: any) { - console.log('catch') + throw new AError('msg'); + } catch (e) { + let errorCode = 1; + let errorMsg = ''; + if (e instanceof AError) { + errorMsg = e.customProp; + errorCode = e.code; + console.log('a4: ' + e.prop); // error + } else if (e instanceof AError1) { + errorMsg = e.customProp; + errorCode = e.code; + } else { + console.log('else prop: ' + e.prop); // error + console.log('else message: ' + e.message); // ok + } + e instanceof AError ? e.customProp : e.prop; // e.prop error + e instanceof AError ? console.log('when true: ' + e.customProp) : console.log('when false: ' + e.prop); // e.prop error + // e.customProp1 / e.prop error + e instanceof AError ? console.log('when true: ' + (e instanceof AError1 ? e.customProp1 : e.code)) : console.log('when false: ' + (e instanceof AError1 ? e.customProp : e.prop)); + e instanceof AError ? console.log('when true: ' + (e instanceof AError1 ? e.customProp : e.code)) : console.log('when false: ' + (e instanceof AError1 ? e.customProp : e.message)); + console.log(errorMsg); + (e as AError).customProp; // ok + console.log('errorMsg: ' + (e as AError).customProp); // ok + const temp = e; + temp.prop; // error + console.log('errorMsg: ' + temp.prop); // error + const temp1 = e as AError; + temp1.customProp; // ok + temp1.message; // ok + console.log('errorMsg: ' + temp1.message); // ok + console.log('errorMsg: ' + temp1.prop); // error } } \ 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 index c42a19087434140d6ec2b18122a7038c5c5622f5..178915a75cf9f90e3497c933291b0902ef107224 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json @@ -1,58 +1,658 @@ { "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT 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": 19, - "column": 5, - "endLine": 21, - "endColumn": 4, + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 9, "problem": "TsLikeCatchType", "suggest": "", "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", "severity": "ERROR" }, { - "line": 27, - "column": 12, - "endLine": 27, - "endColumn": 18, + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 28, "problem": "CatchWithUnsupportedType", "suggest": "", "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", "severity": "ERROR" }, { - "line": 27, + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 38, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 9, + "endLine": 54, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 16, + "endLine": 57, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 35, + "endLine": 61, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 41, + "endLine": 65, + "endColumn": 47, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 99, + "endLine": 67, + "endColumn": 105, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 141, + "endLine": 69, + "endColumn": 167, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 178, + "endLine": 69, + "endColumn": 184, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 30, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 141, + "endLine": 71, + "endColumn": 167, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 23, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 33, + "endLine": 74, + "endColumn": 50, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 32, + "endLine": 77, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 19, + "endLine": 78, + "endColumn": 36, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 11, + "endLine": 75, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 32, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 9, + "endLine": 92, + "endColumn": 28, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 16, + "endLine": 95, + "endColumn": 36, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 35, + "endLine": 99, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 5, + "endLine": 103, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 35, + "endLine": 103, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 93, + "endLine": 105, + "endColumn": 99, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 129, + "endLine": 107, + "endColumn": 149, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 160, + "endLine": 107, + "endColumn": 166, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 109, "column": 5, - "endLine": 29, - "endColumn": 4, + "endLine": 109, + "endColumn": 24, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 129, + "endLine": 109, + "endColumn": 149, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 6, + "endLine": 111, + "endColumn": 17, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 33, + "endLine": 112, + "endColumn": 44, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 5, + "endLine": 114, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 32, + "endLine": 115, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 19, + "endLine": 116, + "endColumn": 30, "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, + "line": 113, + "column": 11, + "endLine": 113, + "endColumn": 19, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 153, + "column": 28, + "endLine": 153, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 35, + "endLine": 158, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 42, + "endLine": 161, + "endColumn": 48, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 100, + "endLine": 162, + "endColumn": 106, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 92, + "endLine": 164, + "endColumn": 98, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 180, + "endLine": 164, + "endColumn": 186, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 32, + "endLine": 171, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 32, + "endLine": 176, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 11, + "endLine": 169, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 28, + "endLine": 190, + "endColumn": 34, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 195, + "column": 35, + "endLine": 195, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 42, + "endLine": 198, + "endColumn": 48, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 100, + "endLine": 199, + "endColumn": 106, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 79, + "endLine": 201, + "endColumn": 92, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 175, + "endLine": 201, + "endColumn": 181, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 5, + "endLine": 207, + "endColumn": 14, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 32, + "endLine": 208, + "endColumn": 41, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 32, + "endLine": 213, + "endColumn": 42, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 11, + "endLine": 206, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' 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/ts-like-catch-type.ets.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.json index bd65f7efbe5b1a14b6001506f9a8511cd080d1d1..e5a6b2de816142f498549720a3e6eab81ef06e9d 100644 --- a/ets2panda/linter/test/main/ts-like-catch-type.ets.json +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.json @@ -15,24 +15,114 @@ ], "result": [ { - "line": 27, - "column": 12, - "endLine": 27, - "endColumn": 18, + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 28, "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, + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 38, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 11, + "endLine": 75, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 5, + "endLine": 88, + "endColumn": 32, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 11, + "endLine": 113, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 11, + "endLine": 169, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 11, + "endLine": 206, + "endColumn": 19, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'msg' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'code' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'code' 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/ts-like-catch-type111.ts b/ets2panda/linter/test/main/ts-like-catch-type111.ts new file mode 100644 index 0000000000000000000000000000000000000000..4c483947ad0a3ea53d285f1c5f3af29f5a14bbd8 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts @@ -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. +*/ + +export class AError extends Error { + customProp: string; + constructor(message: string) { + super(message); + this.customProp = "custom"; + } +} + +export class AError1 extends Error { + customProp: string; + constructor(message: string) { + super(message); + this.customProp = "custom"; + } +} + +export class BError { + msg: string; + code: number; + constructor(msg: string, code: number) { + this.msg = msg; + this.code = code; + } +} + +export class BError1 { + msg: string; + code: number; + constructor(msg: string, code: number) { + this.msg = msg; + this.code = code; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json b/ets2panda/linter/test/main/ts-like-catch-type111.ts.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b87ffd2bb39b887f217040e1b8dfdd4aeebffb03 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts.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." + ], + "commonArgs": "--no-check-ts-as-source" +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type111.ts.json b/ets2panda/linter/test/main/ts-like-catch-type111.ts.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type111.ts.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/ts_overload.ets b/ets2panda/linter/test/main/ts_overload.ets index 40fc4f8024538c335a635959fa461f831bb70fd9..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,11 @@ 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 /* ... */ } } @@ -59,4 +59,30 @@ function func(){ console.log("ArkTs foo4") } -func.val = "0xff"; \ No newline at end of file +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 4c34eae345631c8588549ba5674e988f168d2c39..8e4ea2ce665c2dcc9b00e0367e3a250bad809874 100644 --- a/ets2panda/linter/test/main/ts_overload.ets.arkts2.json +++ b/ets2panda/linter/test/main/ts_overload.ets.arkts2.json @@ -44,6 +44,16 @@ "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, + { + "line": 20, + "column": 16, + "endLine": 20, + "endColumn": 20, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, { "line": 30, "column": 3, @@ -173,6 +183,56 @@ "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": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/types.ets.autofix.json b/ets2panda/linter/test/main/types.ets.autofix.json index 7eb21c4bca928fa17ded06c1872067415840c9b7..1d918e5be97473e497664891fd7c40a200913719 100644 --- a/ets2panda/linter/test/main/types.ets.autofix.json +++ b/ets2panda/linter/test/main/types.ets.autofix.json @@ -54,12 +54,20 @@ { "start": 610, "end": 610, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: string;\n idx: number;\n handler: string;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: string;\n idx: number;\n handler: string;\n}\n", + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 19 }, { "start": 829, "end": 829, - "replacementText": ": GeneratedObjectLiteralInterface_1" + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 19 } ], "suggest": "", @@ -76,7 +84,11 @@ { "start": 969, "end": 1007, - "replacementText": "interface Point {\n x: number;\n y: number;\n}" + "replacementText": "interface Point {\n x: number;\n y: number;\n}", + "line": 32, + "column": 16, + "endLine": 32, + "endColumn": 17 } ], "suggest": "", @@ -123,7 +135,11 @@ { "start": 1235, "end": 1313, - "replacementText": "let isNumber: (x: any) => x is number = (x: any): x is number => {\n return typeof x === 'number';\n};" + "replacementText": "let isNumber: (x: any) => x is number = (x: any): x is number => {\n return typeof x === 'number';\n};", + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 11 } ], "suggest": "", @@ -160,7 +176,11 @@ { "start": 1405, "end": 1570, - "replacementText": "interface ComputedPropertyT {\n a: string; // String-like name\n 5: string; // Number-like name\n [c]: string; // String-like name\n [d]: string; // Number-like name\n}" + "replacementText": "interface ComputedPropertyT {\n a: string; // String-like name\n 5: string; // Number-like name\n [c]: string; // String-like name\n [d]: string; // Number-like name\n}", + "line": 54, + "column": 26, + "endLine": 54, + "endColumn": 27 } ], "suggest": "", @@ -207,12 +227,20 @@ { "replacementText": "__2", "start": 1604, - "end": 1605 + "end": 1605, + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 4 }, { "replacementText": "__2", "start": 1684, - "end": 1685 + "end": 1685, + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 4 } ], "suggest": "", @@ -229,12 +257,50 @@ { "replacementText": "__2", "start": 1604, - "end": 1605 + "end": 1605, + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 4 }, { "replacementText": "__2", "start": 1684, - "end": 1685 + "end": 1685, + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 3, + "endLine": 68, + "endColumn": 8, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "Two", + "start": 1617, + "end": 1622, + "line": 68, + "column": 3, + "endLine": 68, + "endColumn": 8 + }, + { + "replacementText": "Two", + "start": 1696, + "end": 1701, + "line": 68, + "column": 3, + "endLine": 68, + "endColumn": 8 } ], "suggest": "", @@ -251,7 +317,11 @@ { "start": 1710, "end": 1758, - "replacementText": "interface Dictionary {\n [key: string]: unknown;\n}" + "replacementText": "interface Dictionary {\n [key: string]: unknown;\n}", + "line": 71, + "column": 19, + "endLine": 71, + "endColumn": 20 } ], "suggest": "", @@ -328,7 +398,11 @@ { "start": 1999, "end": 2083, - "replacementText": "interface DescribableFunction {\n description: string;\n (someArg: number): boolean;\n}" + "replacementText": "interface DescribableFunction {\n description: string;\n (someArg: number): boolean;\n}", + "line": 94, + "column": 28, + "endLine": 94, + "endColumn": 29 } ], "suggest": "", @@ -355,12 +429,20 @@ { "start": 2405, "end": 2405, - "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n x: 2;\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n x: 2;\n}\n", + "line": 111, + "column": 19, + "endLine": 111, + "endColumn": 20 }, { "start": 2423, "end": 2431, - "replacementText": "GeneratedTypeLiteralInterface_1" + "replacementText": "GeneratedTypeLiteralInterface_1", + "line": 111, + "column": 19, + "endLine": 111, + "endColumn": 20 } ], "suggest": "", @@ -377,12 +459,20 @@ { "start": 2436, "end": 2436, - "replacementText": "interface GeneratedTypeLiteralInterface_2 {\n y: string;\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_2 {\n y: string;\n}\n", + "line": 112, + "column": 12, + "endLine": 112, + "endColumn": 13 }, { "start": 2447, "end": 2460, - "replacementText": "GeneratedTypeLiteralInterface_2" + "replacementText": "GeneratedTypeLiteralInterface_2", + "line": 112, + "column": 12, + "endLine": 112, + "endColumn": 13 } ], "suggest": "", @@ -399,12 +489,20 @@ { "start": 2436, "end": 2436, - "replacementText": "interface GeneratedTypeLiteralInterface_3 {\n y: 'constant';\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_3 {\n y: 'constant';\n}\n", + "line": 112, + "column": 35, + "endLine": 112, + "endColumn": 36 }, { "start": 2470, "end": 2487, - "replacementText": "GeneratedTypeLiteralInterface_3" + "replacementText": "GeneratedTypeLiteralInterface_3", + "line": 112, + "column": 35, + "endLine": 112, + "endColumn": 36 } ], "suggest": "", @@ -421,12 +519,20 @@ { "start": 2543, "end": 2543, - "replacementText": "interface GeneratedTypeLiteralInterface_4 {\n z: boolean;\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_4 {\n z: boolean;\n}\n", + "line": 116, + "column": 9, + "endLine": 116, + "endColumn": 10 }, { "start": 2551, "end": 2565, - "replacementText": "GeneratedTypeLiteralInterface_4" + "replacementText": "GeneratedTypeLiteralInterface_4", + "line": 116, + "column": 9, + "endLine": 116, + "endColumn": 10 } ], "suggest": "", @@ -463,7 +569,11 @@ { "start": 2630, "end": 2636, - "replacementText": "1 as any" + "replacementText": "1 as any", + "line": 119, + "column": 15, + "endLine": 119, + "endColumn": 21 } ], "suggest": "", @@ -490,7 +600,11 @@ { "start": 2657, "end": 2714, - "replacementText": "document.getElementById('main_canvas') as HTMLCanvasElement" + "replacementText": "document.getElementById('main_canvas') as HTMLCanvasElement", + "line": 120, + "column": 20, + "endLine": 120, + "endColumn": 77 } ], "suggest": "", @@ -507,12 +621,20 @@ { "start": 2719, "end": 2719, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n a: number;\n b: string;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n a: number;\n b: string;\n}\n", + "line": 124, + "column": 13, + "endLine": 124, + "endColumn": 14 }, { "start": 2765, "end": 2765, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_2", + "line": 124, + "column": 13, + "endLine": 124, + "endColumn": 14 } ], "suggest": "", @@ -559,7 +681,11 @@ { "start": 3075, "end": 3192, - "replacementText": "let arrayFunc: (array: Array) => Array = (array: Array): Array => {\n return array.map((x) => x.toString());\n};" + "replacementText": "let arrayFunc: (array: Array) => Array = (array: Array): Array => {\n return array.map((x) => x.toString());\n};", + "line": 138, + "column": 3, + "endLine": 138, + "endColumn": 11 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/types.ets.json b/ets2panda/linter/test/main/types.ets.json index 9daadb68bf9f73245defa3b2bfc56b71a80ea5b2..547ad8d2c7487e8e98d95c05af89cf6ac70f2887 100644 --- a/ets2panda/linter/test/main/types.ets.json +++ b/ets2panda/linter/test/main/types.ets.json @@ -184,6 +184,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 68, + "column": 3, + "endLine": 68, + "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": 71, "column": 19, diff --git a/ets2panda/linter/test/main/types.ets.migrate.ets b/ets2panda/linter/test/main/types.ets.migrate.ets index 07bcd2036971da481f8dc8867af57126a0f474f2..6782d2536759d7c34115df24776360d7909f744d 100644 --- a/ets2panda/linter/test/main/types.ets.migrate.ets +++ b/ets2panda/linter/test/main/types.ets.migrate.ets @@ -68,12 +68,12 @@ interface ComputedPropertyT { class LiteralAsPropertyName { __2: string; - 'Two': number; + Two: number; } const litAsPropName: LiteralAsPropertyName = { __2: 'two', - 'Two': 2, + Two: 2, }; interface Dictionary { diff --git a/ets2panda/linter/test/main/types.ets.migrate.json b/ets2panda/linter/test/main/types.ets.migrate.json index 9235d4235cf4c7aca6585e704998c63f0030b9a0..7df919f6535a74d70f5147168ee13a044a7d4ac9 100644 --- a/ets2panda/linter/test/main/types.ets.migrate.json +++ b/ets2panda/linter/test/main/types.ets.migrate.json @@ -274,6 +274,16 @@ "rule": "Property '__2' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, + { + "line": 71, + "column": 3, + "endLine": 71, + "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": 114, "column": 3, diff --git a/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts b/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..638b3a1404338d3dc8cd16d181fe002e024cbbce --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.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. + */ + +import { BuilderNode } from './@ohos.arkui.node'; +import { PersistenceV2 } from './@ohos.arkui.StateManagement'; +export { BuilderNode, PersistenceV2 }; \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.ts b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ba4dbfcb73b09a4e861b21440ed15c3af639ff7 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.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. + */ + +export declare class PersistenceV2 extends AppStorageV2{ + static globalConnect(): void; +} + +declare class AppStorageV2 { + static connect(): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/@ohos.arkui.node.d.ts b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.node.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..bbf489a77f1f965c1b646aa2e464ea4a2ce2b206 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.node.d.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 { BuilderNode } from './BuilderNode'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/BuilderNode.d.ts b/ets2panda/linter/test/main/ui_modules/BuilderNode.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae79a092ff2c1ab1330a7637f53ae2f24c20ea26 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/BuilderNode.d.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 class BuilderNode { + build(): void; + update(): void; + reuse(): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/common.d.ts b/ets2panda/linter/test/main/ui_modules/common.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0826d63c20edceb60d75502249644a9f16d49e0 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/common.d.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. + */ + +declare function getContext(component?: Object): Context; \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.d.ts b/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..2634f5bd9faa4449476f8844e42819c4eaaf1876 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.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 PersistentStorage { + static persistProp(): void; + static PersistProps(): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/undefined_check_calls.ets.json b/ets2panda/linter/test/main/undefined_check_calls.ets.json index 5f20af3a4401e4c627ee4aea349b20b309373644..027d7c1cd2cfeca119b905517134d6740d4f1781 100644 --- a/ets2panda/linter/test/main/undefined_check_calls.ets.json +++ b/ets2panda/linter/test/main/undefined_check_calls.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", @@ -30,8 +30,8 @@ "endLine": 51, "endColumn": 60, "problem": "StrictDiagnostic", - "suggest": "Argument of type 'string | undefined' is not assignable to parameter of type 'ResourceStr'.", - "rule": "Argument of type 'string | undefined' is not assignable to parameter of type 'ResourceStr'.", + "suggest": "Argument of type 'string | undefined' is not assignable to parameter of type 'ResourceStr'.\n Type 'undefined' is not assignable to type 'ResourceStr'.", + "rule": "Argument of type 'string | undefined' is not assignable to parameter of type 'ResourceStr'.\n Type 'undefined' is not assignable to type 'ResourceStr'.", "severity": "ERROR" }, { @@ -100,8 +100,8 @@ "endLine": 92, "endColumn": 15, "problem": "StrictDiagnostic", - "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.", - "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.", + "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", + "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", "severity": "WARNING" }, { @@ -120,8 +120,8 @@ "endLine": 99, "endColumn": 15, "problem": "StrictDiagnostic", - "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.", - "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.", + "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", + "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", "severity": "ERROR" }, { @@ -130,8 +130,8 @@ "endLine": 105, "endColumn": 15, "problem": "StrictDiagnostic", - "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.", - "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.", + "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", + "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", "severity": "ERROR" }, { @@ -140,8 +140,8 @@ "endLine": 106, "endColumn": 15, "problem": "StrictDiagnostic", - "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.", - "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.", + "suggest": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", + "rule": "Type 'TestClassC' is not assignable to type 'TestClassD'.\n Types of property 'ccc' are incompatible.\n Type 'null' is not assignable to type 'string'.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/unfixed_tuple_negative.ets b/ets2panda/linter/test/main/unfixed_tuple_negative.ets new file mode 100644 index 0000000000000000000000000000000000000000..05723324d0197b9c094334504294a368ef3f08a8 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_negative.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. + */ + +const s: [string, ...boolean[]] = ['',true] // report error for unfixed tuple + +type Tuple1 = [string, ...boolean[]]; // report error for unfixed tuple + +type Tuple2 = [number, string, ...number[]]; // report error for unfixed tuple + +type Tuple3 = [...string[]]; // report error for unfixed tuple + +type Tuple4 = [...boolean[], number]; // report error for unfixed tuple + +type NestedTuple = [string, ...[number, boolean][]]; // report error for unfixed tuple + +function logTuple(args: [string, ...number[]]) { // report error for unfixed tuple + +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/unfixed_tuple_negative.ets.args.json b/ets2panda/linter/test/main/unfixed_tuple_negative.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_negative.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/unfixed_tuple_negative.ets.arkts2.json b/ets2panda/linter/test/main/unfixed_tuple_negative.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..cf32008b804f2c10b091d56d81a4e56816b5966e --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_negative.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": 19, + "endLine": 16, + "endColumn": 31, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 24, + "endLine": 18, + "endColumn": 36, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 32, + "endLine": 20, + "endColumn": 43, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 27, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 28, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 29, + "endLine": 26, + "endColumn": 51, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 34, + "endLine": 28, + "endColumn": 45, + "problem": "unfixedTuple", + "suggest": "", + "rule": "No unfixed length tuple support (arkts-no-unfixed-len-tuple)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/unfixed_tuple_negative.ets.json b/ets2panda/linter/test/main/unfixed_tuple_negative.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_negative.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/unfixed_tuple_positive.ets b/ets2panda/linter/test/main/unfixed_tuple_positive.ets new file mode 100644 index 0000000000000000000000000000000000000000..e45b73893e04dc924b46c640d07b1ea95be48ee2 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_positive.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. + */ + +const s: [string, boolean[]] = ['',[true]] // ok + +const s1: [string, boolean] = ['',true] // ok + +type Tuple1 = [string, boolean[]]; // ok + +type Tuple2 = [number, string, number[]]; // ok + +type Tuple3 = [string[]]; // ok + +type Tuple4 = [boolean[], number]; // ok + +type NestedTuple = [string, [number, boolean][]]; // ok + +function logTuple(args: [string, number[]]) { // ok + +} + +function sum(...numbers: number[]): number { // ok + return numbers.reduce((total, num) => total + num, 0); +} diff --git a/ets2panda/linter/test/main/unfixed_tuple_positive.ets.args.json b/ets2panda/linter/test/main/unfixed_tuple_positive.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_positive.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/unfixed_tuple_positive.ets.arkts2.json b/ets2panda/linter/test/main/unfixed_tuple_positive.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_positive.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/unfixed_tuple_positive.ets.json b/ets2panda/linter/test/main/unfixed_tuple_positive.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/unfixed_tuple_positive.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/union_assignment_with_obj_literal_ambiguity.ets b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f7975af877e72973302c6af94b3fdb6b8d46d4d --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.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. + */ + +// --------------------- +// Shared types +// --------------------- +interface IA { + value: number; + name?: string; +} + +interface IB { + value: number; +} + +class CA { + value: number = 1; +} + +class CB { + value: number = 1; +} + +// --------------------- +// Allowed Cases +// --------------------- + +// ----------- Allowed: simple type, no union ------------- +let ok1: IA = { value: 1 }; // OK — no union + +// ----------- Allowed: nullish unions -------------------- +let ok2: IA | null = { value: 1 }; // OK — null union +let ok3: IA | undefined = { value: 1 }; // OK — undefined union +let ok4: IA | null | undefined = { value: 1 }; // OK — null + undefined union + +// ----------- Allowed: casted unions ------------------------ +let ok5: IA | IB = { value: 1 } as IA; // OK — explicit cast + +// ----------- Built-in lib.* guard: should be allowed -------------------- +let ok6: Record | object[] = {}; // OK — both are lib.* types +let ok7: Promise | string[] = {}; // OK — Promise and Array are from lib.* + +// ----------- Other allowed scenarios --------------------- + +// Using 'as' cast +function ok8(): IA | CB { + return { value: 1 } as IA; // ok +} + +// Passing nullish or undefined unions — allowed +function ok9(a: IA | null | undefined) {} +ok9({ value: 42 }); // ok + +// Passing a variable declared as IA +const objIA: IA = { value: 1 }; +function ok10(a: IA | IB) { + console.log(a.value); +} +ok10(objIA); // ok + +// --------------------- +// Disallowed Cases +// --------------------- + +// ----------- Disallowed: simple union of interface + interface ------------ +let fail1: IA | IB = { value: 1 }; // ❌ Error — object literal into interface union + +// ----------- Disallowed: interface + class ----------------- +let fail2: IA | CA = { value: 1 }; // ❌ Error + +// ----------- Disallowed: simple union of class + class ------------------ +let fail3: CA | CB = { value: 1 }; // ❌ Error + +// ----------- Disallowed: with nullish in mixed but still failing -------------------- +let fail4: IA | IB | undefined = { value: 1 }; // ❌ Error — nullish doesn’t save it here + +// ----------- Disallowed: function return types --------------------- + +// Return object literal to interface|interface without cast +function err1(): IA | IB { + return { value: 1 }; // ❌ error +} + +// Return object literal to class|interface without cast +function err2(): CB | IA { + return { value: 1 }; // ❌ error +} + +// ----------- Disallowed: function param passing --------------------- + +// Pass object literal to interface|interface param without cast +function err3(a: IA | IB) { + console.log(a.value); +} +err3({ value: 42 }); // ❌ error + +// Pass object literal to class|class param without cast +function err4(a: CA | CB) { + console.log(a.value); +} +err4({ value: 10 }); // ❌ error + +// Mixed interface|class param without cast +function err5(a: IA | CB) { + console.log(a.value); +} +err5({ value: 5 }); // ❌ error + +// Nested in union with undefined — still error +function err6(a: IA | CB | undefined) {} +err6({ value: 99 }); // ❌ error diff --git a/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.args.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.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/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a5200e79a8f6cc8dd2e9208fa0b321c678b811c6 --- /dev/null +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.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": 53, + "column": 18, + "endLine": 53, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 36, + "endLine": 53, + "endColumn": 37, + "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": 22, + "endLine": 78, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 22, + "endLine": 81, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 22, + "endLine": 84, + "endColumn": 34, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 34, + "endLine": 87, + "endColumn": 46, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 10, + "endLine": 93, + "endColumn": 22, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 10, + "endLine": 98, + "endColumn": 22, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 6, + "endLine": 107, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 6, + "endLine": 113, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 6, + "endLine": 119, + "endColumn": 18, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 6, + "endLine": 123, + "endColumn": 19, + "problem": "ObjectLiteralUnionNeedsCast", + "suggest": "", + "rule": "Object literal used with a union type. The intended union member (e.g. { … } as A) must be explicitly asserted (arkts-union-assignment-with-obj-literal-ambiguity)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json similarity index 51% rename from ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json rename to ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json index 1291e15d5ef455b1073fb6db7bb313b74c2f232e..63a94f9a39b7a47afba1936a8dc4e7986ef99b6b 100644 --- a/ets2panda/linter/test/interop/interop_export_js_rules.ets.migrate.json +++ b/ets2panda/linter/test/main/union_assignment_with_obj_literal_ambiguity.ets.json @@ -15,43 +15,23 @@ ], "result": [ { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 73, + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 21, "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": 23, - "column": 1, - "endLine": 23, - "endColumn": 51, - "problem": "InteropJsObjectExport", - "suggest": "", - "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 1, - "endLine": 25, - "endColumn": 57, - "problem": "InteropArkTs1ObjectExport", + "line": 53, + "column": 36, + "endLine": 53, + "endColumn": 37, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "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/void_operator.ets.arkts2.json b/ets2panda/linter/test/main/void_operator.ets.arkts2.json index 2e051aeddd39bb38b25a34d153be24cfa8812d48..a91c4e740e8ae0a4e9d94ba34b93e8aad1d29cec 100644 --- a/ets2panda/linter/test/main/void_operator.ets.arkts2.json +++ b/ets2panda/linter/test/main/void_operator.ets.arkts2.json @@ -244,16 +244,6 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, - { - "line": 55, - "column": 7, - "endLine": 55, - "endColumn": 12, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 56, "column": 3, @@ -264,16 +254,6 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, - { - "line": 58, - "column": 7, - "endLine": 58, - "endColumn": 20, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 59, "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..28a0220f1f477138e7cb6ffc2215b38f56cf3744 100644 --- a/ets2panda/linter/test/main/void_operator.ets.autofix.json +++ b/ets2panda/linter/test/main/void_operator.ets.autofix.json @@ -24,7 +24,11 @@ { "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": "", @@ -41,7 +45,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,7 +66,11 @@ { "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": "", @@ -75,7 +87,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,12 +108,20 @@ { "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": "", @@ -114,7 +138,11 @@ { "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": "", @@ -131,7 +159,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,7 +180,11 @@ { "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": "", @@ -165,7 +201,11 @@ { "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": "", @@ -182,7 +222,11 @@ { "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": "", @@ -199,7 +243,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,7 +264,11 @@ { "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": "", @@ -233,7 +285,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 +306,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 +327,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 +348,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 +369,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 +390,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 +411,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 +442,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,30 +473,17 @@ { "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": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, - { - "line": 55, - "column": 7, - "endLine": 55, - "endColumn": 12, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1090, - "end": 1095, - "replacementText": "a: number = 1" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 56, "column": 3, @@ -423,30 +494,17 @@ { "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": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, - { - "line": 58, - "column": 7, - "endLine": 58, - "endColumn": 20, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1116, - "end": 1129, - "replacementText": "b: number[] = [1, 2, 3]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, { "line": 59, "column": 3, @@ -457,7 +515,11 @@ { "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": "", @@ -474,7 +536,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 +557,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 +578,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 +599,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 +620,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 +651,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 index 2a81c570d54801e19685e158703a94fcd6dea8d5..8d16ab4da2e4a48df92121b0452c79324c42432d 100644 --- a/ets2panda/linter/test/main/void_operator.ets.migrate.ets +++ b/ets2panda/linter/test/main/void_operator.ets.migrate.ets @@ -109,13 +109,13 @@ const undefined_value3: number | undefined = (() => { })(); function foo() { - let a: number = 1; + let a = 1; (() => { a++; return undefined; })(); - let b: number[] = [1, 2, 3]; + let b = [1, 2, 3]; (() => { console.log(b.filter(x => x % 2 !== 0)); return undefined; diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_1.ets b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..c2d7d44538b3d84143b3ed15dbbf65e447675560 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_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. + */ + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +const wrappedBuilder1: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder); +const wrappedBuilder2: WrappedBuilder<[string, number]> = wrapBuilder<[string, number]>(MyBuilder); +const wrappedBuilder3: WrappedBuilder<[string, number]> = new WrappedBuilder(MyBuilder); +const wrappedBuilder4: WrappedBuilder<[string, number]> = new WrappedBuilder<[string, number]>(MyBuilder); + +@Entry +@Component +struct TestWrappedBuilder1 { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + wrappedBuilder1.builder(this.message, 50) + wrappedBuilder2.builder(this.message, 50) + wrappedBuilder3.builder(this.message, 50) + wrappedBuilder4.builder(this.message, 50) + } + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.args.json b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_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/wrapped_builder_generic_1.ets.arkts2.json b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..e81fd481df1ebbe9516dca588163b99e4ef890f1 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.arkts2.json @@ -0,0 +1,258 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 24, + "endLine": 22, + "endColumn": 56, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 24, + "endLine": 23, + "endColumn": 56, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 59, + "endLine": 23, + "endColumn": 99, + "problem": "WrapBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"wrapBuilder\", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 24, + "endLine": 24, + "endColumn": 56, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 59, + "endLine": 24, + "endColumn": 88, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 63, + "endLine": 24, + "endColumn": 77, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 24, + "endLine": 25, + "endColumn": 56, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 59, + "endLine": 25, + "endColumn": 106, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 63, + "endLine": 25, + "endColumn": 77, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 24, + "endLine": 22, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 59, + "endLine": 22, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 24, + "endLine": 23, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 59, + "endLine": 23, + "endColumn": 70, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 24, + "endLine": 24, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 63, + "endLine": 24, + "endColumn": 77, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 24, + "endLine": 25, + "endColumn": 38, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 63, + "endLine": 25, + "endColumn": 77, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 2, + "endLine": 27, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 2, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.json b/ets2panda/linter/test/main/wrapped_builder_generic_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_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/wrapped_builder_generic_2.ets b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a55bd24a7f326595c0ffef8f3e4520df68bd78a --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +@Builder +function YourBuilder(value: string, size: number) { + Text(value) + .fontSize(size) + .fontColor(Color.Pink) +} + +const builderArr1: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder), wrapBuilder(YourBuilder)]; +const builderArr2: WrappedBuilder<[string, number]>[] = [wrapBuilder<[string, number]>(MyBuilder), wrapBuilder<[string, number]>(YourBuilder)]; +const builderArr3: WrappedBuilder<[string, number]>[] = [new WrappedBuilder(MyBuilder), new WrappedBuilder(YourBuilder)]; +const builderArr4: WrappedBuilder<[string, number]>[] = [new WrappedBuilder<[string, number]>(MyBuilder), new WrappedBuilder<[string, number]>(YourBuilder)]; + +@Entry +@Component +struct Index { + @Builder + testBuilder() { + ForEach(builderArr1, (item: WrappedBuilder<[string, number]>) => { + item.builder('Hello World', 30) + }) + ForEach(builderArr2, (item: WrappedBuilder<[string, number]>) => { + item.builder('Hello World', 30) + }) + ForEach(builderArr3, (item: WrappedBuilder<[string, number]>) => { + item.builder('Hello World', 30) + }) + ForEach(builderArr4, (item: WrappedBuilder<[string, number]>) => { + item.builder('Hello World', 30) + }) + } + + build() { + Row() { + Column() { + this.testBuilder() + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.args.json b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_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/wrapped_builder_generic_2.ets.arkts2.json b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a9ac9aae354b756a0dca883cb4ec04bdb28fcf39 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.arkts2.json @@ -0,0 +1,498 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 20, + "endLine": 29, + "endColumn": 52, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 52, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 58, + "endLine": 30, + "endColumn": 98, + "problem": "WrapBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"wrapBuilder\", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 100, + "endLine": 30, + "endColumn": 142, + "problem": "WrapBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"wrapBuilder\", generics must be declared as arrow function (arkui-wrapbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 52, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 58, + "endLine": 31, + "endColumn": 87, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 62, + "endLine": 31, + "endColumn": 76, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 89, + "endLine": 31, + "endColumn": 120, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 93, + "endLine": 31, + "endColumn": 107, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 52, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 58, + "endLine": 32, + "endColumn": 105, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 62, + "endLine": 32, + "endColumn": 76, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 107, + "endLine": 32, + "endColumn": 156, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 111, + "endLine": 32, + "endColumn": 125, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 33, + "endLine": 39, + "endColumn": 65, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 33, + "endLine": 42, + "endColumn": 65, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 33, + "endLine": 45, + "endColumn": 65, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 33, + "endLine": 48, + "endColumn": 65, + "problem": "WrappedBuilderGenericNeedArrowFunc", + "suggest": "", + "rule": "When using \"WrappedBuilder\", generics are required and must be declared as arrow function (arkui-wrappedbuilder-require-arrow-func-generic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 58, + "endLine": 29, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 82, + "endLine": 29, + "endColumn": 93, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 58, + "endLine": 30, + "endColumn": 69, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 100, + "endLine": 30, + "endColumn": 111, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"wrapBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 62, + "endLine": 31, + "endColumn": 76, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 93, + "endLine": 31, + "endColumn": 107, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 34, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 62, + "endLine": 32, + "endColumn": 76, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 111, + "endLine": 32, + "endColumn": 125, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 2, + "endLine": 34, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 2, + "endLine": 35, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 4, + "endLine": 37, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Builder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 33, + "endLine": 39, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 33, + "endLine": 42, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 33, + "endLine": 45, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 33, + "endLine": 48, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"WrappedBuilder\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Row\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 7, + "endLine": 55, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.json b/ets2panda/linter/test/main/wrapped_builder_generic_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/wrapped_builder_generic_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/migration/mixed_problems.ets.autofix.json b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json index 57f25df2f307782186bdc847598ce6a21d60dae0..011a49fa390f3c33f1131c0db195b312d0ca7449 100644 --- a/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json +++ b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json @@ -24,12 +24,20 @@ { "replacementText": "GeneratedDestructObj_1", "start": 663, - "end": 671 + "end": 671, + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 30 }, { "replacementText": "\nlet a = GeneratedDestructObj_1.a;\nlet b = GeneratedDestructObj_1.b;\n", "start": 689, - "end": 689 + "end": 689, + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 30 } ], "suggest": "", @@ -56,12 +64,20 @@ { "replacementText": "GeneratedDestructObj_2", "start": 764, - "end": 774 + "end": 774, + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2 }, { "replacementText": "\nlet a2 = GeneratedDestructObj_2.a2;\nlet b2 = GeneratedDestructObj_2.b2;\n", "start": 869, - "end": 869 + "end": 869, + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2 } ], "suggest": "", @@ -98,12 +114,20 @@ { "start": 760, "end": 760, - "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n c2: number;\n d2: string;\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n c2: number;\n d2: string;\n}\n", + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11 }, { "start": 840, "end": 866, - "replacementText": "GeneratedTypeLiteralInterface_1" + "replacementText": "GeneratedTypeLiteralInterface_1", + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11 } ], "suggest": "", @@ -130,12 +154,20 @@ { "start": 913, "end": 913, - "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": 29, + "column": 20, + "endLine": 29, + "endColumn": 21 }, { "start": 932, "end": 946, - "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)" + "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)", + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 21 } ], "suggest": "", @@ -152,7 +184,11 @@ { "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}" + "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}", + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 4 } ], "suggest": "", @@ -169,7 +205,11 @@ { "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}" + "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}", + "line": 32, + "column": 11, + "endLine": 46, + "endColumn": 2 } ], "suggest": "", @@ -186,7 +226,11 @@ { "start": 1071, "end": 1117, - "replacementText": "let o = {\n 'a': 1,\n 'b': 2\n}" + "replacementText": "let o = {\n 'a': 1,\n 'b': 2\n}", + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8 } ], "suggest": "", @@ -203,6 +247,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 34, + "column": 9, + "endLine": 34, + "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": 35, + "column": 9, + "endLine": 35, + "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": 38, "column": 5, @@ -213,7 +277,11 @@ { "start": 1124, "end": 1235, - "replacementText": "let o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n}" + "replacementText": "let o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n}", + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 8 } ], "suggest": "", @@ -230,6 +298,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 39, + "column": 9, + "endLine": 39, + "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": 40, + "column": 9, + "endLine": 40, + "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": 41, "column": 9, @@ -250,12 +338,20 @@ { "start": 1043, "end": 1043, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n x1: number;\n x2: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n x1: number;\n x2: number;\n}\n", + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13 }, { "start": 1178, "end": 1228, - "replacementText": "({ x1: 10,\n x2: 20 } as GeneratedObjectLiteralInterface_2)" + "replacementText": "({ x1: 10,\n x2: 20 } as GeneratedObjectLiteralInterface_2)", + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13 } ], "suggest": "", @@ -282,7 +378,11 @@ { "start": 1299, "end": 1311, - "replacementText": "private a!: number;" + "replacementText": "private a!: number;", + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 7 } ], "suggest": "", diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.json b/ets2panda/linter/test/migration/mixed_problems.ets.json index dbb09ef3dc5bcac13242fb8caaa6b0e6f809b349..96624388d7cc0712cf3a957dde5e70746199a1da 100644 --- a/ets2panda/linter/test/migration/mixed_problems.ets.json +++ b/ets2panda/linter/test/migration/mixed_problems.ets.json @@ -134,6 +134,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 34, + "column": 9, + "endLine": 34, + "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": 35, + "column": 9, + "endLine": 35, + "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": 38, "column": 5, @@ -154,6 +174,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 39, + "column": 9, + "endLine": 39, + "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": 40, + "column": 9, + "endLine": 40, + "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": 41, "column": 9, diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json index bfb7a82f089b08ec604a536fff2ac426e2896312..0708a128c884dcda36beaf7b9cb54e48ed9e6ee6 100644 --- a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json +++ b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json @@ -34,6 +34,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 60, + "column": 5, + "endLine": 60, + "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": 61, + "column": 5, + "endLine": 61, + "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": 63, "column": 14, @@ -44,6 +64,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 64, + "column": 5, + "endLine": 64, + "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": 65, + "column": 5, + "endLine": 65, + "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": 66, "column": 5, diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json index 04102fd8c9c1695de263ff569ff15438f1733240..38bbc1707319fc8ba129853841abc026a08b3bdb 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 60, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 56, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 45, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 52, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 48, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json index dee154796f4b5da718f83077fbfc2a4fc38b6984..c81032fb95d2ea20b778669d0ba07441ad21abec 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json @@ -28,7 +28,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -45,7 +45,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -62,7 +62,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -79,7 +79,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -96,7 +96,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/rules/rule1.ets.autofix.json b/ets2panda/linter/test/rules/rule1.ets.autofix.json index 4418693726fc8d2fee1ef9a555ecaf70b8925a1e..0220cda6b41b17512ccad75a3cec0639b537a46a 100644 --- a/ets2panda/linter/test/rules/rule1.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule1.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 610, "end": 635, - "replacementText": "let x = { \"name\": 1, 2: 3 }" + "replacementText": "let x = { \"name\": 1, 2: 3 }", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 4 } ], "suggest": "", @@ -41,6 +45,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 16, + "column": 10, + "endLine": 16, + "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": 16, "column": 21, @@ -81,12 +95,20 @@ { "start": 719, "end": 719, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n}\n", + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 10 }, { "start": 724, "end": 724, - "replacementText": ": GeneratedObjectLiteralInterface_1" + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 10 } ], "suggest": "", diff --git a/ets2panda/linter/test/rules/rule1.ets.json b/ets2panda/linter/test/rules/rule1.ets.json index d5b0d795ee9ad175d1527c7d355ad0fb872dc4ea..424d045dbd18e13583f0273ba858a14d08cebc22 100644 --- a/ets2panda/linter/test/rules/rule1.ets.json +++ b/ets2panda/linter/test/rules/rule1.ets.json @@ -34,6 +34,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 16, + "column": 10, + "endLine": 16, + "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": 16, "column": 21, diff --git a/ets2panda/linter/test/rules/rule1.ets.migrate.json b/ets2panda/linter/test/rules/rule1.ets.migrate.json index a6b59e880c252dc5f29c2e55d97ff6242a0ba012..c61230891574c43734ca68382d94b761abfe858d 100644 --- a/ets2panda/linter/test/rules/rule1.ets.migrate.json +++ b/ets2panda/linter/test/rules/rule1.ets.migrate.json @@ -24,6 +24,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 16, + "column": 11, + "endLine": 16, + "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": 16, "column": 22, diff --git a/ets2panda/linter/test/rules/rule144.ets.json b/ets2panda/linter/test/rules/rule144.ets.json index c52a53a30f9636fb50e46086b03ff2f864d0fe20..9bbf5b7e7c41749d4583c23cfd4c6b7f4371e22e 100644 --- a/ets2panda/linter/test/rules/rule144.ets.json +++ b/ets2panda/linter/test/rules/rule144.ets.json @@ -274,6 +274,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 85, + "column": 1, + "endLine": 85, + "endColumn": 51, + "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": 86, "column": 1, @@ -284,6 +294,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 86, + "column": 1, + "endLine": 86, + "endColumn": 39, + "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": 86, "column": 32, @@ -304,6 +324,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 36, + "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": 87, "column": 32, @@ -324,6 +354,26 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 88, + "column": 1, + "endLine": 88, + "endColumn": 34, + "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": 89, + "column": 1, + "endLine": 89, + "endColumn": 32, + "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": 90, "column": 1, @@ -334,6 +384,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 90, + "column": 1, + "endLine": 90, + "endColumn": 53, + "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": 91, "column": 1, @@ -344,6 +404,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 91, + "column": 1, + "endLine": 91, + "endColumn": 27, + "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": 92, "column": 1, @@ -354,6 +424,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 92, + "column": 1, + "endLine": 92, + "endColumn": 25, + "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": 93, "column": 1, @@ -364,6 +444,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 93, + "column": 1, + "endLine": 93, + "endColumn": 30, + "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": 94, "column": 1, @@ -374,6 +464,86 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 94, + "column": 1, + "endLine": 94, + "endColumn": 30, + "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": 95, + "column": 1, + "endLine": 95, + "endColumn": 39, + "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": 96, + "column": 1, + "endLine": 96, + "endColumn": 46, + "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": 97, + "column": 1, + "endLine": 97, + "endColumn": 39, + "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": 98, + "column": 1, + "endLine": 98, + "endColumn": 39, + "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": 99, + "column": 1, + "endLine": 99, + "endColumn": 38, + "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": 100, + "column": 1, + "endLine": 100, + "endColumn": 31, + "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": 101, + "column": 1, + "endLine": 101, + "endColumn": 29, + "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": 104, "column": 32, 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/rule207.ets.arkts2.json b/ets2panda/linter/test/rules/rule207.ets.arkts2.json index 625924f2609834583615644f85222a937f10db3e..0b4e1a641512592fd533d01e2f4b9ae0cacbbe09 100644 --- a/ets2panda/linter/test/rules/rule207.ets.arkts2.json +++ b/ets2panda/linter/test/rules/rule207.ets.arkts2.json @@ -1,4 +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": [ { "line": 17, @@ -42,12 +56,12 @@ }, { "line": 25, - "column": 14, + "column": 35, "endLine": 25, - "endColumn": 19, - "problem": "NumericSemantics", + "endColumn": 41, + "problem": "BuiltinDisableApi", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "API has been disabled (arkts-builtin-disable-api)", "severity": "ERROR" }, { @@ -80,6 +94,16 @@ "rule": "Special arguments object inside functions are not supported (arkts-no-arguments-obj)", "severity": "ERROR" }, + { + "line": 31, + "column": 51, + "endLine": 31, + "endColumn": 57, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, { "line": 31, "column": 41, @@ -220,6 +244,16 @@ "rule": "Special arguments object inside functions are not supported (arkts-no-arguments-obj)", "severity": "ERROR" }, + { + "line": 57, + "column": 19, + "endLine": 57, + "endColumn": 25, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, { "line": 57, "column": 9, @@ -240,6 +274,16 @@ "rule": "Special arguments object inside functions are not supported (arkts-no-arguments-obj)", "severity": "ERROR" }, + { + "line": 65, + "column": 3, + "endLine": 65, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, { "line": 68, "column": 22, diff --git a/ets2panda/linter/test/rules/rule37.ets.arkts2.json b/ets2panda/linter/test/rules/rule37.ets.arkts2.json index e07b57d6dfb8725687fadcdc4937e02927228535..907deb012b6b900ad51bd985b8f9ab319d1d4159 100644 --- a/ets2panda/linter/test/rules/rule37.ets.arkts2.json +++ b/ets2panda/linter/test/rules/rule37.ets.arkts2.json @@ -24,6 +24,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 18, + "column": 27, + "endLine": 18, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 20, "column": 17, @@ -34,6 +44,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 35, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 23, "column": 23, @@ -44,6 +64,26 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 27, + "endLine": 27, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 27, "column": 34, @@ -54,6 +94,26 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 38, + "endLine": 29, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 31, "column": 23, @@ -64,6 +124,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 33, + "column": 28, + "endLine": 33, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 36, "column": 44, @@ -84,6 +154,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 40, + "column": 32, + "endLine": 40, + "endColumn": 38, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 43, "column": 22, @@ -94,6 +174,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 47, + "column": 34, + "endLine": 47, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 51, "column": 22, @@ -104,6 +194,16 @@ "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 55, + "column": 34, + "endLine": 55, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 59, "column": 17, diff --git a/ets2panda/linter/test/rules/rule37.ets.autofix.json b/ets2panda/linter/test/rules/rule37.ets.autofix.json index 3cad91ca09415031931a0886e1e44b09b2ec7132..73acc1da3e5a42d10a16607463fa4bce4ceb6e5e 100644 --- a/ets2panda/linter/test/rules/rule37.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule37.ets.autofix.json @@ -24,13 +24,27 @@ { "start": 631, "end": 637, - "replacementText": "new RegExp(\"bc*d\")" + "replacementText": "new RegExp(\"bc*d\")", + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 28 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 18, + "column": 27, + "endLine": 18, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 20, "column": 17, @@ -41,13 +55,27 @@ { "start": 699, "end": 764, - "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")" + "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")", + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 82 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 35, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 23, "column": 23, @@ -58,13 +86,37 @@ { "start": 892, "end": 900, - "replacementText": "new RegExp(\"bc*d\", \"ig\")" + "replacementText": "new RegExp(\"bc*d\", \"ig\")", + "line": 23, + "column": 23, + "endLine": 23, + "endColumn": 31 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 27, + "endLine": 27, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 27, "column": 34, @@ -75,13 +127,37 @@ { "start": 985, "end": 992, - "replacementText": "new RegExp(\"bc*d\", \"i\")" + "replacementText": "new RegExp(\"bc*d\", \"i\")", + "line": 27, + "column": 34, + "endLine": 27, + "endColumn": 41 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 38, + "endLine": 29, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 31, "column": 23, @@ -92,13 +168,27 @@ { "start": 1088, "end": 1093, - "replacementText": "new RegExp(\"a\\\\\\\\\")" + "replacementText": "new RegExp(\"a\\\\\\\\\")", + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 28 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 33, + "column": 28, + "endLine": 33, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 36, "column": 44, @@ -109,7 +199,11 @@ { "start": 1195, "end": 1201, - "replacementText": "new RegExp(\"bc*d\")" + "replacementText": "new RegExp(\"bc*d\")", + "line": 36, + "column": 44, + "endLine": 36, + "endColumn": 50 } ], "suggest": "", @@ -126,13 +220,27 @@ { "start": 1239, "end": 1304, - "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")" + "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")", + "line": 38, + "column": 36, + "endLine": 38, + "endColumn": 101 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 40, + "column": 32, + "endLine": 40, + "endColumn": 38, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 43, "column": 22, @@ -143,13 +251,27 @@ { "start": 1410, "end": 1416, - "replacementText": "new RegExp(\"bc*d\")" + "replacementText": "new RegExp(\"bc*d\")", + "line": 43, + "column": 22, + "endLine": 43, + "endColumn": 28 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 47, + "column": 34, + "endLine": 47, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 51, "column": 22, @@ -160,13 +282,27 @@ { "start": 1557, "end": 1563, - "replacementText": "new RegExp(\"bc*d\")" + "replacementText": "new RegExp(\"bc*d\")", + "line": 51, + "column": 22, + "endLine": 51, + "endColumn": 28 } ], "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" }, + { + "line": 55, + "column": 34, + "endLine": 55, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, { "line": 59, "column": 17, @@ -177,7 +313,11 @@ { "start": 1694, "end": 1759, - "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")" + "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")", + "line": 59, + "column": 17, + "endLine": 59, + "endColumn": 82 } ], "suggest": "", @@ -194,7 +334,11 @@ { "start": 1799, "end": 1864, - "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")" + "replacementText": "new RegExp(\"^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$\")", + "line": 63, + "column": 28, + "endLine": 63, + "endColumn": 93 } ], "suggest": "", @@ -211,7 +355,11 @@ { "start": 1890, "end": 1904, - "replacementText": "new RegExp(\"ab*c\")" + "replacementText": "new RegExp(\"ab*c\")", + "line": 65, + "column": 24, + "endLine": 65, + "endColumn": 38 } ], "suggest": "", @@ -228,7 +376,11 @@ { "start": 1929, "end": 1947, - "replacementText": "new RegExp(\"ab*c\", \"i\")" + "replacementText": "new RegExp(\"ab*c\", \"i\")", + "line": 67, + "column": 24, + "endLine": 67, + "endColumn": 42 } ], "suggest": "", @@ -245,7 +397,11 @@ { "start": 1968, "end": 1992, - "replacementText": "new RegExp('dawfgr' + '12345')" + "replacementText": "new RegExp('dawfgr' + '12345')", + "line": 69, + "column": 20, + "endLine": 69, + "endColumn": 44 } ], "suggest": "", @@ -262,7 +418,11 @@ { "start": 2013, "end": 2169, - "replacementText": "new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗')" + "replacementText": "new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗')", + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 176 } ], "suggest": "", @@ -279,7 +439,11 @@ { "start": 2195, "end": 2227, - "replacementText": "new RegExp('dawfgr'.concat('12345'))" + "replacementText": "new RegExp('dawfgr'.concat('12345'))", + "line": 73, + "column": 24, + "endLine": 73, + "endColumn": 56 } ], "suggest": "", @@ -296,7 +460,11 @@ { "start": 2250, "end": 2282, - "replacementText": "new RegExp('dawfgr' + '12345' + '789')" + "replacementText": "new RegExp('dawfgr' + '12345' + '789')", + "line": 75, + "column": 21, + "endLine": 75, + "endColumn": 53 } ], "suggest": "", diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.json b/ets2panda/linter/test/rules/rule37.ets.migrate.json index ca88f857e960b437dcf767c0ac40be998c8f1236..37f9ac92510e701122490aa80c5e2dad68676e68 100644 --- a/ets2panda/linter/test/rules/rule37.ets.migrate.json +++ b/ets2panda/linter/test/rules/rule37.ets.migrate.json @@ -13,5 +13,276 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 16, + "column": 26, + "endLine": 16, + "endColumn": 32, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 27, + "endLine": 18, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 27, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 35, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 27, + "endLine": 27, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 38, + "endLine": 27, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 38, + "endLine": 29, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 27, + "endLine": 31, + "endColumn": 33, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 28, + "endLine": 33, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 48, + "endLine": 36, + "endColumn": 54, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 40, + "endLine": 38, + "endColumn": 46, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 32, + "endLine": 40, + "endColumn": 38, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 26, + "endLine": 43, + "endColumn": 32, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 34, + "endLine": 47, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 26, + "endLine": 51, + "endColumn": 32, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 34, + "endLine": 55, + "endColumn": 40, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 21, + "endLine": 59, + "endColumn": 27, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 32, + "endLine": 63, + "endColumn": 38, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 28, + "endLine": 65, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 28, + "endLine": 67, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 24, + "endLine": 69, + "endColumn": 30, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 24, + "endLine": 71, + "endColumn": 30, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 34, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 25, + "endLine": 75, + "endColumn": 31, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/@ohos.convertxml.d.ts b/ets2panda/linter/test/sdkcommonapi/@ohos.convertxml.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e9aafa2364eabca443067f410c73caf4c4aee3b8 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/@ohos.convertxml.d.ts @@ -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 declare namespace xml { + interface ConvertOptions { + trim: boolean; + ignoreDeclaration?: boolean; + ignoreInstruction?: boolean; + ignoreAttributes?: boolean; + ignoreComment?: boolean; + ignoreCDATA?: boolean; + ignoreDoctype?: boolean; + ignoreText?: boolean; + declarationKey: string; + instructionKey: string; + attributesKey: string; + textKey: string; + cdataKey: string; + doctypeKey: string; + commentKey: string; + parentKey: string; + typeKey: string; + nameKey: string; + elementsKey: string; + } + class ConvertXML { + convert(xml: string, options?: ConvertOptions): Object; + convertToJSObject(xml: string, options?: ConvertOptions): Object; + fastConvertToJSObject(xml: string, options?: ConvertOptions): Object; + } +} +export default xml; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/@ohos.util.ArrayList.d.ts b/ets2panda/linter/test/sdkcommonapi/@ohos.util.ArrayList.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd9e51d62d2dde9375eb7eda160a9eb627d263ae --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/@ohos.util.ArrayList.d.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. + */ + +export declare class ArrayList { + constructor(); + [Symbol.iterator](): IterableIterator; + sort(comparator?: (firstValue: T, secondValue: T) => number): void; + forEach(callbackFn: (value: T, index?: number, arrlist?: ArrayList) => void, thisArg?: Object): void; + replaceAllElements(callbackFn: (value: T, index?: number, arrlist?: ArrayList) => T, thisArg?: Object): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/@ohos.util.Vector.d.ts b/ets2panda/linter/test/sdkcommonapi/@ohos.util.Vector.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..8fae94d4d521dba152e072d75f6852c2e24d8157 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/@ohos.util.Vector.d.ts @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 Vector { + /** + * A constructor used to create a Vector object. + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + constructor(); + /** + * Gets the element number of the Vector. This is a number one higher than the highest index in the vector. + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + length: number; + /** + * Appends the specified element to the end of this vector. + * + * @param { T } element - Element to be appended to this vector + * @returns { boolean } the boolean type, returns true if the addition is successful, and returns false if it fails. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + add(element: T): boolean; + /** + * Inserts the specified element at the specified position in this + * vector. Shifts the element currently at that position (if any) and + * any subsequent elements to the right (adds one to their index). + * + * @param { T } element - Element at which the specified element is to be inserted + * @param { number } index - Index to be inserted + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + insert(element: T, index: number): void; + /** + * Check if vector contains the specified element + * + * @param { T } element - Element to be contained + * @returns { boolean } the boolean type,if vector contains the specified element,return true,else return false + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + has(element: T): boolean; + /** + * Returns the element at the specified position in this Vector,or returns undefined if vector is empty + * + * @param { number } index - Index to be contained + * @returns { T } the number type ,returns the lowest index such that or -1 if there is no such index. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + get(index: number): T; + /** + * Returns the index of the first occurrence of the specified element + * in this vector, or -1 if this vector does not contain the element. + * + * @param { T } element - Element current index + * @returns { number } the number type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getIndexOf(element: T): number; + /** + * Returns the first component (the item at index 0) of this vector. + * or returns undefined if vector is empty + * + * @returns { T } the T type ,returns undefined if vector is empty + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getFirstElement(): T; + /** + * Returns the Last component (the item at index length-1) of this vector. + * or returns undefined if vector is empty + * + * @returns { T } the T type ,returns undefined if vector is empty + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getLastElement(): T; + /** + * Find the corresponding element according to the index, + * delete the element, and move the index of all elements to the right of the element forward by one. + * + * @param { number } index - The index in the vector + * @returns { T } the T type ,returns undefined if vector is empty,If the index is + * out of bounds (greater than or equal to length or less than 0), throw an exception + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + removeByIndex(index: number): T; + /** + * Removes the first occurrence of the specified element from this vector, + * if it is present. If the vector does not contain the element, it is + * unchanged. More formally, removes the element with the lowest index + * + * @param { T } element - Element to remove + * @returns { boolean } the boolean type ,If there is no such element, return false + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + remove(element: T): boolean; + /** + * Replaces the element at the specified position in this Vector with the specified element + * + * @param { number } index - Index to find + * @param { T } element - Element replaced element + * @returns { T } the T type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + set(index: number, element: T): T; + /** + * Returns in the index of the last occurrence of the specified element in this vector , + * or -1 if the vector does not contain the element. + * + * @param { T } element - Element to find + * @returns { number } The number type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getLastIndexOf(element: T): number; + /** + * Returns the index of the last occurrence of the specified element in this vector ,searching backwards from index, + * or returns -1 if the element is not found,or -1 if there is no such index + * + * @param { T } element - Element to find + * @param { number } index - Index start index + * @returns { number } the number type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getLastIndexFrom(element: T, index: number): number; + /** + * Returns the index of the first occurrence of the specified element in this vector ,searching forwards from index, + * or returns -1 if the element is not found,or -1 if there is no such index + * + * @param { T } element - Element to find + * @param { number } index - Index start index + * @returns { number } the number type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getIndexFrom(element: T, index: number): number; + /** + * Removes from this vector all of the elements whose index is between fromIndex,inclusive,and toIndex ,exclusive. + * + * @param { number } fromIndex - The starting position of the index, containing the value at that index position + * @param { number } toIndex - The end of the index, excluding the value at that index + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + removeByRange(fromIndex: number, toIndex: number): void; + /** + * Replaces each element of this vector with the result of applying the operator to that element. + * + * @param { function } callbackFn - A function that accepts up to four arguments.The function to be called + * for each element in the vector,Returns the result of an operation + * @param { Object } thisArg - The value passed to the function generally uses the + * "this" value.If this parameter is empty, "undefined" will be passed to the "this" value + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + replaceAllElements(callbackFn: (value: T, index?: number, vector?: Vector) => T, thisArg?: Object): void; + /** + * Executes a provided function once for each value in the vector object. + * + * @param { function } callbackFn - callbackFn + * callbackFn (required) A function that accepts up to four arguments.The function to be + * called for each element in the vector + * @param { Object } thisArg - The value passed to the function generally uses the "this" value. + * If this parameter is empty, "undefined" will be passed to the "this" value + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + forEach(callbackFn: (value: T, index?: number, vector?: Vector) => void, thisArg?: Object): void; + /** + * Sorts this vector according to the order induced by the specified comparator,without comparator + * this parameter, it will default to ASCII sorting + * + * @param { function } comparator - comparator + * (Optional) A function that accepts up to two arguments.Specifies the sort order. + * Must be a function,return number type,If it returns firstValue minus secondValue, it returns an vector sorted + * in ascending order;If it returns secondValue minus firstValue, it returns an vector sorted in descending order; + * If this parameter is empty, it will default to ASCII sorting + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + sort(comparator?: (firstValue: T, secondValue: T) => number): void; + /** + * Returns a view of the portion of this vector between the specified fromIndex,inclusive,and toIndex,exclusive + * + * @param { number } fromIndex - The starting position of the index, containing the value at that index position + * @param { number } toIndex - The end of the index, excluding the value at that index + * @returns { Vector } + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + subVector(fromIndex: number, toIndex: number): Vector; + /** + * Removes all of the elements from this vector.The vector will + * be empty after this call returns.length becomes 0 + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + clear(): void; + /** + * Returns a shallow copy of this instance. (The elements themselves are not copied.) + * + * @returns { Vector } this vector instance + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + clone(): Vector; + /** + * Sets the length of this vector + * + * @param { number } newSize - newSize + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + setLength(newSize: number): void; + /** + * returns the capacity of this vector + * + * @returns { number } the number type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + getCapacity(): number; + /** + * convert vector to array + * + * @returns { Array } the Array type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + convertToArray(): Array; + /** + * Determine whether vector is empty and whether there is an element + * + * @returns { boolean } the boolean type + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + isEmpty(): boolean; + /** + * If the newCapacity provided by the user is greater than or equal to length, + * change the capacity of the vector to newCapacity, otherwise the capacity will not be changed + * + * @param { number } newCapacity - newCapacity + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + increaseCapacityTo(newCapacity: number): void; + /** + * Returns a string representation of this Vector, + * containing the String representation of each element + * + * @returns { string } + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + toString(): string; + /** + * Limit the capacity to the current length + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + trimToCurrentLength(): void; + /** + * Copies the components of this vector into the specified array, + * to overwrite elements of the same index + * + * @param { Array } array - Replaced array + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + copyToArray(array: Array): void; + /** + * returns an ES6 iterator.Each item of the iterator is a Javascript Object + * + * @returns { IterableIterator } + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + */ + [Symbol.iterator](): IterableIterator; +} +export default Vector; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/@ohos.util.d.ts b/ets2panda/linter/test/sdkcommonapi/@ohos.util.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..83195de524f79948d4192d5b8efeeade6fc10169 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/@ohos.util.d.ts @@ -0,0 +1,1191 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 util { + class Base64 { + /** + * Constructor for creating base64 encoding and decoding + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.constructor + */ + constructor(); + /** + * Encodes all bytes from the specified u8 array into a newly-allocated u8 array using the Base64 encoding scheme. + * + * @param { Uint8Array } src - A Uint8Array value + * @returns { Uint8Array } Return the encoded new Uint8Array. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.encodeSync + */ + encodeSync(src: Uint8Array): Uint8Array; + /** + * Encodes the specified byte array into a String using the Base64 encoding scheme. + * + * @param { Uint8Array } src - A Uint8Array value + * @returns { string } Return the encoded string. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.encodeToStringSync + */ + encodeToStringSync(src: Uint8Array): string; + /** + * Decodes a Base64 encoded String or input u8 array into a newly-allocated u8 array using the Base64 encoding scheme. + * + * @param { Uint8Array | string } src - A Uint8Array value or value A string value + * @returns { Uint8Array } Return the decoded Uint8Array. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.decodeSync + */ + decodeSync(src: Uint8Array | string): Uint8Array; + /** + * Asynchronously encodes all bytes in the specified u8 array into the newly allocated u8 array using the Base64 encoding scheme. + * + * @param { Uint8Array } src - A Uint8Array value + * @returns { Promise } Return the encodes asynchronous new Uint8Array. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.encode + */ + encode(src: Uint8Array): Promise; + /** + * Asynchronously encodes the specified byte array into a String using the Base64 encoding scheme. + * + * @param { Uint8Array } src - A Uint8Array value + * @returns { Promise } Returns the encoded asynchronous string. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.encodeToString + */ + encodeToString(src: Uint8Array): Promise; + /** + * Use the Base64 encoding scheme to asynchronously decode a Base64-encoded string or input u8 array into a newly allocated u8 array. + * + * @param { Uint8Array | string } src - A Uint8Array value or value A string value + * @returns { Promise } Return the decoded asynchronous Uint8Array. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.Base64Helper.decode + */ + decode(src: Uint8Array | string): Promise; + } + class LruBuffer { + /** + * Default constructor used to create a new LruBuffer instance with the default capacity of 64. + * + * @param { number } capacity - Indicates the capacity to customize for the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.constructor + */ + constructor(capacity?: number); + /** + * Updates the buffer capacity to a specified capacity. + * + * @param { number } newCapacity - Indicates the new capacity to set. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.updateCapacity + */ + updateCapacity(newCapacity: number): void; + /** + * Returns a string representation of the object. + * + * @returns { string } Returns the string representation of the object and outputs the string representation of the object. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.toString + */ + toString(): string; + /** + * Obtains a list of all values in the current buffer. + * + * @type { number } + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.length + */ + length: number; + /** + * Obtains the capacity of the current buffer. + * + * @returns { number } Returns the capacity of the current buffer. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getCapacity + */ + getCapacity(): number; + /** + * Clears key-value pairs from the current buffer. + * + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.clear + */ + clear(): void; + /** + * Obtains the number of times createDefault(Object) returned a value. + * + * @returns { number } Returns the number of times createDefault(java.lang.Object) returned a value. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getCreateCount + */ + getCreateCount(): number; + /** + * Obtains the number of times that the queried values are not matched. + * + * @returns { number } Returns the number of times that the queried values are not matched. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getMissCount + */ + getMissCount(): number; + /** + * Obtains the number of times that values are evicted from the buffer. + * + * @returns { number } Returns the number of times that values are evicted from the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getRemovalCount + */ + getRemovalCount(): number; + /** + * Obtains the number of times that the queried values are successfully matched. + * + * @returns { number } Returns the number of times that the queried values are successfully matched. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getMatchCount + */ + getMatchCount(): number; + /** + * Obtains the number of times that values are added to the buffer. + * + * @returns { number } Returns the number of times that values are added to the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.getPutCount + */ + getPutCount(): number; + /** + * Checks whether the current buffer is empty. + * + * @returns { boolean } Returns true if the current buffer contains no value. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.isEmpty + */ + isEmpty(): boolean; + /** + * Obtains the value associated with a specified key. + * + * @param { K } key - Indicates the key to query. + * @returns { V | undefined } Returns the value associated with the key if the specified key is present in the buffer; returns null otherwise. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.get + */ + get(key: K): V | undefined; + /** + * Adds a key-value pair to the buffer. + * + * @param { K } key - Indicates the key to add. + * @param { V } value - Indicates the value associated with the key to add. + * @returns { V } Returns the value associated with the added key; returns the original value if the key to add already exists. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.put + */ + put(key: K, value: V): V; + /** + * Obtains a list of all values in the current buffer. + * + * @returns { V[] } Returns the list of all values in the current buffer in ascending order, from the most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.values + */ + values(): V[]; + /** + * Obtains a list of keys for the values in the current buffer. + * + * @returns { K[] } Returns a list of keys sorted from most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.keys + */ + keys(): K[]; + /** + * Deletes a specified key and its associated value from the current buffer. + * + * @param { K } key - Indicates the key to delete. + * @returns { V | undefined } Returns an Optional object containing the deleted key-value pair; returns an empty Optional object if the key does not exist. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.remove + */ + remove(key: K): V | undefined; + /** + * Executes subsequent operations after a value is deleted. + * + * @param { boolean } isEvict - The parameter value is true if this method is called due to insufficient capacity, + * and the parameter value is false in other cases. + * @param { K } key - Indicates the deleted key. + * @param { V } value - Indicates the deleted value. + * @param { V } newValue - The parameter value is the new value associated if the put(java.lang.Object,java.lang.Object) + * method is called and the key to add already exists. The parameter value is null in other cases. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.afterRemoval + */ + afterRemoval(isEvict: boolean, key: K, value: V, newValue: V): void; + /** + * Checks whether the current buffer contains a specified key. + * + * @param { K } key - Indicates the key to check. + * @returns { boolean } Returns true if the buffer contains the specified key. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.contains + */ + contains(key: K): boolean; + /** + * Called after a cache miss to compute a value for the corresponding key. + * + * @param { K } key - Indicates the missed key. + * @returns { V } Returns the value associated with the key. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.createDefault + */ + createDefault(key: K): V; + /** + * Returns an array of key-value pairs of enumeratable properties of a given object. + * + * @returns { IterableIterator<[K, V]> } Returns an array of key-value pairs for the enumeratable properties of the given object itself. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.entries + */ + entries(): IterableIterator<[ + K, + V + ]>; + /** + * Specifies the default iterator for an object. + * @returns { IterableIterator<[K, V]> } Returns a two - dimensional array in the form of key - value pairs. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.LRUCache.[Symbol.iterator] + */ + [Symbol.iterator](): IterableIterator<[ + K, + V + ]>; + } + class LRUCache { + /** + * Default constructor used to create a new LruBuffer instance with the default capacity of 64. + * + * @param { number } [capacity] - Indicates the capacity to customize for the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Default constructor used to create a new LruBuffer instance with the default capacity of 64. + * + * @param { number } [capacity] - Indicates the capacity to customize for the buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Default constructor used to create a new LruBuffer instance with the default capacity of 64. + * + * @param { number } [capacity] - Indicates the capacity to customize for the buffer. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + constructor(capacity?: number); + /** + * Updates the buffer capacity to a specified capacity. + * + * @param { number } newCapacity - Indicates the new capacity to set. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1.Mandatory parameters are left unspecified. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Updates the buffer capacity to a specified capacity. + * + * @param { number } newCapacity - Indicates the new capacity to set. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1.Mandatory parameters are left unspecified. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Updates the buffer capacity to a specified capacity. + * + * @param { number } newCapacity - Indicates the new capacity to set. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1.Mandatory parameters are left unspecified. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + updateCapacity(newCapacity: number): void; + /** + * Returns a string representation of the object. + * + * @returns { string } Returns the string representation of the object and outputs the string representation of the object. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Returns a string representation of the object. + * + * @returns { string } Returns the string representation of the object and outputs the string representation of the object. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Returns a string representation of the object. + * + * @returns { string } Returns the string representation of the object and outputs the string representation of the object. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + toString(): string; + /** + * Obtains a list of all values in the current buffer. + * + * @type { number } + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains a list of all values in the current buffer. + * + * @type { number } + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains a list of all values in the current buffer. + * + * @type { number } + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + length: number; + /** + * Obtains the capacity of the current buffer. + * + * @returns { number } Returns the capacity of the current buffer. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the capacity of the current buffer. + * + * @returns { number } Returns the capacity of the current buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the capacity of the current buffer. + * + * @returns { number } Returns the capacity of the current buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getCapacity(): number; + /** + * Clears key-value pairs from the current buffer. + * + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Clears key-value pairs from the current buffer. + * + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Clears key-value pairs from the current buffer. + * + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + clear(): void; + /** + * Obtains the number of times createDefault(Object) returned a value. + * + * @returns { number } Returns the number of times createDefault(java.lang.Object) returned a value. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the number of times createDefault(Object) returned a value. + * + * @returns { number } Returns the number of times createDefault(java.lang.Object) returned a value. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the number of times createDefault(Object) returned a value. + * + * @returns { number } Returns the number of times createDefault(java.lang.Object) returned a value. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getCreateCount(): number; + /** + * Obtains the number of times that the queried values are not matched. + * + * @returns { number } Returns the number of times that the queried values are not matched. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the number of times that the queried values are not matched. + * + * @returns { number } Returns the number of times that the queried values are not matched. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the number of times that the queried values are not matched. + * + * @returns { number } Returns the number of times that the queried values are not matched. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getMissCount(): number; + /** + * Obtains the number of times that values are evicted from the buffer. + * + * @returns { number } Returns the number of times that values are evicted from the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the number of times that values are evicted from the buffer. + * + * @returns { number } Returns the number of times that values are evicted from the buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the number of times that values are evicted from the buffer. + * + * @returns { number } Returns the number of times that values are evicted from the buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getRemovalCount(): number; + /** + * Obtains the number of times that the queried values are successfully matched. + * + * @returns { number } Returns the number of times that the queried values are successfully matched. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the number of times that the queried values are successfully matched. + * + * @returns { number } Returns the number of times that the queried values are successfully matched. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the number of times that the queried values are successfully matched. + * + * @returns { number } Returns the number of times that the queried values are successfully matched. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getMatchCount(): number; + /** + * Obtains the number of times that values are added to the buffer. + * + * @returns { number } Returns the number of times that values are added to the buffer. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the number of times that values are added to the buffer. + * + * @returns { number } Returns the number of times that values are added to the buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the number of times that values are added to the buffer. + * + * @returns { number } Returns the number of times that values are added to the buffer. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + getPutCount(): number; + /** + * Checks whether the current buffer is empty. + * + * @returns { boolean } Returns true if the current buffer contains no value. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Checks whether the current buffer is empty. + * + * @returns { boolean } Returns true if the current buffer contains no value. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Checks whether the current buffer is empty. + * + * @returns { boolean } Returns true if the current buffer contains no value. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + isEmpty(): boolean; + /** + * Obtains the value associated with a specified key. + * + * @param { K } key - Indicates the key to query. + * @returns { V | undefined } Returns the value associated with the key if the specified key is present in the buffer; returns null otherwise. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains the value associated with a specified key. + * + * @param { K } key - Indicates the key to query. + * @returns { V | undefined } Returns the value associated with the key if the specified key is present in the buffer; returns null otherwise. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains the value associated with a specified key. + * + * @param { K } key - Indicates the key to query. + * @returns { V | undefined } Returns the value associated with the key if the specified key is present in the buffer; returns null otherwise. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + get(key: K): V | undefined; + /** + * Adds a key-value pair to the buffer. + * + * @param { K } key - Indicates the key to add. + * @param { V } value - Indicates the value associated with the key to add. + * @returns { V } Returns the value associated with the added key; returns the original value if the key to add already exists. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Adds a key-value pair to the buffer. + * + * @param { K } key - Indicates the key to add. + * @param { V } value - Indicates the value associated with the key to add. + * @returns { V } Returns the value associated with the added key; returns the original value if the key to add already exists. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Adds a key-value pair to the buffer. + * + * @param { K } key - Indicates the key to add. + * @param { V } value - Indicates the value associated with the key to add. + * @returns { V } Returns the value associated with the added key; returns the original value if the key to add already exists. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + put(key: K, value: V): V; + /** + * Obtains a list of all values in the current buffer. + * + * @returns { V[] } Returns the list of all values in the current buffer in ascending order, from the most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains a list of all values in the current buffer. + * + * @returns { V[] } Returns the list of all values in the current buffer in ascending order, from the most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains a list of all values in the current buffer. + * + * @returns { V[] } Returns the list of all values in the current buffer in ascending order, from the most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + values(): V[]; + /** + * Obtains a list of keys for the values in the current buffer. + * since 9 + * + * @returns { K[] } Returns a list of keys sorted from most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Obtains a list of keys for the values in the current buffer. + * since 9 + * + * @returns { K[] } Returns a list of keys sorted from most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Obtains a list of keys for the values in the current buffer. + * since 9 + * + * @returns { K[] } Returns a list of keys sorted from most recently accessed to least recently accessed. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + keys(): K[]; + /** + * Deletes a specified key and its associated value from the current buffer. + * + * @param { K } key - Indicates the key to delete. + * @returns { V | undefined } Returns an Optional object containing the deleted key-value pair; returns an empty Optional object if the key does not exist. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Deletes a specified key and its associated value from the current buffer. + * + * @param { K } key - Indicates the key to delete. + * @returns { V | undefined } Returns an Optional object containing the deleted key-value pair; returns an empty Optional object if the key does not exist. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Deletes a specified key and its associated value from the current buffer. + * + * @param { K } key - Indicates the key to delete. + * @returns { V | undefined } Returns an Optional object containing the deleted key-value pair; returns an empty Optional object if the key does not exist. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + remove(key: K): V | undefined; + /** + * Executes subsequent operations after a value is deleted. + * + * @param { boolean } isEvict - The parameter value is true if this method is called due to insufficient capacity, + * and the parameter value is false in other cases. + * @param { K } key - Indicates the deleted key. + * @param { V } value - Indicates the deleted value. + * @param { V } newValue - The parameter value is the new value associated if the put(java.lang.Object,java.lang.Object) + * method is called and the key to add already exists. The parameter value is null in other cases. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Executes subsequent operations after a value is deleted. + * + * @param { boolean } isEvict - The parameter value is true if this method is called due to insufficient capacity, + * and the parameter value is false in other cases. + * @param { K } key - Indicates the deleted key. + * @param { V } value - Indicates the deleted value. + * @param { V } newValue - The parameter value is the new value associated if the put(java.lang.Object,java.lang.Object) + * method is called and the key to add already exists. The parameter value is null in other cases. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Executes subsequent operations after a value is deleted. + * + * @param { boolean } isEvict - The parameter value is true if this method is called due to insufficient capacity, + * and the parameter value is false in other cases. + * @param { K } key - Indicates the deleted key. + * @param { V } value - Indicates the deleted value. + * @param { V } newValue - The parameter value is the new value associated if the put(java.lang.Object,java.lang.Object) + * method is called and the key to add already exists. The parameter value is null in other cases. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + afterRemoval(isEvict: boolean, key: K, value: V, newValue: V): void; + /** + * Checks whether the current buffer contains a specified key. + * + * @param { K } key - Indicates the key to check. + * @returns { boolean } Returns true if the buffer contains the specified key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Checks whether the current buffer contains a specified key. + * + * @param { K } key - Indicates the key to check. + * @returns { boolean } Returns true if the buffer contains the specified key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Checks whether the current buffer contains a specified key. + * + * @param { K } key - Indicates the key to check. + * @returns { boolean } Returns true if the buffer contains the specified key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + contains(key: K): boolean; + /** + * Executes subsequent operations if miss to compute a value for the specific key. + * + * @param { K } key - Indicates the missed key. + * @returns { V } Returns the value associated with the key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Executes subsequent operations if miss to compute a value for the specific key. + * + * @param { K } key - Indicates the missed key. + * @returns { V } Returns the value associated with the key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Executes subsequent operations if miss to compute a value for the specific key. + * + * @param { K } key - Indicates the missed key. + * @returns { V } Returns the value associated with the key. + * @throws { BusinessError } 401 - Parameter error. Possible causes: + * 1.Mandatory parameters are left unspecified; + * 2.Incorrect parameter types. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + createDefault(key: K): V; + /** + * Returns an array of key-value pairs of enumeratable properties of a given object. + * + * @returns { IterableIterator<[K, V]> } Returns an array of key-value pairs for the enumeratable properties of the given object itself. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Returns an array of key-value pairs of enumeratable properties of a given object. + * + * @returns { IterableIterator<[K, V]> } Returns an array of key-value pairs for the enumeratable properties of the given object itself. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Returns an array of key-value pairs of enumeratable properties of a given object. + * + * @returns { IterableIterator<[K, V]> } Returns an array of key-value pairs for the enumeratable properties of the given object itself. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + entries(): IterableIterator<[ + K, + V + ]>; + /** + * Specifies the default iterator for an object. + * + * @returns { IterableIterator<[K, V]> } Returns a two - dimensional array in the form of key - value pairs. + * @syscap SystemCapability.Utils.Lang + * @since 9 + */ + /** + * Specifies the default iterator for an object. + * + * @returns { IterableIterator<[K, V]> } Returns a two - dimensional array in the form of key - value pairs. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * Specifies the default iterator for an object. + * + * @returns { IterableIterator<[K, V]> } Returns a two - dimensional array in the form of key - value pairs. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + [Symbol.iterator](): IterableIterator<[ + K, + V + ]>; + } + class Scope { + /** + * A constructor used to create a Scope instance with the lower and upper bounds specified. + * + * @param { ScopeType } lowerObj - A ScopeType value + * @param { ScopeType } upperObj - A ScopeType value + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.constructor + */ + constructor(lowerObj: ScopeType, upperObj: ScopeType); + /** + * Obtains a string representation of the current range. + * + * @returns { string } Returns a string representation of the current range object. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.toString + */ + toString(): string; + /** + * Returns the intersection of a given range and the current range. + * + * @param { Scope } range - A Scope range object + * @returns { Scope } Returns the intersection of a given range and the current range. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.intersect + */ + intersect(range: Scope): Scope; + /** + * Returns the intersection of the current range and the range specified by the given lower and upper bounds. + * + * @param { ScopeType } lowerObj - A ScopeType value + * @param { ScopeType } upperObj - A ScopeType value + * @returns { Scope } Returns the intersection of the current range and the range specified by the given lower and upper bounds. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.intersect + */ + intersect(lowerObj: ScopeType, upperObj: ScopeType): Scope; + /** + * Obtains the upper bound of the current range. + * + * @returns { ScopeType } Returns the upper bound of the current range. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.getUpper + */ + getUpper(): ScopeType; + /** + * Obtains the lower bound of the current range. + * + * @returns { ScopeType } Returns the lower bound of the current range. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.getLower + */ + getLower(): ScopeType; + /** + * Creates the smallest range that includes the current range and the given lower and upper bounds. + * + * @param { ScopeType } lowerObj - A ScopeType value + * @param { ScopeType } upperObj - A ScopeType value + * @returns { Scope } Returns the smallest range that includes the current range and the given lower and upper bounds. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.expand + */ + expand(lowerObj: ScopeType, upperObj: ScopeType): Scope; + /** + * Creates the smallest range that includes the current range and a given range. + * + * @param { Scope } range - A Scope range object + * @returns { Scope } Returns the smallest range that includes the current range and a given range. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.expand + */ + expand(range: Scope): Scope; + /** + * Creates the smallest range that includes the current range and a given value. + * + * @param { ScopeType } value - A ScopeType value + * @returns { Scope } Returns the smallest range that includes the current range and a given value. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.expand + */ + expand(value: ScopeType): Scope; + /** + * Checks whether a given value is within the current range. + * + * @param { ScopeType } value - A ScopeType value + * @returns { boolean } If the value is within the current range return true,otherwise return false. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.contains + */ + contains(value: ScopeType): boolean; + /** + * Checks whether a given range is within the current range. + * + * @param { Scope } range - A Scope range + * @returns { boolean } If the current range is within the given range return true,otherwise return false. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.contains + */ + contains(range: Scope): boolean; + /** + * Clamps a given value to the current range. + * + * @param { ScopeType } value - A ScopeType value + * @returns { ScopeType } Returns a ScopeType object that a given value is clamped to the current range.. + * @syscap SystemCapability.Utils.Lang + * @since 8 + * @deprecated since 9 + * @useinstead ohos.util.ScopeHelper.clamp + */ + clamp(value: ScopeType): ScopeType; + } + interface ScopeComparable { + /** + * The comparison function is used by the scope. + * + * @param { ScopeComparable } other - Other + * @returns { boolean } Returns whether the current object is greater than or equal to the input object. + * @syscap SystemCapability.Utils.Lang + * @since 8 + */ + /** + * The comparison function is used by the scope. + * + * @param { ScopeComparable } other - Other + * @returns { boolean } Returns whether the current object is greater than or equal to the input object. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @since 10 + */ + /** + * The comparison function is used by the scope. + * + * @param { ScopeComparable } other - Other + * @returns { boolean } Returns whether the current object is greater than or equal to the input object. + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 12 + */ + compareTo(other: ScopeComparable): boolean; + } + class types { + isArgumentsObject(value: Object): boolean; + isGeneratorFunction(value: Object): boolean; + isGeneratorObject(value: Object): boolean; + isModuleNamespaceObject(value: Object): boolean; + isProxy(value: Object): boolean; + isSymbolObject(value: Object): boolean; + } + class Aspect { + static addBefore(targetClass: Object, methodName: string, isStatic: boolean, before: Function): void; + static addAfter(targetClass: Object, methodName: string, isStatic: boolean, after: Function): void; + static replace(targetClass: Object, methodName: string, isStatic: boolean, instead: Function): void; + } + class Base64Helper { + encodeToStringSync(src: Uint8Array, options?: Type): string; + } + function getErrorString(errno: number): string; + function printf(format: string, ...args: Object[]): string; + function promiseWrapper(original: (err: Object, value: Object) => void): Object; + interface DecodeWithStreamOptions { + /** + * Does the call follow additional data blocks. The default value is false. + * @type { ?boolean } + * @syscap SystemCapability.Utils.Lang + * @crossplatform + * @atomicservice + * @since 11 + */ + stream?: boolean; + } + class TextDecoder { + constructor(encoding?: string, options?: { + fatal?: boolean; + ignoreBOM?: boolean; + }); + decode(input: Uint8Array, options?: { + stream?: false; + }): string; + decodeWithStream(input: Uint8Array, options?: DecodeWithStreamOptions): string; + } + class TextEncoder { + encode(input?: string): Uint8Array; + encodeInto(input: string, dest: Uint8Array): { + read: number; + written: number; + }; + } +} +export default util; diff --git a/ets2panda/linter/test/sdkcommonapi/api/@arkts.collections.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@arkts.collections.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e48680b12238846f5072b0afd8c2dc9970e0843b --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@arkts.collections.d.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. + */ + +declare namespace collections { + class Array implements ConcatArray { + constructor(); + constructor(first: T, ...left: T[]); + } + class Float32Array { + constructor(); + } + class Uint8Array { + constructor(); + } + class Uint8ClampedArray { + constructor(); + } + class Uint16Array { + constructor(); + } + class Uint32Array { + constructor(); + } +} + +export default collections; diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.buffer.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.buffer.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f42a4512357b2ffca4f70ba136daf1dccdc7b91f --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.buffer.d.ts @@ -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. + */ + +declare namespace buffer { + class Blob { + slice(start?: number, end?: number, type?: string): Blob; + } + class Buffer { + readInt8(offset?: number): number; + readInt16BE(offset?: number): number; + readInt16LE(offset?: number): number; + readInt32BE(offset?: number): number; + readInt32LE(offset?: number): number; + readIntBE(offset: number, byteLength: number): number; + readIntLE(offset: number, byteLength: number): number; + indexOf(value: string | number | Buffer | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; + } + function from(string: String, encoding?: BufferEncoding): Buffer; +} +export default buffer; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.url.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.url.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..ad14ed13864098c7c0781410c665dd01d25092f7 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.url.d.ts @@ -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. + */ + +declare namespace url { + class URLSearchParams { + constructor(init?: string[][] | Record | string | URLSearchParams); + [Symbol.iterator](): IterableIterator<[ + string, + string + ]>; + append(name: string, value: string): void; + delete(name: string): void; + getAll(name: string): string[]; + has(name: string): boolean; + keys(): IterableIterator; + entries(): IterableIterator<[ + string, + string + ]>; + forEach(callbackFn: (value: string, key: string, searchParams: URLSearchParams) => void, thisArg?: Object): void; + get(name: string): string | null; + set(name: string, value: string): void; + sort(): void; + toString(): string; + values(): IterableIterator; + } + class URL { + href: string; + readonly origin: string; + pathname: string; + search: string; + readonly searchParams: URLSearchParams; + } + class URLParams { + constructor(init?: string[][] | Record | string | URLParams); + [Symbol.iterator](): IterableIterator<[ + string, + string + ]>; + } +} +export default url; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.LinkedList.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.LinkedList.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ba1de3c7b807d35bbe6b20347399600e1e1a6cd --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.LinkedList.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 LinkedList { + constructor(); + length: number; + add(element: T): boolean; + [Symbol.iterator](): IterableIterator; + removeFirstFound(element: T): boolean; + removeLastFound(element: T): boolean; +} +export default LinkedList; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.PlainArray.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.PlainArray.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..8eef47deb465a5fa2304701482191e3b1088e5bf --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.PlainArray.d.ts @@ -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 class PlainArray { + constructor(); + length: number; + add(key: number, value: T): void; + [Symbol.iterator](): IterableIterator<[ + number, + T + ]>; + getValueAt(index: number): T; + setValueAt(index: number, value: T): void; + forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray) => void, thisArg?: Object): void; +} +export default PlainArray; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Queue.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Queue.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..688a9e1b93e348e6641420f5c363aa12d82f6608 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Queue.d.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. + */ +declare class Queue { + constructor(); + length: number; + add(element: T): boolean; + [Symbol.iterator](): IterableIterator; +} + +export default Queue; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Stack.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Stack.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..65bdc86d2cbb2d73c2e9599d30c97ae7815a3404 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.Stack.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 class Stack { + [Symbol.iterator](): IterableIterator; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.TreeMap.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.TreeMap.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0ebb5b14af65af67106552ed41f98e817f53f71 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.TreeMap.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. + */ +declare class TreeMap{ + constructor(comparator?: (firstValue: K, secondValue: K) => boolean); +} +export default TreeMap; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.json.d.ts b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.json.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..3819fda8b6e4cc15e5df077eab7d80bbcc4d95c8 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/api/@ohos.util.json.d.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. + */ + +declare namespace json{ + type Transformer = (this: Object, key: string, value: Object) => Object | undefined | null; + function parse(text: string, reviver?: Transformer, options?: ParseOptions): Object | null; + function remove(obj: object, property: string): void; +} +export default json; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets new file mode 100644 index 0000000000000000000000000000000000000000..a60faf8956cf677096a45d5052bffec0e1c4ed27 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.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 collections from './api/@arkts.collections' + +const a: collections.Array = new collections.Array(); +const b: collections.Float32Array = new collections.Float32Array(); +const c: collections.Uint8Array = new collections.Uint8Array(); +const d: collections.Uint8ClampedArray = new collections.Uint8ClampedArray(); +const e: collections.Uint16Array = new collections.Uint16Array(); +const f: collections.Uint32Array = new collections.Uint32Array(); +const a1: collections.Array = new collections.Array("111"); +const a2: collections.Array = new collections.Array(2); +const a3: collections.Array = new collections.Array(); +let arr1 = new collections.Array(2) \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.args.json b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/collections_no_array_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/sdkcommonapi/collections_no_array_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..073ae7505a8736ea6f4d094af3532ca27ea42c39 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 8, + "endLine": 15, + "endColumn": 19, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 42, + "endLine": 17, + "endColumn": 59, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 41, + "endLine": 18, + "endColumn": 65, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 32, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 39, + "endLine": 19, + "endColumn": 61, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 46, + "endLine": 20, + "endColumn": 75, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 33, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 40, + "endLine": 21, + "endColumn": 63, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 10, + "endLine": 22, + "endColumn": 33, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 40, + "endLine": 22, + "endColumn": 63, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 11, + "endLine": 23, + "endColumn": 28, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 43, + "endLine": 23, + "endColumn": 60, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 11, + "endLine": 24, + "endColumn": 22, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 39, + "endLine": 24, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 43, + "endLine": 24, + "endColumn": 54, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 11, + "endLine": 25, + "endColumn": 28, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 39, + "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": 43, + "endLine": 25, + "endColumn": 60, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 12, + "endLine": 26, + "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": 16, + "endLine": 26, + "endColumn": 27, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.json b/ets2panda/linter/test/sdkcommonapi/collections_no_array_sdk.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/collections_no_array_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/sdkcommonapi/sdk_buffer.ets b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets new file mode 100755 index 0000000000000000000000000000000000000000..0528557176a222ab5300c34c664552c746f0b8b8 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.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 buffer from './api/@ohos.buffer' + +let blob: buffer.Blob = new buffer.Blob(['a', 'b', 'c', 'd', 'e']); +const newBlob = blob.slice(0, 2, 'MIME'); //error +const res1 = newBlob.size // 5" + +//indexOf +let buf = buffer.from([-1, 5]); +let index = buf.indexOf(""); // error +let buf1 = new buffer.Buffer().indexOf(""); // error +let index2 = buffer.from("abc").indexOf(""); // error +let buf2 = buffer.from("123"); +let buf3 = buf2; +buf3.indexOf(""); // error +let buf4 = new buffer.Buffer(); +let buf5 = buf4; +buf5.indexOf(""); // error +buf5.indexOf(); // error +buf5.indexOf(1); +buf5.indexOf('adasf'); +new buffer.Buffer().indexOf("555"); + +//sum:7 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.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/sdkcommonapi/sdk_buffer.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..bf860d819fba14861d645c4db7c2d01959b03bab --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.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": 22, + "endLine": 18, + "endColumn": 27, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"slice\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 26, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 17, + "endLine": 23, + "endColumn": 24, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 32, + "endLine": 24, + "endColumn": 39, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 33, + "endLine": 25, + "endColumn": 40, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 6, + "endLine": 28, + "endColumn": 13, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 6, + "endLine": 31, + "endColumn": 13, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 6, + "endLine": 32, + "endColumn": 13, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"indexOf\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..d4ee73858cf44a3952df70bc44a71923e42b2c24 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_buffer.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": 19, + "column": 7, + "endLine": 19, + "endColumn": 26, + "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/sdkcommonapi/sdk_index.ets b/ets2panda/linter/test/sdkcommonapi/sdk_index.ets new file mode 100755 index 0000000000000000000000000000000000000000..2f7fb4f18aeb17da2d6cf4c18a6498eed179e8d1 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_index.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. + */ + +import {Stack} from './api/@ohos.util.Stack'; +import Queue from './api/@ohos.util.Queue'; +import {LinkedList} from './api/@ohos.util.LinkedList'; +import {PlainArray} from './api/@ohos.util.PlainArray'; + +let stack = new Stack(); +stack.push(1); +const a: number = stack[0]; //error + + +let queue = new Queue(); +queue.add(1); //error +const b: number = queue[0]; //error + + +let linkedList = new LinkedList(); +linkedList.add(1); +const c: number = linkedList[0]; //error + + +let plainArray = new PlainArray(); +stack.push(1); +const d: number = plainArray[0]; //error +const d: number = plainArray[]; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_index.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_index.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_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/sdkcommonapi/sdk_index.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_index.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..1dbd86e5b7e2276cd0dee456c61b51c7329a4fe6 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_index.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": 23, + "column": 19, + "endLine": 23, + "endColumn": 27, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"Stack\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 10, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"add\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 19, + "endLine": 28, + "endColumn": 27, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"Queue\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 19, + "endLine": 33, + "endColumn": 32, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"LinkedList\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 19, + "endLine": 38, + "endColumn": 32, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"PlainArray\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_index.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_index.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..fd71430f1ea0e4fa9f4558e3f678859330eaf69c --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_index.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/sdkcommonapi/sdk_json.ets b/ets2panda/linter/test/sdkcommonapi/sdk_json.ets new file mode 100755 index 0000000000000000000000000000000000000000..d3bf617e61b92e5c27551c45c4164f50dc4eafa1 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_json.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 json from './api/@ohos.util.json' + +let obj = json.parse(''); //error +function aa(this: Object, key: string, value: Object): Object | undefined | null { + return null; +} +let obj1 = json.parse('', aa); //error +json.remove(obj, ''); //error +const uppercaseTransformer: json.Transformer = (key, value) => { //error + if (typeof value === 'string') { + return value.toUpperCase(); + } + return value; +}; +//sum:4 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_json.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_json.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_json.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/sdkcommonapi/sdk_json.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_json.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..a63da21b61d371f41b3da93bc45ec08bc3b3b0d2 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_json.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": 15, + "column": 18, + "endLine": 15, + "endColumn": 41, + "problem": "NoImportJsonFile", + "suggest": "", + "rule": "JSON files cannot be imported (arkts-no-import-json-file)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 21, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"parse\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 13, + "endLine": 18, + "endColumn": 17, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 22, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"parse\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 6, + "endLine": 22, + "endColumn": 12, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"remove\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 29, + "endLine": 23, + "endColumn": 45, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Transformer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_json.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_json.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_json.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/sdkcommonapi/sdk_list.ets b/ets2panda/linter/test/sdkcommonapi/sdk_list.ets new file mode 100755 index 0000000000000000000000000000000000000000..d7f1ecb4d39f693e6e538be76cf522830590900c --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_list.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ArrayList } from './@ohos.util.ArrayList'; +import LinkedList from './api/@ohos.util.LinkedList'; +import {PlainArray} from './api/@ohos.util.PlainArray'; +import TreeMap from './api/@ohos.util.TreeMap'; + +let linkedList: LinkedList = new LinkedList(); +linkedList.add(4); +linkedList.add(5); +linkedList.add(4); +let result = linkedList.removeFirstFound(6);//error +let result1 = linkedList.removeLastFound(6); //error + +let plainArray: PlainArray = new PlainArray(); +let result3 = plainArray.getKeyAt(-1); +let result32 = plainArray.getValueAt(-1); +let result4 = plainArray.setValueAt(-2, 0); + +let treeMap: TreeMap = + new TreeMap((firstValue: string, secondValue: string): boolean => { //error + return firstValue > secondValue + }); + +let arrayList: ArrayList = new ArrayList(); +arrayList.add("刘"); +arrayList.add("张三"); +arrayList.add(1); +arrayList.add(2); +arrayList.sort((a, b) => a - b); //error + +function fn() {console.log('Hello');} +let arrayList2: ArrayList = new ArrayList(); +arrayList2.add(2); +arrayList2.forEach((value: number, index?: number) => { //error + console.log('value:' + value, 'index:' + index); +}, fn); + +let arrayList3: ArrayList = new ArrayList(); +arrayList.add(2); +arrayList.add(4); +arrayList.replaceAllElements((value: number): number => { //error + return value; +},fn); + + +arrayList.replaceAllElements((value: number): number => { //error need fix on whitelist + return value; +}); +arrayList2.forEach((value: number, index?: number) => { //error need fix on whitelist + console.log('value:' + value, 'index:' + index); +}); +//sum:6 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_list.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_list.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_list.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/sdkcommonapi/sdk_list.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_list.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b0da5305304e6916df66d9bc20caa164387b890d --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_list.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": 21, + "column": 38, + "endLine": 21, + "endColumn": 54, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 25, + "endLine": 25, + "endColumn": 41, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"removeFirstFound\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 26, + "endLine": 26, + "endColumn": 41, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"removeLastFound\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 15, + "endLine": 31, + "endColumn": 43, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 14, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"constructor\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 11, + "endLine": 43, + "endColumn": 15, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"sort\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 19, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"forEach\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 29, + "endLine": 52, + "endColumn": 44, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 29, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"replaceAllElements\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 11, + "endLine": 60, + "endColumn": 29, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"replaceAllElements\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 12, + "endLine": 63, + "endColumn": 19, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"forEach\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 30, + "endLine": 55, + "endColumn": 66, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "rule": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 30, + "endLine": 60, + "endColumn": 88, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "rule": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_list.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_list.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..1beab63279504dbae19f0c9004587f8a2d4db693 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_list.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": 29, + "column": 5, + "endLine": 29, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 30, + "endLine": 55, + "endColumn": 66, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "rule": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 30, + "endLine": 60, + "endColumn": 88, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "rule": "Argument of type '(value: number) => number' is not assignable to parameter of type '(value: String | Number, index?: number | undefined, arrlist?: ArrayList | undefined) => String | Number'.\n Types of parameters 'value' and 'value' are incompatible.\n Type 'String | Number' is not assignable to type 'number'.\n Type 'String' is not assignable to type 'number'.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_url.ets b/ets2panda/linter/test/sdkcommonapi/sdk_url.ets new file mode 100755 index 0000000000000000000000000000000000000000..e9a14fb8067d3301f6948c9ac3bb8cce9888b27e --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_url.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. + */ +import url from './api/@ohos.url'; + +let paramsObj = new url.URLParams('aa=%E4%B8%AD%E5%9B%BD%BD'); //error +console.log(paramsObj.get('aa')) // 中国%BD console.log(paramsObj.toString()) // aa=%E4%B8%AD%E5%9B%BD%25BD" +const paramsObject1 = new url.URLSearchParams('fod=bay&edg=bap');//error +paramsObject1.append('fod', '3');//error + +let objectParams = new url.URLSearchParams([ ['user1', 'abc1'], ['query2', 'first2'], ['query3', 'second3'] ]);//error +let objectParams1 = new url.URLSearchParams({"fod" : '1' , "bard" : '2'});//error +let objectParams2 = new url.URLSearchParams('?fod=1&bard=2');//error +let urlObject1 = new url.URL('https://developer.mozilla.org/?fod=1&bard=2'); +let params1 = new url.URLSearchParams(urlObject1.search); //error*2 + +const paramsObject2 = new url.URLSearchParams('fod=bay&edg=bap');//error +paramsObject2.delete('fod');//error + +let searchParamsObject1 = new url.URLSearchParams("keyName1=valueName1&keyName2=valueName2");//error +let iter: Iterable = searchParamsObject1.entries();//error +let pairs = Array.from(iter); //BuiltinAll +for (let pair of pairs) { // Show keyName/valueName pairs + console.log(pair[0]+ ', '+ pair[1]); +} + +const myURLObject = new url.URL('https://developer.exampleUrl/?fod=1&bard=2'); +myURLObject.searchParams.forEach((value, name, searchParams) => {//error*2 + console.log(name, value, myURLObject.searchParams === searchParams);//error +}); + +let paramsObject3 = new url.URLSearchParams('name=Jonathan&age=18');//error +let name = paramsObject3.get("name"); //error +let age = paramsObject3.get("age"); //error +let getObj = paramsObject3.get("abc"); //error + +let urlObject2 = new url.URL('https://developer.exampleUrl/?fod=1&bard=2'); +let params2 = new url.URLSearchParams(urlObject2.search.slice(1));//error*2 +params2.append('fod', '3');//error +console.log(params2.getAll('fod').toString())//error +let paramsObject4 = new url.URLSearchParams(urlObject2.search.slice(1));//error*2 +paramsObject4.has('bard') === true;//error + +let searchParamsObject2 = new url.URLSearchParams("key1=value1&key2=value2"); //error +let keys = Array.from(searchParamsObject2.keys());//error+BuiltinAll +for (let key of keys) { + console.log(key); +} + +let urlObject3 = new url.URL('https://developer.exampleUrl/?fod=1&bard=2'); +let paramsObject = new url.URLSearchParams(urlObject3.search.slice(1));//error*2 +paramsObject.set('baz', '3');//error + +let searchParamsObject = new url.URLSearchParams("c=3&a=9&b=4&d=2");//error +searchParamsObject.sort(); //error +console.log(searchParamsObject.toString());//error +let urlObject = new url.URL('https://developer.exampleUrl/?fod=1&bard=2'); +let params = new url.URLSearchParams(urlObject.search.slice(1));//error*2 +params.append('fod', '3');//error +console.log(params.toString()); //error + +let searchParams = new url.URLSearchParams("key1=value1&key2=value2");//error +let values = Array.from(searchParams.values());//error+BuiltinAll +for (let value of values) { console.log(value); } + +//sum:40 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_url.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/sdkcommonapi/sdk_url.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..d538bc711d7d538c83d6ac3fa59ea70bfc51d519 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.arkts2.json @@ -0,0 +1,468 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 34, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"constructor\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 31, + "endLine": 19, + "endColumn": 46, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 15, + "endLine": 20, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 43, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 29, + "endLine": 23, + "endColumn": 44, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 29, + "endLine": 24, + "endColumn": 44, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 38, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 50, + "endLine": 26, + "endColumn": 56, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"search\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 31, + "endLine": 28, + "endColumn": 46, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 35, + "endLine": 31, + "endColumn": 50, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 52, + "endLine": 32, + "endColumn": 59, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 19, + "endLine": 33, + "endColumn": 23, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 15, + "endLine": 35, + "endColumn": 22, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 37, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 26, + "endLine": 39, + "endColumn": 33, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 13, + "endLine": 39, + "endColumn": 25, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"searchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 40, + "endLine": 40, + "endColumn": 52, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"searchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 29, + "endLine": 43, + "endColumn": 44, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 26, + "endLine": 44, + "endColumn": 29, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 25, + "endLine": 45, + "endColumn": 28, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 28, + "endLine": 46, + "endColumn": 31, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 23, + "endLine": 49, + "endColumn": 38, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 50, + "endLine": 49, + "endColumn": 56, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"search\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 9, + "endLine": 50, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 21, + "endLine": 51, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 29, + "endLine": 52, + "endColumn": 44, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 56, + "endLine": 52, + "endColumn": 62, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"search\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 15, + "endLine": 53, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 35, + "endLine": 55, + "endColumn": 50, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 18, + "endLine": 56, + "endColumn": 22, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 43, + "endLine": 56, + "endColumn": 47, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 28, + "endLine": 62, + "endColumn": 43, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 55, + "endLine": 62, + "endColumn": 61, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"search\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 14, + "endLine": 63, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 34, + "endLine": 65, + "endColumn": 49, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 20, + "endLine": 66, + "endColumn": 24, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 32, + "endLine": 67, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 22, + "endLine": 69, + "endColumn": 37, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 48, + "endLine": 69, + "endColumn": 54, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"search\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 8, + "endLine": 70, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 28, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 43, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 20, + "endLine": 74, + "endColumn": 24, + "problem": "BuiltinDisableApi", + "suggest": "", + "rule": "API has been disabled (arkts-builtin-disable-api)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 38, + "endLine": 74, + "endColumn": 44, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"url.URLSearchParams\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_url.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_url.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/sdkcommonapi/sdk_util.ets b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets new file mode 100755 index 0000000000000000000000000000000000000000..8e8394bb921caf8d24336279349ff4dbd387ea03 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets @@ -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. + */ +import util from './@ohos.util'; + +//util.Base64 +let base64 = new util.Base64(); //error +let array = new Uint8Array([99,122,69,122]); +base64.decode(array).then((val) => { //error + console.info(val.toString()); // 115,49,51 +}) +let buff = 'czEz'; +let result0 = base64.decodeSync(buff); //error +console.info("result0 = " + result0); // result = 115,49,51" + +base64.encode(array).then((val) => { //error + console.info(val.toString()); // 99,122,69,122 +}) + +let result1 = base64.encodeSync(array); //error +console.info("result1 = " + result1); // result = 99,122,69,122" + +base64.encodeToString(array).then((val) => { //error + console.info(val); // czEz +}) + +let result2 = base64.encodeToStringSync(array); //error +console.info("result2 = "+ result2); // result = czEz +//util.LruBuffer +class ChildLruBuffer extends util.LruBuffer { //error + length: number=0; //error + constructor(capacity?: number) { + super(capacity); //error + } + afterRemoval(isEvict: boolean, key: K, value: V, newValue: V): void { //error + if (isEvict === true) { + console.info('key: ' + key); // 输出结果:key: 11 + console.info('value: ' + value); // 输出结果:value: 1 + console.info('newValue: ' + newValue); // 输出结果:newValue: null + } + } + [Symbol.iterator](): IterableIterator<[ //error + K, + V + ]>{ + return <>; + } +} +class ChildLruBuffer1 extends util.LruBuffer { //error +} +let lru: ChildLruBuffer = new ChildLruBuffer(2); +lru.put(11, 1); //error +lru.put(22, 2); //error +lru.afterRemoval(false,22, 2,1); + +let lru1: ChildLruBuffer1 = new ChildLruBuffer1(2); +lru1.afterRemoval(false,22, 2,1); //error + +let pro : util.LruBuffer = new util.LruBuffer(); //error*2 +pro[Symbol.iterator](); //error +pro.afterRemoval(true,1,2,1); //error +pro.length; //error +pro.clear(); //error +let result4 = pro.contains(20); //error +console.info('result4 = ' + result4); // result = false +pro.createDefault(50); //error +pro.put(2,10); //error +pro.entries(); //error +pro.get(2); //error +pro.remove(20); //error +console.info("result = " + pro.toString()); //error +pro.updateCapacity(100); //error + +let pro3: util.LruBuffer = new util.LruBuffer(); //error*2 +pro3.put(2,10); //error +pro3.put(2,"anhu"); //error +pro3.put("afaf","grfb"); //error +let result3 = pro3.values(); //error +console.info("result3 = " + result3); // result = anhu,grfb" + +let pro4: util.LruBuffer= new util.LruBuffer(); //error*2 +pro4.put(2,10); //error +pro4.put(1,8); //error +console.info("result = " + pro4.length); //error + +//util.Scope +class ScopeDemo extends util.Scope {} //error +class Temperature implements util.ScopeComparable { + private readonly _temp: number; + constructor(value: number) { + this._temp = value; + } + compareTo(value: Temperature) { + return this._temp >= value.getTemp(); + } + getTemp() { + return this._temp; + } + toString(): string { + return this._temp.toString(); + } +} +let tempLower = new Temperature(30); +let tempUpper = new Temperature(40); +let tempMiDF = new Temperature(35); +let range = new util.Scope(tempLower, tempUpper); //error +console.info("result = " + range.clamp(tempMiDF)); //error +console.info("range = " + range); // range = [30, 40]" +let tempLess = new Temperature(20); +let tempMore = new Temperature(45); +let rangeSec = new util.Scope(tempLess, tempMore); //error +range.contains(rangeSec); //error + +let tempMiDS = new Temperature(39); +range.expand(tempMiDF, tempMiDS); //error +range.expand(range); //error +console.info("result = " + result); +range.expand(tempMiDF); //error +console.info("result = " + result); +range.getLower(); //error +range.getUpper(); //error +range.intersect(tempMiDF, tempMiDS); //error +range.intersect(range); //error +range.toString(); //error + +//sum:54 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util.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/sdkcommonapi/sdk_util.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..99f42c563fa9ca8602b8729ed9c3346814eaff8e --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.arkts2.json @@ -0,0 +1,668 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 23, + "endLine": 18, + "endColumn": 29, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 32, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 8, + "endLine": 27, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 32, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 8, + "endLine": 34, + "endColumn": 22, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 22, + "endLine": 38, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Base64\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 3, + "endLine": 52, + "endColumn": 4, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 58, + "endColumn": 4, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 3, + "endLine": 42, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 41, + "endLine": 41, + "endColumn": 50, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 4, + "endLine": 53, + "endColumn": 19, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 14, + "problem": "TypeAssertion", + "suggest": "", + "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 1, + "endLine": 61, + "endColumn": 2, + "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": 60, + "column": 42, + "endLine": 60, + "endColumn": 51, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 43, + "endLine": 62, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 8, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 8, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 45, + "endLine": 67, + "endColumn": 67, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 6, + "endLine": 68, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 11, + "endLine": 70, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 43, + "endLine": 70, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 52, + "endLine": 70, + "endColumn": 61, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 20, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 20, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"Symbol.iterator\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 10, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 19, + "endLine": 75, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 5, + "endLine": 77, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 5, + "endLine": 78, + "endColumn": 8, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 12, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 8, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 32, + "endLine": 82, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 19, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 11, + "endLine": 85, + "endColumn": 58, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 61, + "endLine": 85, + "endColumn": 81, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 70, + "endLine": 85, + "endColumn": 79, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 6, + "endLine": 86, + "endColumn": 9, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 6, + "endLine": 87, + "endColumn": 9, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 6, + "endLine": 88, + "endColumn": 9, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 20, + "endLine": 89, + "endColumn": 26, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 11, + "endLine": 92, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 42, + "endLine": 92, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 51, + "endLine": 92, + "endColumn": 60, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 6, + "endLine": 93, + "endColumn": 9, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 6, + "endLine": 94, + "endColumn": 9, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 33, + "endLine": 95, + "endColumn": 39, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.LruBuffer\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 1, + "endLine": 98, + "endColumn": 39, + "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": 98, + "column": 31, + "endLine": 98, + "endColumn": 36, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 13, + "endLine": 104, + "endColumn": 31, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 22, + "endLine": 117, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 34, + "endLine": 118, + "endColumn": 39, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 25, + "endLine": 122, + "endColumn": 30, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 7, + "endLine": 123, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 7, + "endLine": 126, + "endColumn": 13, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 7, + "endLine": 127, + "endColumn": 13, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 7, + "endLine": 129, + "endColumn": 13, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 7, + "endLine": 131, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 7, + "endLine": 132, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 7, + "endLine": 133, + "endColumn": 16, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 7, + "endLine": 134, + "endColumn": 16, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 7, + "endLine": 135, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"util.Scope\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_util.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..3b5a4f9ce58c8f1e99991d43344b3c76576b64ae --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util.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": 57, + "column": 12, + "endLine": 57, + "endColumn": 14, + "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/sdkcommonapi/sdk_util2.ets b/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets new file mode 100755 index 0000000000000000000000000000000000000000..5a08ed392d9eccd237712354ca36724f34305f76 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util2.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. + */ +import util from './@ohos.util'; + +function test(obj: Object) { + let type = new util.types(); + type.isArgumentsObject(obj); //error + type.isGeneratorFunction(obj); //error + type.isGeneratorObject(obj); //error + type.isModuleNamespaceObject(obj); //error + type.isProxy(obj); //error + type.isSymbolObject(obj); //error +} + +class A { +} + +util.Aspect.addAfter(A, 'foo', true, (str: string) => { //error +}); +util.Aspect.addBefore(A, 'foo', true, (str: string) => { //error +}); +util.Aspect.replace(A, 'foo', true, (str: string) => { //error +}); + +let base64Helper = new util.Base64Helper(); +let array = new Uint8Array([115, 49, 51]); +let result = base64Helper.encodeToStringSync(array); //error +let cache = new util.LRUCache(); //error +let result1 = cache.put(2, 10); //error +console.log('result = ' + result1); // 输出结果:result = 10 +let pro2: util.LRUCache = new util.LRUCache(); //error +let result5 = pro2.getCapacity(); //error +console.info("result5 = " + result5); +pro2.put(1, 8); //error +let result6 = pro2.getCreateCount(); //error +console.info("result6 = " + result6); +pro2.getMatchCount(); //error +pro2.get(2); +console.info("result = " + pro2.getMissCount()); //error +console.info("result = " + pro2.getPutCount()); //error +pro2.updateCapacity(2); //error +pro2.put(50, 22); //error +pro2.length; //error +pro2.getCapacity(); //error +console.info("result = " + pro2.getRemovalCount()); //error +console.info("result = " + pro2.isEmpty()); +console.info("result = " + pro2.keys()); // 输出结果:result = 2" +console.info("result = " + pro2.put(2, 10)); //error +console.info("result = " + pro2.remove(20)); +let a: number = 5; +new util.LRUCache().length; //error*2 + +let errnum = -1; +console.info("" + util.getErrorString(errnum)); //error + +let res = util.printf("\"%s\"", "hello world!"); //error +console.info(res); // 输出结果:hello world! + +async function fn() { return 'hello world'; } +const addCall = util.promiseWrapper(util.callbackWrapper(fn)); //error + +let decodeWithStreamOptions: util.DecodeWithStreamOptions = { stream: false } //error +let textDecoder1 = new util.TextDecoder("utf-8",{ignoreBOM: true}); //error + +let uint8 = new Uint8Array(6); +uint8[0] = 0xEF; +uint8[1] = 0xBB; +uint8[2] = 0xBF; +uint8[3] = 0x61; +uint8[4] = 0x62; +uint8[5] = 0x63; +console.info("input num:"); +textDecoder1.decode(uint8, {stream: false}); //error + +let textDecoderOptions: util.TextDecoderOptions = { + fatal: false, + ignoreBOM : true +} + +let textEncoder3: util.TextEncoder = new util.TextEncoder(); +let resu = textEncoder3.encode(''); //error + +let textEncoder: util.TextEncoder = new util.TextEncoder(); +let buffer = new ArrayBuffer(4); +let uint = new Uint8Array(buffer); +let result10 = textEncoder.encodeInto('', uint); //error + +//sum:35 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util2.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/sdkcommonapi/sdk_util2.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..c37e3cee93b84039f607c33c29d5020d8c4340c8 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.arkts2.json @@ -0,0 +1,448 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 8, + "endLine": 19, + "endColumn": 25, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isArgumentsObject\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 27, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isGeneratorFunction\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 25, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isGeneratorObject\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 8, + "endLine": 22, + "endColumn": 31, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isModuleNamespaceObject\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 15, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isProxy\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 8, + "endLine": 24, + "endColumn": 22, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"isSymbolObject\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 21, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"addAfter\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 22, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"addBefore\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 13, + "endLine": 34, + "endColumn": 20, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"replace\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 27, + "endLine": 39, + "endColumn": 45, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"encodeToStringSync\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 17, + "endLine": 40, + "endColumn": 30, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"constructor\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 21, + "endLine": 41, + "endColumn": 24, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"put\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 47, + "endLine": 43, + "endColumn": 60, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"constructor\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 43, + "endLine": 43, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 20, + "endLine": 44, + "endColumn": 31, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getCapacity\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 6, + "endLine": 46, + "endColumn": 9, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"put\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 20, + "endLine": 47, + "endColumn": 34, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getCreateCount\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 6, + "endLine": 49, + "endColumn": 19, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getMatchCount\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 33, + "endLine": 51, + "endColumn": 45, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getMissCount\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 33, + "endLine": 52, + "endColumn": 44, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getPutCount\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 6, + "endLine": 53, + "endColumn": 20, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"updateCapacity\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 6, + "endLine": 54, + "endColumn": 9, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"put\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 6, + "endLine": 55, + "endColumn": 12, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"length\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 6, + "endLine": 56, + "endColumn": 17, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getCapacity\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 33, + "endLine": 57, + "endColumn": 48, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"getRemovalCount\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 33, + "endLine": 60, + "endColumn": 36, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"put\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 21, + "endLine": 63, + "endColumn": 27, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"length\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 18, + "problem": "SdkCommonApiBehaviorChange", + "suggest": "", + "rule": "The \"constructor\" in SDK has been changed.(sdk-method-changed)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "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": 24, + "endLine": 66, + "endColumn": 38, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"getErrorString\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 16, + "endLine": 68, + "endColumn": 22, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"printf\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 22, + "endLine": 72, + "endColumn": 36, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"promiseWrapper\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 63, + "endLine": 74, + "endColumn": 69, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stream\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 24, + "endLine": 75, + "endColumn": 40, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"constructor\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 1, + "endLine": 78, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 1, + "endLine": 79, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 1, + "endLine": 80, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 1, + "endLine": 81, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 1, + "endLine": 82, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 1, + "endLine": 83, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 14, + "endLine": 85, + "endColumn": 20, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"decode\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 25, + "endLine": 93, + "endColumn": 31, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"encode\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 28, + "endLine": 98, + "endColumn": 38, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"encodeInto\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_util2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_util2.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/sdkcommonapi/sdk_vector.ets b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets new file mode 100755 index 0000000000000000000000000000000000000000..94be7b643e8d9d36d8e9d466d1be827991f29192 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets @@ -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 Vector from './@ohos.util.Vector'; + +let vector : Vector = new Vector(); //error +vector.add(2); //error +vector.add(4); //error +vector.add(5); //error +vector.add(4); //error +// 使用方法一: +let nums: Array = vector.convertToArray() //error +for (let item of nums) { + console.log("testLog value:" + item); +} +vector.clear(); //error +vector.add(2); //error +vector.clone(); //error +vector.add(2); //error +vector.convertToArray(); //error +vector.add(2); //error +let arr: Array = [] +vector.copyToArray(arr); //error + + +vector.add(2); //error +vector.forEach((value: number, index?: number) => { //error + console.log('value = ' + value, 'index = ' + index); +}); +vector.add(2); //error +vector.get(0); //error +vector.add(2); //error +vector.getCapacity(); //error +vector.getFirstElement(); //error +vector.getIndexFrom(2, 0); //error +vector.getIndexOf(2); //error +vector.getLastElement(); //error +vector.getLastIndexFrom(2, 0); //error +vector.getLastIndexOf(2); //error +vector.has(2); //error +vector.increaseCapacityTo(2); //error +vector.insert(2, 0); //error +vector.isEmpty(); //error +vector.remove(2); //error +vector.removeByIndex(0); //error +vector.removeByRange(0, 1); //error +vector.replaceAllElements((value: number) => { //error + return value; +}); +vector.set(0, 0); //error +vector.setLength(0); //error +vector.sort((firstValue: number, secondValue: number) => { //error + return firstValue - secondValue; +}); +vector.subVector(0, 1); //error +vector.toString(); //error +vector.trimToCurrentLength(); //error +let result = vector.length; //error +//sum:40 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_vector.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/sdkcommonapi/sdk_vector.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..936da3b8c2550e486842ab59518e8563677ff062 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.arkts2.json @@ -0,0 +1,428 @@ +{ + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 14, + "endLine": 18, + "endColumn": 28, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 31, + "endLine": 18, + "endColumn": 43, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 8, + "endLine": 19, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 8, + "endLine": 22, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 35, + "endLine": 24, + "endColumn": 49, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 13, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 8, + "endLine": 30, + "endColumn": 13, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 8, + "endLine": 31, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 22, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 8, + "endLine": 35, + "endColumn": 19, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 8, + "endLine": 38, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 8, + "endLine": 42, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 8, + "endLine": 43, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 8, + "endLine": 44, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 8, + "endLine": 45, + "endColumn": 19, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 8, + "endLine": 46, + "endColumn": 23, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 8, + "endLine": 47, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 8, + "endLine": 48, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 8, + "endLine": 49, + "endColumn": 22, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 8, + "endLine": 50, + "endColumn": 24, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 22, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 8, + "endLine": 52, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 8, + "endLine": 53, + "endColumn": 26, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 8, + "endLine": 54, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 8, + "endLine": 55, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 8, + "endLine": 56, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 8, + "endLine": 57, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 8, + "endLine": 58, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 8, + "endLine": 59, + "endColumn": 26, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 8, + "endLine": 62, + "endColumn": 11, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 8, + "endLine": 63, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 8, + "endLine": 64, + "endColumn": 12, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 8, + "endLine": 67, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 8, + "endLine": 68, + "endColumn": 16, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 8, + "endLine": 69, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 21, + "endLine": 70, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"Vector\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_vector.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_vector.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/sdkcommonapi/sdk_xml.ets b/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets new file mode 100755 index 0000000000000000000000000000000000000000..69329cb6c927ea476fb4520ccb0a5b1e204258de --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets @@ -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 convertxml from './@ohos.convertxml'; +let xml1 = ''; +let conv = new convertxml.ConvertXML(); //error +let options: convertxml.ConvertOptions = { //error + trim: false, //error + declarationKey: '', //error + instructionKey: '', //error + attributesKey: '', //error + textKey: '', //error + cdataKey: '', //error + doctypeKey: '', //error + commentKey: '', //error + parentKey: '', //error + typeKey: '', //error + nameKey: '', //error + elementsKey: '' //error +} +let result = JSON.stringify(conv.fastConvertToJSObject(xml1, options)); //error +let options2: convertxml.ConvertOptions = { //error + trim: false, //error + ignoreDeclaration: false, //error + ignoreInstruction: false, //error + ignoreAttributes: false, //error + ignoreComment: false, //error + ignoreCDATA: false, //error + ignoreDoctype: false, //error + ignoreText: false, //error + declarationKey: '', //error + instructionKey: '', //error + attributesKey: '', //error + textKey: '', //error + cdataKey: '', //error + doctypeKey: '', //error + commentKey: '', //error + parentKey: '', //error + typeKey: '', //error + nameKey: '', //error + elementsKey: '' //error +} +let opt:convertxml.ConvertXML; //error + +class Demo extends convertxml.ConvertXML implements convertxml.ConvertOptions{ //error*2 + parentKey: string; //error + typeKey: string; //error + nameKey: string; //error + elementsKey: string; //error + convert(xml: string, options?: convertxml.ConvertOptions | undefined): Object { //error*2 + } +} +//sum :44 \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets.args.json b/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_xml.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/sdkcommonapi/sdk_xml.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..84f3263b20862fcbb5d399ddb03190fe0a30c69e --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_xml.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": 17, + "column": 27, + "endLine": 17, + "endColumn": 37, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertXML\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 14, + "endLine": 18, + "endColumn": 39, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 3, + "endLine": 21, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 3, + "endLine": 27, + "endColumn": 16, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 28, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 3, + "endLine": 30, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 19, + "endLine": 32, + "endColumn": 28, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"stringify\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 19, + "endLine": 32, + "endColumn": 28, + "problem": "BuiltinNarrowTypes", + "suggest": "", + "rule": "Using narrowing of types is not allowed in this API (arkts-builtin-narrow-types)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 34, + "endLine": 32, + "endColumn": 55, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"xml.ConvertXML\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 40, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 27, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 3, + "endLine": 37, + "endColumn": 26, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 23, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 23, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 3, + "endLine": 42, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 3, + "endLine": 43, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 20, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 15, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 3, + "endLine": 47, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 3, + "endLine": 48, + "endColumn": 17, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 3, + "endLine": 49, + "endColumn": 16, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 3, + "endLine": 50, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 3, + "endLine": 51, + "endColumn": 14, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 3, + "endLine": 52, + "endColumn": 18, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 9, + "endLine": 54, + "endColumn": 30, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertXML\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 3, + "endLine": 62, + "endColumn": 4, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertXML\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 32, + "endLine": 56, + "endColumn": 42, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertXML\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 21, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 19, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 19, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 23, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 66, + "endLine": 56, + "endColumn": 80, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 34, + "endLine": 61, + "endColumn": 59, + "problem": "SdkCommonApiDeprecated", + "suggest": "", + "rule": "The \"ConvertOptions\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'parentKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'parentKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'typeKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'typeKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'nameKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'nameKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Property 'elementsKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'elementsKey' 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/sdkcommonapi/sdk_xml.ets.json b/ets2panda/linter/test/sdkcommonapi/sdk_xml.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..690a4fa56d734d5584a70c6128e8b2d6bf7ef18f --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/sdk_xml.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": 57, + "column": 3, + "endLine": 57, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'parentKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'parentKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 58, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'typeKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'typeKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 10, + "problem": "StrictDiagnostic", + "suggest": "Property 'nameKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'nameKey' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Property 'elementsKey' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'elementsKey' 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/sdkcommonapi/symbol_iterator.ets b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets new file mode 100755 index 0000000000000000000000000000000000000000..4cde50ea3696cb906e30b5fdaab79ac7ed5db29a --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.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 { ArrayList } from './@ohos.util.ArrayList' + +let arrayList = new ArrayList(); +arrayList[Symbol.iterator](); //error \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets.args.json b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..4dfa4f20174c5965ff0a03fe9745d4cece7b7efa --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/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/sdkcommonapi/symbol_iterator.ets.arkts2.json b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..5c7594199faebeada043c4b3779ec915933f0270 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.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": 11, + "endLine": 18, + "endColumn": 26, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 26, + "problem": "SdkCommonApiWhiteList", + "suggest": "", + "rule": "The \"Symbol.iterator\" in SDK is no longer supported.(sdk-method-not-supported)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets.json b/ets2panda/linter/test/sdkcommonapi/symbol_iterator.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..7633c79b6aa0073a72cf8f74a66e11dac370f619 --- /dev/null +++ b/ets2panda/linter/test/sdkcommonapi/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/sdkwhite/decl_with_duplicate_name_sdk.ets b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets index 4584cafa7b4940bab8a405ecae1f87d510783d5a..43e59da7f5025136aa713e61673f1e4908030d96 100755 --- a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets @@ -14,15 +14,11 @@ */ '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++) @@ -47,14 +43,26 @@ class TextStyleDemo2 extends TextStyle { // Error } } -let hyperlinkAttr1: HyperlinkAttribute = HyperlinkInterface; -let hyperlinkAttr2: HyperlinkAttribute = HyperlinkInterface.color(''); +let hyperlinkAttr1: HyperlinkAttribute = HyperlinkInterface; // Error +let hyperlinkAttr2: HyperlinkAttribute = HyperlinkInterface.color(''); // Error class HyperlinkTest { - prop1: HyperlinkAttribute = HyperlinkInterface; - prop2: HyperlinkAttribute = HyperlinkInterface.color(''); + prop1: HyperlinkAttribute = HyperlinkInterface; // Error + prop2: HyperlinkAttribute = HyperlinkInterface.color(''); // Error } let hyperlinkAttr3: HyperlinkAttribute; -hyperlinkAttr3 = HyperlinkInterface; -function func(x = HyperlinkInterface) { +hyperlinkAttr3 = HyperlinkInterface; // Error +function func(x = HyperlinkInterface) { // Error + +} +class A { + onBackPress: Function; + TextStyle: Function; + constructor(onBackPress: Function, TextStyle: Function) { + this.onBackPress = onBackPress; // no Error + this.TextStyle = TextStyle; // no Error + } +} +function tt(a: A) { + a.onBackPress(); } 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 index 307e9a28a600465c8174974ff51b52c609c700c3..b41be47d2ad5875650537a6bbcec26e96e8846f8 100644 --- 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 @@ -1,278 +1,288 @@ { - "copyright": [ - "Copyright (c) 2025 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "result": [ - { - "line": 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": 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" - } - ] + "copyright": [ + "Copyright (c) 2025 Huawei Device Co., Ltd.", + "Licensed under the Apache License, Version 2.0 (the 'License');", + "you may not use this file except in compliance with the License.", + "You may obtain a copy of the License at", + "", + "http://www.apache.org/licenses/LICENSE-2.0", + "", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an 'AS IS' BASIS,", + "WITHOUT WARRANTIES OR 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": 35, + "endLine": 20, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 44, + "endLine": 22, + "endColumn": 49, + "problem": "BuiltinNewCtor", + "suggest": "", + "rule": "API is not support initial ctor signature (arkts-builtin-new-cotr)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 40, + "endLine": 22, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 31, + "endLine": 25, + "endColumn": 40, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 37, + "problem": "ParameterType", + "suggest": "", + "rule": "Type of parameter must be defined explicitly (arkts-require-func-arg-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 16, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Component\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 35, + "endLine": 20, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 57, + "endLine": 20, + "endColumn": 62, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Color\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 4, + "endLine": 22, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"State\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 36, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 31, + "endLine": 25, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ForEach\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 38, + "endLine": 30, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 32, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 30, + "endLine": 40, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"TextStyle\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 21, + "endLine": 46, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HyperlinkAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 21, + "endLine": 47, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HyperlinkAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 10, + "endLine": 49, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HyperlinkAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HyperlinkAttribute\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 21, + "endLine": 52, + "endColumn": 39, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"HyperlinkAttribute\" should be imported before it is used (arkui-modular-interface)", + "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 index 489a1474b5a6f1db71bdf86fbf3b06b773ea21c8..4e18966ecf9476bb11e1fa1f33245984342a792d 100755 --- a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json @@ -15,33 +15,13 @@ ], "result": [ { - "line": 17, - "column": 1, - "endLine": 17, - "endColumn": 61, - "problem": "ImportAfterStatement", + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 37, + "problem": "AnyType", "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.", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" } ] 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 index 36517426284632aa6afae10ce61b059b3a06d55d..6ae45b584b0226c9dc360d16145bbaae828280ff 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json @@ -44,6 +44,16 @@ "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, + { + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 46, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 22, "column": 26, @@ -54,6 +64,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 28, + "endLine": 41, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 41, "column": 28, @@ -64,6 +84,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 45, + "column": 29, + "endLine": 45, + "endColumn": 49, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 45, "column": 29, diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets index 4592f1a4799a13d1597042fb3e9c3ffc11598285..5eca858a48d2a573d043d956bd8db13ab393195e 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets @@ -58,4 +58,14 @@ function prefetchTest2(){ } export const res = new MyDataSource().cancel(222); //report error -export const res2 = ds.cancel(222); //report error \ No newline at end of file +export const res2 = ds.cancel(222); //report error + +interface BackPressInterceptor { + onBackPress: ()=> boolean | void; +} + +class A implements BackPressInterceptor{ + onBackPress() : boolean | void { + return false; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json index 2a4a3080f09475df9e522b26254c5f2860f36a2c..9f578dbed861407f9d4815e3f292573abe388c7d 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json @@ -24,16 +24,6 @@ "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, @@ -94,6 +84,16 @@ "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 28, "column": 28, @@ -104,6 +104,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 32, + "column": 26, + "endLine": 32, + "endColumn": 46, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 32, "column": 26, @@ -154,6 +164,46 @@ "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", "severity": "ERROR" }, + { + "line": 68, + "column": 3, + "endLine": 70, + "endColumn": 4, + "problem": "MethodOverridingField", + "suggest": "", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 31, + "endLine": 64, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 19, + "endLine": 68, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 29, + "endLine": 68, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 44, "column": 41, @@ -161,7 +211,7 @@ "endColumn": 59, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"DataChangeListener\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" }, { @@ -171,7 +221,7 @@ "endColumn": 61, "problem": "UIInterfaceImport", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "The ArkUI interface \"DataChangeListener\" should be imported before it is used (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets index e05617b2ffb84ecbd04c71f0dc7b94f63b0f1138..d7922e5530f0b559ca570e8f25ea707edf6464cf 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { rcp } from '@kit.RemoteCommunicationKit'; +import mainRcp,{ rcp } from '@kit.RemoteCommunicationKit'; class LI implements rcp.WriteFile{ write(buffer: ArrayBuffer): Promise { // Error throw new Error('Method not implemented.'); @@ -41,4 +41,16 @@ export class LocalDataSource implements IDataSourcePrefetching { cancel(index: number): void | Promise { throw new Error("LocalDataSource Method not implemented."); } +} + +class L3 implements mainRcp.WriteFile { + write(buffer: ArrayBuffer): Promise { // error + throw new Error('Method not implemented.'); + } +} + +class L4 implements rcp.WriteFile { + write(buffer: ArrayBuffer): Promise { // error + throw new Error('Method not implemented.'); + } } \ No newline at end of file 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 index 5d0e2d9cb631c646033d268395725ece2391e0d6..ab0cf4ecd5c92fd1dd761b877acf0948618a2e13 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json @@ -24,16 +24,6 @@ "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, @@ -94,6 +84,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 37, "column": 28, @@ -104,6 +104,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 46, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 41, "column": 26, @@ -113,6 +123,46 @@ "suggest": "", "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" + }, + { + "line": 47, + "column": 3, + "endLine": 49, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 48, + "endLine": 47, + "endColumn": 52, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 55, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 48, + "endLine": 53, + "endColumn": 52, + "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/literal_as_property_name_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json index aafa0c6dae965cc263d030a379c4a0c741e7e03a..e912f222acdacc33add98dbc94ee38e01d5ab30e 100644 --- a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json @@ -24,16 +24,6 @@ "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": 18, - "column": 3, - "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": 19, "column": 3, @@ -44,16 +34,6 @@ "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": 3, - "endLine": 19, - "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": 24, "column": 5, @@ -64,16 +44,6 @@ "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": 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": 25, "column": 5, @@ -84,16 +54,6 @@ "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": 25, - "column": 5, - "endLine": 25, - "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": 26, "column": 5, @@ -104,16 +64,6 @@ "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, - "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": 27, "column": 5, @@ -123,16 +73,6 @@ "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": 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" } ] } \ 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 index ca88f857e960b437dcf767c0ac40be998c8f1236..eccbe37c0fbc370725ec85d57b10e880e9a5018a 100644 --- a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json @@ -13,5 +13,66 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 18, + "column": 3, + "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": 19, + "column": 3, + "endLine": 19, + "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": 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": 25, + "column": 5, + "endLine": 25, + "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": 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": 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" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json index 3a348d3c8350c18237159008eeb22f282ceceb46..2d9b41b9926c40eb497baf12cfa69b478940fa0e 100644 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json @@ -24,16 +24,6 @@ "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": 29, - "column": 5, - "endLine": 29, - "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": 37, "column": 3, @@ -44,16 +34,6 @@ "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": 37, - "column": 3, - "endLine": 37, - "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": 38, "column": 3, @@ -64,16 +44,6 @@ "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": 38, - "column": 3, - "endLine": 38, - "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": 43, "column": 5, @@ -84,16 +54,6 @@ "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": 43, - "column": 5, - "endLine": 43, - "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": 44, "column": 5, @@ -104,16 +64,6 @@ "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": 44, - "column": 5, - "endLine": 44, - "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": 45, "column": 5, @@ -124,16 +74,6 @@ "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": 20, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 46, "column": 5, @@ -144,16 +84,6 @@ "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": 46, - "column": 5, - "endLine": 46, - "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": 50, "column": 10, @@ -174,16 +104,6 @@ "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": 56, - "column": 3, - "endLine": 56, - "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": 57, "column": 3, @@ -194,16 +114,6 @@ "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": 57, - "column": 3, - "endLine": 57, - "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": 58, "column": 3, @@ -214,16 +124,6 @@ "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": 3, - "endLine": 58, - "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": 59, "column": 3, @@ -234,16 +134,6 @@ "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": 59, - "column": 3, - "endLine": 59, - "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": 60, "column": 3, @@ -254,16 +144,6 @@ "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": 60, - "column": 3, - "endLine": 60, - "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": 61, "column": 3, @@ -274,16 +154,6 @@ "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": 61, - "column": 3, - "endLine": 61, - "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": 62, "column": 3, @@ -294,16 +164,6 @@ "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": 62, - "column": 3, - "endLine": 62, - "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": 67, "column": 3, @@ -314,36 +174,6 @@ "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": 67, - "column": 3, - "endLine": 67, - "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": 80, - "column": 7, - "endLine": 80, - "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": 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, @@ -384,6 +214,16 @@ "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": 13, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, { "line": 114, "column": 3, @@ -404,16 +244,6 @@ "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": 115, - "column": 5, - "endLine": 115, - "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": 125, "column": 31, @@ -424,6 +254,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 20, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, { "line": 126, "column": 12, @@ -444,16 +284,6 @@ "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": 149, "column": 3, @@ -464,16 +294,6 @@ "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": 149, - "column": 3, - "endLine": 149, - "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": 150, "column": 3, @@ -484,16 +304,6 @@ "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": 150, - "column": 3, - "endLine": 150, - "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": 151, "column": 3, @@ -504,16 +314,6 @@ "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": 151, - "column": 3, - "endLine": 151, - "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": 152, "column": 3, @@ -525,13 +325,13 @@ "severity": "ERROR" }, { - "line": 152, + "line": 159, "column": 3, - "endLine": 152, + "endLine": 159, "endColumn": 21, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -544,16 +344,6 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, - { - "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, @@ -574,6 +364,16 @@ "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", "severity": "ERROR" }, + { + "line": 179, + "column": 5, + "endLine": 179, + "endColumn": 20, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, { "line": 178, "column": 3, @@ -585,13 +385,13 @@ "severity": "ERROR" }, { - "line": 179, + "line": 183, "column": 5, - "endLine": 179, - "endColumn": 20, - "problem": "LiteralAsPropertyName", + "endLine": 183, + "endColumn": 13, + "problem": "ObjectLiteralKeyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", "severity": "ERROR" }, { @@ -614,16 +414,6 @@ "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": 183, - "column": 5, - "endLine": 183, - "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": 193, "column": 33, @@ -634,6 +424,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 23, + "problem": "ObjectLiteralKeyType", + "suggest": "", + "rule": "Use string-literal keys with Record (arkts-obj-literal-key-type)", + "severity": "ERROR" + }, { "line": 194, "column": 12, @@ -653,16 +453,6 @@ "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": 195, - "column": 5, - "endLine": 195, - "endColumn": 23, - "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_sdk.ets.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json index eaeaa7697684c7a6a6ecffddcb301018911f035e..17ed9e4363fca09b6ecd4a87b3ab113ec66be126 100755 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json @@ -14,6 +14,76 @@ "limitations under the License." ], "result": [ + { + "line": 29, + "column": 5, + "endLine": 29, + "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": 37, + "column": 3, + "endLine": 37, + "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": 38, + "column": 3, + "endLine": 38, + "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": 43, + "column": 5, + "endLine": 43, + "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": 44, + "column": 5, + "endLine": 44, + "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": 45, + "column": 5, + "endLine": 45, + "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": 46, + "column": 5, + "endLine": 46, + "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": 50, "column": 10, @@ -24,6 +94,106 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, + { + "line": 56, + "column": 3, + "endLine": 56, + "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": 57, + "column": 3, + "endLine": 57, + "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": 58, + "column": 3, + "endLine": 58, + "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": 59, + "column": 3, + "endLine": 59, + "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": 60, + "column": 3, + "endLine": 60, + "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": 61, + "column": 3, + "endLine": 61, + "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": 62, + "column": 3, + "endLine": 62, + "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": 67, + "column": 3, + "endLine": 67, + "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": 80, + "column": 7, + "endLine": 80, + "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": 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, @@ -74,6 +244,16 @@ "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": 13, + "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": 31, @@ -94,6 +274,56 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "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": 149, + "column": 3, + "endLine": 149, + "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": 150, + "column": 3, + "endLine": 150, + "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": 151, + "column": 3, + "endLine": 151, + "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": 152, + "column": 3, + "endLine": 152, + "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": 158, "column": 70, @@ -104,6 +334,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "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, @@ -134,6 +374,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "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": 182, "column": 3, @@ -144,6 +394,16 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 183, + "column": 5, + "endLine": 183, + "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": 193, "column": 33, @@ -163,6 +423,16 @@ "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" + }, + { + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 23, + "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.arkts2.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json index f2d125c5784100f6d7f32f00cfe38427f50a997b..56c2ae04205439d81632839b6fc2abc08ee228a1 100755 --- 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 @@ -15,40 +15,30 @@ ], "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, + "line": 42, + "column": 10, + "endLine": 42, "endColumn": 20, - "problem": "LiteralAsPropertyName", + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 73, - "column": 3, - "endLine": 73, - "endColumn": 15, - "problem": "LiteralAsPropertyName", + "line": 48, + "column": 20, + "endLine": 48, + "endColumn": 30, + "problem": "RuntimeArrayCheck", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Array bound not checked. (arkts-runtime-array-check)", "severity": "ERROR" }, { - "line": 74, - "column": 3, - "endLine": 74, - "endColumn": 36, + "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)", @@ -58,10 +48,10 @@ "line": 74, "column": 3, "endLine": 74, - "endColumn": 16, - "problem": "LiteralAsPropertyName", + "endColumn": 36, + "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" }, { @@ -74,16 +64,6 @@ "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, @@ -94,16 +74,6 @@ "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, @@ -124,16 +94,6 @@ "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, @@ -144,16 +104,6 @@ "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, @@ -164,16 +114,6 @@ "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, @@ -184,16 +124,6 @@ "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, @@ -204,16 +134,6 @@ "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, @@ -224,16 +144,6 @@ "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, @@ -244,16 +154,6 @@ "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, @@ -264,16 +164,6 @@ "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, @@ -284,26 +174,6 @@ "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, @@ -313,16 +183,6 @@ "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 index fe966ab865f8e5a1816ebf8e86731c56e1a9d321..4715ee64ddc7d3ec47ac851790203b2ff678976d 100755 --- a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json @@ -14,6 +14,56 @@ "limitations under the License." ], "result": [ + { + "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": 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": 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": 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, @@ -23,6 +73,116 @@ "suggest": "", "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "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": 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": 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": 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": 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": 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": 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": 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": 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": 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/return_new_interface.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json index 92f597960e2eead0bfad0cdde65d9981dff2b182..9245dba0a11bbaf806692701835f36a58b3f051b 100644 --- a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json @@ -44,16 +44,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 26, - "column": 14, - "endLine": 26, - "endColumn": 15, - "problem": "ConstructorIface", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 26, "column": 14, @@ -74,16 +64,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 30, - "column": 14, - "endLine": 30, - "endColumn": 15, - "problem": "ConstructorIface", - "suggest": "", - "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", - "severity": "ERROR" - }, { "line": 30, "column": 14, @@ -95,4 +75,4 @@ "severity": "ERROR" } ] -} \ 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 index c50d5885dafbfff29cadcffe094db980bf764b07..d14c65ae1c861531b81503aa00cd20018f660386 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets @@ -13,8 +13,30 @@ * limitations under the License. */ -import {cloudDatabase} from '@hms.core.deviceCloudGateway.cloudDatabase'; +import cloudDatabase from '@hms.core.deviceCloudGateway.cloudDatabase'; class Test extends cloudDatabase.DatabaseObject{ - + query = new cloudDatabase.DatabaseQuery(Test); //Error + equalTo(){ + return this.query.equalTo('test',''); + } } -new cloudDatabase.DatabaseQuery(Test); // NOT OK \ No newline at end of file +const localQuery = new cloudDatabase.DatabaseQuery(Test); //Error +class LocalDatabaseQuery extends cloudDatabase.DatabaseQuery{ //Error + query = new cloudDatabase.DatabaseQuery(Test); //Error + set(query:cloudDatabase.DatabaseQuery){ //Error + query.equalTo('test',''); + } + getTypeQuery(): cloudDatabase.DatabaseQuery { //Error + typeof new cloudDatabase.DatabaseQuery(Test); //Error + return new cloudDatabase.DatabaseQuery(Test); //Error + } + getEqual(){ + this.query = new Test().equalTo(); //Error? + } + +} +function useDatabaseQuery1(query:cloudDatabase.DatabaseQuery){ //Error + console.log(' '+new cloudDatabase.DatabaseQuery(Test)); //Error +} +class DatabaseQuery{} +new DatabaseQuery(); \ 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 index 745ab994b23232173122f6924c1d6ca84dd291a9..0356091ac5abbd0faa46843c6a1c1ccd785e8d1a 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json @@ -15,20 +15,200 @@ ], "result": [ { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 32, + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 49, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 29, + "endLine": 18, + "endColumn": 42, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 10, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 25, + "endLine": 23, + "endColumn": 52, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 39, + "endLine": 23, + "endColumn": 52, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 48, + "endLine": 24, + "endColumn": 61, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 49, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 42, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 29, + "endLine": 25, + "endColumn": 42, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 27, + "endLine": 26, + "endColumn": 40, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 33, + "endLine": 29, + "endColumn": 46, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 16, + "endLine": 30, + "endColumn": 43, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 30, + "endLine": 30, + "endColumn": 43, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 16, + "endLine": 31, + "endColumn": 43, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 30, + "endLine": 31, + "endColumn": 43, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 48, + "endLine": 38, + "endColumn": 61, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 23, + "endLine": 39, + "endColumn": 50, "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, + "line": 39, + "column": 37, + "endLine": 39, + "endColumn": 50, "problem": "ConstructorTypesDeprecated", "suggest": "", "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json index 9f305c86d7ff705098b1e480818e125d5e6e3a4a..7cf57b141b3d43579fa1e172817e76e9f78133aa 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json @@ -13,5 +13,46 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 49, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 10, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 49, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] } diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json index 67a42975bf378b67bc2de3e51dd05fa085910e55..7053b9055fcfce3cb3c06c48e3e8005c16d70500 100755 --- a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json @@ -174,6 +174,16 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 44, + "column": 17, + "endLine": 44, + "endColumn": 19, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, { "line": 48, "column": 14, diff --git a/ets2panda/linter/test/taskpool/taskpool_execute.ets b/ets2panda/linter/test/taskpool/taskpool_execute.ets new file mode 100644 index 0000000000000000000000000000000000000000..f50a174b039814a7cd4ee8976a68b3c6c86e65aa --- /dev/null +++ b/ets2panda/linter/test/taskpool/taskpool_execute.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 printArgs(args: number): number { + console.info(""printArgs: "" + args); + return args; +} + +taskpool.execute<[number], number>(printArgs, 100).then((value: number) => { + console.info(""taskpool result: "" + value); +}); + diff --git a/ets2panda/linter/test/taskpool/taskpool_execute.ets.args.json b/ets2panda/linter/test/taskpool/taskpool_execute.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/taskpool/taskpool_execute.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/taskpool/taskpool_execute.ets.arkts2.json b/ets2panda/linter/test/taskpool/taskpool_execute.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2b96bc02fd880a506bdbccfeb52c134c4d985986 --- /dev/null +++ b/ets2panda/linter/test/taskpool/taskpool_execute.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": 21, + "column": 18, + "endLine": 21, + "endColumn": 26, + "problem": "NotSupportTupleGenericValidation", + "suggest": "", + "rule": "Tuple type cannot be used in generic type parameters (arkts-not-support-tuple-generic-validation)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/taskpool/taskpool_execute.ets.json b/ets2panda/linter/test/taskpool/taskpool_execute.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/taskpool/taskpool_execute.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/webpack.config.js b/ets2panda/linter/webpack.config.js index 15ee37c29b5dc1cf0dd3e6ae4468a81a5e4a514d..2a15b2bfd7b53dbdaf9a1c268ff5abb4e8962a01 100644 --- a/ets2panda/linter/webpack.config.js +++ b/ets2panda/linter/webpack.config.js @@ -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 @@ -17,7 +17,7 @@ let path = require('path'); module.exports = { mode: 'development', - target: 'node', + target: 'node', entry: './build/cli/main.js', externalsType: 'commonjs', externals: { diff --git a/ets2panda/lsp/BUILD.gn b/ets2panda/lsp/BUILD.gn index 08ec8fd1b92d23d9ca5553625bcff7ca53b1dc1a..2e6655e584d43f917131854284db867fe709ca9a 100644 --- a/ets2panda/lsp/BUILD.gn +++ b/ets2panda/lsp/BUILD.gn @@ -11,7 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/runtime_core/static_core/ark_config.gni") +if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + import("//arkcompiler/runtime_core/static_core/ark_config.gni") +} else { + import( + "//build/config/components/runtime_core/static_core/ark_common_config.gni") +} if (ark_standalone_build) { import("$build_root/ark.gni") @@ -41,34 +47,101 @@ 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_name_or_dotted_name_span.cpp", + "src/get_node.cpp", + "src/get_safe_delete_info.cpp", + "src/get_signature.cpp", + "src/inlay_hints.cpp", "src/internal_api.cpp", + "src/isolated_declaration.cpp", "src/line_column_offset.cpp", + "src/navigate_to.cpp", + "src/node_matchers.cpp", + "src/organize_imports.cpp", "src/quick_info.cpp", + "src/refactor_provider.cpp", + "src/refactors/convert_chain.cpp", + "src/refactors/convert_export.cpp", + "src/refactors/convert_function.cpp", + "src/refactors/convert_import.cpp", + "src/refactors/convert_template.cpp", + "src/refactors/refactor_types.cpp", "src/references.cpp", + "src/register_code_fix/add_local_variable.cpp", + "src/register_code_fix/add_missing_declare_property.cpp", + "src/register_code_fix/add_missing_new_operator.cpp", + "src/register_code_fix/add_name_to_nameless_parameter.cpp", + "src/register_code_fix/constructor_for_derived_need_super_call.cpp", + "src/register_code_fix/convert_const_to_let.cpp", + "src/register_code_fix/fix_add_function_return_statement.cpp", + "src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp", + "src/register_code_fix/fix_class_incorrectly_implements_interface.cpp", + "src/register_code_fix/fix_class_super_must_precede_this_access.cpp", + "src/register_code_fix/fix_expected_comma.cpp", + "src/register_code_fix/fix_extends_interface_becomes_implements.cpp", + "src/register_code_fix/fix_import_non_exported_member.cpp", + "src/register_code_fix/fix_missing_call_parantheses.cpp", + "src/register_code_fix/fix_nan_equality.cpp", + "src/register_code_fix/fix_remove_override_modifier.cpp", + "src/register_code_fix/fix_return_type_in_async_function.cpp", + "src/register_code_fix/fix_unreachable_code.cpp", + "src/register_code_fix/forgotten_this_property_access.cpp", + "src/register_code_fix/import_fixes.cpp", + "src/register_code_fix/remove_accidental_call_parentheses.cpp", + "src/register_code_fix/ui_plugin_suggest.cpp", "src/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 = [ + if ((defined(ark_standalone_build) && ark_standalone_build) || + (defined(ark_static_standalone_build) && ark_static_standalone_build)) { + configs = [ "$ark_root:ark_config" ] + } else { + configs = [ + "//build/config/components/runtime_core/static_core:ark_common_config", + ] + } + configs += [ "$ark_root/assembler:arkassembler_public_config", - "$ark_root:ark_config", "../:libes2panda_public_config", "../:libes2panda_config", "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", + "$ark_root/libarkfile:arkfile_public_config", ":libes2panda_lsp_config", ] deps = [ + "../:es2panda_lsp_code_fix_register_gen_code_fix_register_h", "../:libes2panda_frontend_static", "../:libes2panda_public_frontend_static", ] diff --git a/ets2panda/lsp/CMakeLists.txt b/ets2panda/lsp/CMakeLists.txt index f242fbb8762e38f7fd18047d86dfb536cdc49655..97b269d5fe8c664eeb6b24d2bdc7e671262a0f81 100644 --- a/ets2panda/lsp/CMakeLists.txt +++ b/ets2panda/lsp/CMakeLists.txt @@ -11,28 +11,137 @@ # See the License for the specific language governing permissions and # limitations under the License. +function(panda_code_fix_gen) + set(singlevalues SOURCE DESTINATION TARGET_NAME) + set(multivalues DATA TEMPLATES REQUIRES EXTRA_DEPENDENCIES EXTRA_ARGV) + cmake_parse_arguments( + CODE_FIX_GEN_ARG + "" + "${singlevalues}" + "${multivalues}" + ${ARGN} + ) + list(LENGTH CODE_FIX_GEN_ARG_DATA DATA_COUNT) + set(CODE_FIX_API "${ES2PANDA_ROOT}/lsp/code_fix_register.rb") + foreach(i RANGE 1 ${DATA_COUNT}) + list(APPEND API_LIST ${CODE_FIX_API}) + endforeach() + + panda_gen(DATA ${CODE_FIX_GEN_ARG_DATA} + API ${API_LIST} + TEMPLATES ${CODE_FIX_GEN_ARG_TEMPLATES} + SOURCE ${CODE_FIX_GEN_ARG_SOURCE} + TARGET_NAME ${CODE_FIX_GEN_ARG_TARGET_NAME} + DESTINATION ${CODE_FIX_GEN_ARG_DESTINATION} + REQUIRES ${CODE_FIX_GEN_ARG_REQUIRES} + EXTRA_DEPENDENCIES ${CODE_FIX_GEN_ARG_EXTRA_DEPENDENCIES} + ) +endfunction() + +set(DIAGNOSTIC_DIR + ${ES2PANDA_ROOT}/util/diagnostic/ +) + +panda_code_fix_gen( + DATA + ${DIAGNOSTIC_DIR}/syntax.yaml + ${DIAGNOSTIC_DIR}/semantic.yaml + ${DIAGNOSTIC_DIR}/warning.yaml + ${DIAGNOSTIC_DIR}/fatal.yaml + ${ES2PANDA_ROOT}/declgen_ets2ts/declgen_ets2ts_error.yaml + ${ES2PANDA_ROOT}/declgen_ets2ts/declgen_ets2ts_warning.yaml + ${ES2PANDA_ROOT}/declgen_ets2ts/isolated_declgen.yaml + ${DIAGNOSTIC_DIR}/arktsconfig_error.yaml + TARGET_NAME es2panda_code_fix_register_gen + TEMPLATES code_fix_register.h.erb + SOURCE ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION ${GENERATED_DIR} +) + 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/refactors/refactor_types.cpp + ./src/applicable_refactors.cpp + ./src/refactor_provider.cpp + ./src/refactors/convert_chain.cpp + ./src/refactors/convert_export.cpp + ./src/refactors/convert_function.cpp + ./src/refactors/convert_import.cpp + ./src/refactors/convert_template.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_local_variable.cpp + ./src/register_code_fix/add_missing_new_operator.cpp + ./src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp + ./src/register_code_fix/fix_expected_comma.cpp + ./src/register_code_fix/fix_extends_interface_becomes_implements.cpp + ./src/register_code_fix/fix_class_super_must_precede_this_access.cpp + ./src/register_code_fix/fix_return_type_in_async_function.cpp + ./src/register_code_fix/add_name_to_nameless_parameter.cpp + ./src/register_code_fix/add_missing_declare_property.cpp + ./src/register_code_fix/convert_const_to_let.cpp + ./src/register_code_fix/constructor_for_derived_need_super_call.cpp + ./src/register_code_fix/fix_missing_call_parantheses.cpp + ./src/register_code_fix/fix_import_non_exported_member.cpp + ./src/register_code_fix/fix_nan_equality.cpp + ./src/register_code_fix/forgotten_this_property_access.cpp + ./src/register_code_fix/import_fixes.cpp + ./src/register_code_fix/remove_accidental_call_parentheses.cpp + ./src/register_code_fix/fix_remove_override_modifier.cpp + ./src/register_code_fix/fix_add_function_return_statement.cpp + ./src/register_code_fix/ui_plugin_suggest.cpp + ./src/register_code_fix/fix_spelling.cpp + ./src/register_code_fix/fix_class_incorrectly_implements_interface.cpp + ./src/get_signature.cpp + ./src/register_code_fix/fix_unreachable_code.cpp + ./src/get_name_or_dotted_name_span.cpp + ./src/get_node.cpp + ./src/node_matchers.cpp ) -panda_add_library(${LSP_LIB} SHARED ${ES2PANDA_LSP_SRC}) +panda_frontend_add_library(${LSP_LIB} SHARED ${ES2PANDA_LSP_SRC}) +add_dependencies(${LSP_LIB} es2panda_code_fix_register_gen) +add_dependencies(frontend_bins ${LSP_LIB}) panda_target_include_directories(${LSP_LIB} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -41,7 +150,7 @@ panda_target_include_directories(${LSP_LIB} ) panda_target_compile_options(${LSP_LIB} - PRIVATE -fexceptions -Werror=shadow + PRIVATE -fexceptions -Werror=shadow -Wno-return-type-c-linkage ) panda_target_link_libraries(${LSP_LIB} @@ -51,3 +160,4 @@ panda_target_link_libraries(${LSP_LIB} panda_add_sanitizers(TARGET ${LSP_LIB} SANITIZERS ${PANDA_SANITIZERS_LIST}) + diff --git a/ets2panda/lsp/code_fix_register.h.erb b/ets2panda/lsp/code_fix_register.h.erb new file mode 100644 index 0000000000000000000000000000000000000000..775aad1d81799ebebb534ab33a46f8daf3967b56 --- /dev/null +++ b/ets2panda/lsp/code_fix_register.h.erb @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Autogenerated file -- DO NOT EDIT! + +#ifndef ES2PANDA_LSP_CODE_FIX_KIND_H +#define ES2PANDA_LSP_CODE_FIX_KIND_H + +#include "util/diagnostic.h" +#include + +namespace ark::es2panda::lsp::codefixes { + +class DiagnosticCode { +public: + /** + * Need a numeric type error code to send to the IDE. So, using 'DIAGNOSTIC_CODE_ULTIPLIER*diagnosticType+id' to + * calculate it. Now all the 'id' are below 1000, so set the multiplier as 1000. + */ + static constexpr int DIAGNOSTIC_CODE_MULTIPLIER = 1000; + + constexpr DiagnosticCode(util::DiagnosticType type, int id, std::string_view message) + : type_(type), id_(id), message_(message) {} + + constexpr int GetCodeNumber() const + { + return (static_cast(type_) * DIAGNOSTIC_CODE_MULTIPLIER + id_); + } + + constexpr std::string_view GetMessage() const + { + return message_; + } + + constexpr bool operator==(const DiagnosticCode &other) const + { + return GetCodeNumber() == other.GetCodeNumber(); + } + + constexpr bool operator!=(const DiagnosticCode &other) const + { + return !(*this == other); + } + +private: + util::DiagnosticType type_; + int id_; + std::string_view message_; +}; + +template +class CodeFixKind { +public: + constexpr CodeFixKind(std::array codes, const std::string_view id) + : diagnosticCodes_(codes), codeFixId_(id) + { + } + + constexpr const std::array &GetSupportedCodes() const + { + return diagnosticCodes_; + } + + constexpr std::array GetSupportedCodeNumbers() const + { + std::array codeNumbers {}; + for (size_t i = 0; i < N; ++i) { + codeNumbers[i] = diagnosticCodes_[i].GetCodeNumber(); + } + return codeNumbers; + } + + constexpr std::string_view GetFixId() const + { + return codeFixId_; + } + +private: + std::array diagnosticCodes_; + std::string_view codeFixId_; +}; + +% CodeFixRegister::codefix_map.each do |code_fix_id, diag_vec| +static constexpr CodeFixKind<<%= diag_vec.size %>> <%= code_fix_id.snakecase.upcase %> { + std::array> { +% diag_vec.each_with_index do |diag, index| + DiagnosticCode(util::DiagnosticType::<%= diag.type.to_s.upcase %>, <%= diag.id %>, "<%= diag.message %>")<%= ',' unless index == diag_vec.size - 1 %> +% end + }, + "<%= code_fix_id %>" +}; +% end + +} // namespace ark::es2panda::lsp::codefixes + +#endif // ES2PANDA_LSP_CODE_FIX_KIND_H diff --git a/ets2panda/lsp/code_fix_register.rb b/ets2panda/lsp/code_fix_register.rb new file mode 100644 index 0000000000000000000000000000000000000000..f400419942b71a5dc89b0c83eec2a36f85bda9d0 --- /dev/null +++ b/ets2panda/lsp/code_fix_register.rb @@ -0,0 +1,68 @@ +#!/usr/bin/env ruby +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'ostruct' +require 'set' +require 'delegate' + +module CodeFixRegister + @codefix_map = Hash.new { |h, k| h[k] = [] } + + class DiagnosticCode + attr_reader :type, :id, :message + + def initialize(type, id, message) + @type = type + @id = id + @message = message + end + end + + class << self + def codefix_map + @codefix_map + end + + def collect_code_fix(diagnostic) + diagnostic.code_fix_ids.each do |code_fix_id| + @codefix_map[code_fix_id] << DiagnosticCode.new(diagnostic.type, diagnostic.id, diagnostic.message) + end + end + + def wrap_data(data) + data.each_pair do |diagnostic_type, diagnostics| + diagnostics.each do |diagnostic| + if diagnostic.respond_to?(:code_fix_ids) + diagnostic.type = diagnostic_type + collect_code_fix(diagnostic) + end + end + end + end + end +end + +class String + def snakecase + self.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end +end + +def Gen.on_require(data) + CodeFixRegister.wrap_data(data) +end \ No newline at end of file diff --git a/ets2panda/lsp/include/api.h b/ets2panda/lsp/include/api.h index d6fe06bc3984c8b040f1c72447675516f73b4500..9f395859f4263b86468edf8df0872a6f5e9d531e 100644 --- a/ets2panda/lsp/include/api.h +++ b/ets2panda/lsp/include/api.h @@ -25,17 +25,34 @@ #include #include #include +#include "ir/astNode.h" #include "line_column_offset.h" #include "public/es2panda_lib.h" #include "cancellation_token.h" +#include "user_preferences.h" +#include "class_hierarchies.h" #include "find_references.h" #include "find_rename_locations.h" +#include "class_hierarchy_info.h" #include "completions.h" +#include "refactors/refactor_types.h" +#include "applicable_refactors.h" +#include "rename.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 +73,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 +201,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 - { - return text_; - } - std::string GetKind() const +struct FieldsInfo { + std::string name; + std::vector properties; + bool operator<(const FieldsInfo &other) 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_; @@ -326,6 +328,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 +418,160 @@ 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 CodeFixActionInfoList { + std::vector infos_; +}; + +struct CodeFixOptions { + ark::es2panda::lsp::CancellationToken token; + ark::es2panda::lsp::FormatCodeSettings options; + ark::es2panda::lsp::UserPreferences preferences; +}; + +struct NodeInfo { + NodeInfo(std::string n, ark::es2panda::ir::AstNodeType k) : name(n), kind(k) {} + std::string name; + ark::es2panda::ir::AstNodeType kind; +}; + typedef struct LSPAPI { DefinitionInfo (*getDefinitionAtPosition)(es2panda_Context *context, size_t position); + std::vector (*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)( + std::vector *contextList, const char *fileName, size_t pos); + bool (*getSafeDeleteInfo)(es2panda_Context *context, size_t position); 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); + const std::vector &fileContexts, es2panda_Context *context, size_t position); + std::set (*findRenameLocationsInCurrentFile)(es2panda_Context *context, + size_t position); + bool (*needsCrossFileRename)(es2panda_Context *context, size_t position); std::vector (*findRenameLocationsWithCancellationToken)( - ark::es2panda::lsp::CancellationToken *tkn, const std::vector &files, - const ark::es2panda::SourceFile &file, size_t position); + ark::es2panda::lsp::CancellationToken *tkn, const std::vector &fileContexts, + es2panda_Context *context, 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); + ark::es2panda::lsp::RenameInfoType (*getRenameInfo)(es2panda_Context *context, size_t position, + const char *pandaLibPath); + 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); + ark::es2panda::lsp::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); + size_t (*getOffsetByColAndLine)(const std::string &sourceCode, size_t line, size_t column); + std::pair (*getColAndLineByOffset)(const std::string &sourceCode, size_t offset); + std::vector (*getCodeFixesAtPosition)(es2panda_Context *context, size_t start_position, + size_t end_position, std::vector &errorCodes, + CodeFixOptions &codeFixOptions); + CombinedCodeActionsInfo (*getCombinedCodeFix)(const char *fileName, const std::string &fixId, + CodeFixOptions &codeFixOptions); + TextSpan *(*GetNameOrDottedNameSpan)(es2panda_Context *context, int startPos); + es2panda_AstNode *(*getProgramAst)(es2panda_Context *context); + std::vector (*getNodeInfosByDefinitionData)(es2panda_Context *context, size_t position); + es2panda_AstNode *(*getClassDefinition)(es2panda_AstNode *astNode, const std::string &nodeName); + es2panda_AstNode *(*getIdentifier)(es2panda_AstNode *astNode, const std::string &nodeName); + DefinitionInfo (*getDefinitionDataFromNode)(es2panda_Context *context, const std::vector &nodeInfos); } 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..9d736ddbf8f6f000991cfad4f016c39650a0aa7a --- /dev/null +++ b/ets2panda/lsp/include/applicable_refactors.h @@ -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. + */ + +#ifndef APPLICABLE_REFACTORS_H +#define APPLICABLE_REFACTORS_H + +#include "public/es2panda_lib.h" +#include "refactors/refactor_types.h" +#include +#include +#include + +namespace ark::es2panda::lsp { + +std::vector GetApplicableRefactorsImpl(const RefactorContext *context); +} // 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/cancellation_token.h b/ets2panda/lsp/include/cancellation_token.h index a6a9209127a4e1179b40842f6bac94e47ebfd28a..942f7f957ed1499494e971bcf924e3ce74e8ad40 100644 --- a/ets2panda/lsp/include/cancellation_token.h +++ b/ets2panda/lsp/include/cancellation_token.h @@ -32,6 +32,7 @@ public: bool IsCancellationRequested(); bool ThrottledCancellationCheck(); CancellationToken(time_t designatedThrottleTime, HostCancellationToken *hostCancellationToken); + CancellationToken() : lastCancellationTime_(0), throttleTime_(0), host_(nullptr) {} private: time_t lastCancellationTime_; diff --git a/ets2panda/lsp/include/class_hierarchies.h b/ets2panda/lsp/include/class_hierarchies.h new file mode 100644 index 0000000000000000000000000000000000000000..73c06a69f045820079454be7b6cd312fa4926a89 --- /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(std::vector *contextList, + 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..8ff110fa20480d7bbf656dfba7e0b69b06bbe7fe --- /dev/null +++ b/ets2panda/lsp/include/class_hierarchy_info.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_CLASS_HIERARCHY_INFO_H +#define ES2PANDA_LSP_CLASS_HIERARCHY_INFO_H + +#include +#include +#include +#include "class_hierarchy_item.h" +#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_; +}; + +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> &GetMethodItemList() const + { + return methodItems_; + } + + const std::unordered_map> &GetPropertyItemList() const + { + return propertyItems_; + } + + bool AddItemToMethodList(const std::shared_ptr &item) + { + if (item == nullptr) { + return false; + } + auto detail = item->GetDetail(); + auto result = methodItems_.try_emplace(detail, item); + return result.second; + } + + bool AddItemToPropertyList(const std::shared_ptr &item) + { + if (item == nullptr) { + return false; + } + auto detail = item->GetDetail(); + auto result = propertyItems_.try_emplace(detail, item); + return result.second; + } + + void DeleteTargetItemInMethodList(const std::shared_ptr &item) + { + if (item == nullptr) { + return; + } + auto detail = item->GetDetail(); + methodItems_.erase(detail); + } + + void DeleteTargetItemInPropertyList(const std::shared_ptr &item) + { + if (item == nullptr) { + return; + } + auto detail = item->GetDetail(); + propertyItems_.erase(detail); + } + + void DeleteAllItemsInMethodList() + { + methodItems_.clear(); + } + + void DeleteAllItemsInPropertyList() + { + propertyItems_.clear(); + } + + bool IsItemExistInMethodList(const std::shared_ptr &item) const + { + if (item == nullptr) { + return false; + } + auto detail = item->GetDetail(); + auto iter = methodItems_.find(detail); + return iter != methodItems_.end(); + } + + bool IsItemExistInPropertyList(const std::shared_ptr &item) const + { + if (item == nullptr) { + return false; + } + auto detail = item->GetDetail(); + auto iter = propertyItems_.find(detail); + return iter != propertyItems_.end(); + } + +private: + std::string className_; + std::unordered_map> methodItems_; + std::unordered_map> propertyItems_; +}; + +using ClassHierarchy = std::vector; + +/** + * Retrieve the list of undefined virtual functions and properties in the parent class. + * + * such as ets: + * class Animal { + * public 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: body_: string, ClassDefinitionStyle FIELD, AccessModifierStyle: PUBLIC } }, + * { "Animal", { detail: sleep(): void, ClassDefinitionStyle: METHOD, AccessModifierStyle: PUBLIC } } ]. + */ +ClassHierarchy GetClassHierarchyInfoImpl(es2panda_Context *context, size_t position); +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/class_hierarchy_item.h b/ets2panda/lsp/include/class_hierarchy_item.h new file mode 100644 index 0000000000000000000000000000000000000000..a2d6789aa7dc9c0d06598621f11670afca406c50 --- /dev/null +++ b/ets2panda/lsp/include/class_hierarchy_item.h @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_ITEM_H +#define ES2PANDA_LSP_CLASS_HIERARCHY_ITEM_H + +#include + +namespace ark::es2panda::lsp { +enum class SetterStyle { NONE = 0, SETTER, GETTER }; + +enum class AccessModifierStyle { PUBLIC = 0, PROTECTED, PRIVATE }; + +enum class ClassDefinitionStyle { FIELD = 0, METHOD }; + +class ClassHierarchyItem { +public: + ClassHierarchyItem(AccessModifierStyle access, std::string detail) + : accessModifier_(access), detail_(std::move(detail)) + { + } + + virtual ~ClassHierarchyItem() = default; + + ClassHierarchyItem(const ClassHierarchyItem &other) = default; + ClassHierarchyItem(ClassHierarchyItem &&other) = default; + ClassHierarchyItem &operator=(const ClassHierarchyItem &other) = default; + ClassHierarchyItem &operator=(ClassHierarchyItem &&other) = default; + + virtual ClassDefinitionStyle GetClassDefinitionStyle() const = 0; + + AccessModifierStyle GetAccessModifierStyle() const + { + return accessModifier_; + } + + const std::string &GetDetail() const + { + return detail_; + } + +private: + AccessModifierStyle accessModifier_; + std::string detail_; +}; + +class ClassPropertyItem : public ClassHierarchyItem { +public: + ClassPropertyItem(AccessModifierStyle access, std::string detail) : ClassHierarchyItem(access, std::move(detail)) {} + + ~ClassPropertyItem() override = default; + + ClassPropertyItem(const ClassPropertyItem &other) = default; + ClassPropertyItem(ClassPropertyItem &&other) = default; + ClassPropertyItem &operator=(const ClassPropertyItem &other) = default; + ClassPropertyItem &operator=(ClassPropertyItem &&other) = default; + + ClassDefinitionStyle GetClassDefinitionStyle() const override + { + return ClassDefinitionStyle::FIELD; + } + + void SetVariableName(const std::string &variableName) + { + if (variableName.empty()) { + return; + } + variableName_ = variableName; + } + + const std::string &GetVariableName() const + { + return variableName_; + } + +private: + std::string variableName_; +}; + +class ClassMethodItem : public ClassHierarchyItem { +public: + ClassMethodItem(AccessModifierStyle access, std::string detail, SetterStyle setter) + : ClassHierarchyItem(access, std::move(detail)), setter_(setter) + { + } + + ~ClassMethodItem() override = default; + + ClassMethodItem(const ClassMethodItem &other) = default; + ClassMethodItem(ClassMethodItem &&other) = default; + ClassMethodItem &operator=(const ClassMethodItem &other) = default; + ClassMethodItem &operator=(ClassMethodItem &&other) = default; + + ClassDefinitionStyle GetClassDefinitionStyle() const override + { + return ClassDefinitionStyle::METHOD; + } + + void SetFunctionName(const std::string &functionName) + { + if (functionName.empty()) { + return; + } + funcName_ = functionName; + } + + const std::string &GetFunctionName() const + { + return funcName_; + } + + SetterStyle GetSetterStyle() const + { + return setter_; + } + +private: + std::string funcName_; + SetterStyle setter_; +}; +} // 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..567be5aa8602fd485f5e839b5695f11a48bfb910 --- /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 "generated/code_fix_register.h" +#include "es2panda.h" + +namespace ark::es2panda::lsp { +using ark::es2panda::lsp::codefixes::DiagnosticCode; +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 codefixes::DiagnosticCode &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, + DiagnosticCode &diagCode); + CodeFixAction CreateCodeFixAction(std::string fixName, std::vector changes, + DiagnosticCode diagCode, std::string fixId, + std::vector &command); + std::string GetFileName(const std::string &filePath); + std::vector GetSupportedErrorCodes(); + std::unique_ptr 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..1b5dd62704da2decfcf74cd4462b8ab2b6ceae42 --- /dev/null +++ b/ets2panda/lsp/include/code_fixes/code_fix_types.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "generated/code_fix_register.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "../get_class_property_info.h" +#include "lsp/include/services/text_change/text_change_context.h" + +namespace ark::es2panda::lsp { + +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 = {}; +}; + +class DiagnosticWithLocation : Diagnostic { +public: + DiagnosticWithLocation(Diagnostic &&base, const SourceFile &file, const size_t start = 0, const size_t length = 0) + : Diagnostic(std::move(base)), file_(file), start_(start), length_(length) + { + } + + using Diagnostic::Diagnostic; + + SourceFile GetFile() const + { + return file_; + } + + size_t GetStart() const + { + return start_; + } + + size_t Getlength() const + { + return length_; + } + +private: + 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 d776bb06f13b0e693442cc32e6b3c264b89f4985..9b3c85492b0b7d2898e340f1516e9be9c669b041 100644 --- a/ets2panda/lsp/include/completions.h +++ b/ets2panda/lsp/include/completions.h @@ -52,7 +52,9 @@ enum class CompletionEntryKind { STRUCT = 22, EVENT = 23, OPERATOR = 24, - TYPE_PARAMETER = 25 + TYPE_PARAMETER = 25, + ALIAS_TYPE = 26, + ANNOTATION = 27 }; namespace sort_text { @@ -205,10 +207,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_references.h b/ets2panda/lsp/include/find_references.h index c729d3e20b496def549b887f0782c0d1d82606ef..361a382eaad6871afac1c779db1d3adfa61bb4f1 100644 --- a/ets2panda/lsp/include/find_references.h +++ b/ets2panda/lsp/include/find_references.h @@ -45,6 +45,8 @@ struct ReferencedNode { // Returns a map of file path and reference position list std::set FindReferences(CancellationToken *tkn, const std::vector &files, const SourceFile &file, size_t position); +std::set FindReferences(CancellationToken *tkn, const std::vector &fileContexts, + es2panda_Context *context, size_t position); } // namespace ark::es2panda::lsp #endif \ No newline at end of file diff --git a/ets2panda/lsp/include/find_rename_locations.h b/ets2panda/lsp/include/find_rename_locations.h index c701d62563f909e2603f367dfd4fa75678029b12..8ce725bbda58c8908e61765bd824266788db47fe 100644 --- a/ets2panda/lsp/include/find_rename_locations.h +++ b/ets2panda/lsp/include/find_rename_locations.h @@ -26,27 +26,41 @@ namespace ark::es2panda::lsp { // NOLINTBEGIN(misc-non-private-member-variables-in-classes) struct RenameLocation { - std::string filePath; + std::string fileName; size_t start = 0; size_t end = 0; size_t line = 0; - std::string prefixText; - std::string suffixText; + std::optional prefixText = std::nullopt; + std::optional suffixText = std::nullopt; + RenameLocation() = default; + RenameLocation(std::string file, size_t s, size_t e, size_t l, std::optional prefix = std::nullopt, + std::optional suffix = std::nullopt) + : fileName(std::move(file)), + start(s), + end(e), + line(l), + prefixText(std::move(prefix)), + suffixText(std::move(suffix)) + { + } bool operator<(const RenameLocation &other) const { - return std::tie(filePath, start, end, line, prefixText, suffixText) < - std::tie(other.filePath, other.start, other.end, other.line, other.prefixText, other.suffixText); + return std::tie(fileName, start, end, line, prefixText, suffixText) < + std::tie(other.fileName, other.start, other.end, other.line, other.prefixText, other.suffixText); } }; // NOLINTEND(misc-non-private-member-variables-in-classes) +bool NeedsCrossFileRename(es2panda_Context *context, size_t position); + std::set FindRenameLocations(CancellationToken *tkn, - const std::vector &files, - const ark::es2panda::SourceFile &file, size_t position); + const std::vector &fileContexts, + es2panda_Context *context, size_t position); -std::set FindRenameLocations(const std::vector &files, - const ark::es2panda::SourceFile &file, size_t position); +std::set FindRenameLocations(const std::vector &fileContexts, + es2panda_Context *context, size_t position); +std::set FindRenameLocationsInCurrentFile(es2panda_Context *context, size_t position); } // namespace ark::es2panda::lsp 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/util/ast-builders/etsLaunchExpressionBuilder.h b/ets2panda/lsp/include/formatting/formatting.h similarity index 37% rename from ets2panda/util/ast-builders/etsLaunchExpressionBuilder.h rename to ets2panda/lsp/include/formatting/formatting.h index dc43d9322bff3f9f720a9eb870927ffea10634c9..4edb858971153e4c2da007ad2a51a91a535003f6 100644 --- a/ets2panda/util/ast-builders/etsLaunchExpressionBuilder.h +++ b/ets2panda/lsp/include/formatting/formatting.h @@ -1,10 +1,10 @@ /** - * 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 + * 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,34 +13,41 @@ * limitations under the License. */ -#ifndef ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER -#define ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER +#ifndef FORMATTING_H +#define FORMATTING_H -#include "ir/ets/etsLaunchExpression.h" -#include "mem/arena_allocator.h" -#include "astBuilder.h" +#include +#include "formatting_settings.h" +#include "rules_map.h" +#include "lsp/include/types.h" -namespace ark::es2panda::ir { +namespace ark::es2panda::lsp { -class ETSLaunchExpressionBuilder : public AstBuilder { +struct FormatContext { public: - explicit ETSLaunchExpressionBuilder(ark::ArenaAllocator *allocator) : AstBuilder(allocator) {} + explicit FormatContext(FormatCodeSettings &formatCodeSetting, RulesMap &rulesMap) + : options_(formatCodeSetting), getRules_(rulesMap) + { + } - ETSLaunchExpressionBuilder &SetExpression(CallExpression *expr) + FormatCodeSettings &GetFormatCodeSettings() { - expr_ = expr; - return *this; + return options_; } - ETSLaunchExpression *Build() + RulesMap &GetRulesMap() { - auto node = AllocNode(expr_); - return node; + return getRules_; } private: - CallExpression *expr_ {}; + FormatCodeSettings options_; + RulesMap getRules_; }; -} // namespace ark::es2panda::ir -#endif // ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER \ No newline at end of file +FormatContext GetFormatContext(FormatCodeSettings &options); +std::vector FormatDocument(es2panda_Context *context, FormatContext formatContext); + +} // 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..cad2a21c73cc7979f4692416065462bbd4d7048e --- /dev/null +++ b/ets2panda/lsp/include/formatting/formatting_context.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 FORMATTING_CONTEXT_H +#define FORMATTING_CONTEXT_H + +#include "formatting_settings.h" +#include "ir/astNode.h" +#include "lexer/token/token.h" +#include + +namespace ark::es2panda::lsp { + +class FormattingContext { +public: + explicit FormattingContext(const std::string &sourceText); + + void SetCurrentToken(const lexer::Token &token); + void SetPreviousToken(const lexer::Token &token); + void SetNextToken(const lexer::Token &token); + void SetCurrentTokenParent(ir::AstNode *node); + void SetNextTokenParent(ir::AstNode *node); + void SetOptions(const FormatCodeSettings &options); + + const lexer::Token &GetCurrentToken() const; + const lexer::Token &GetPreviousToken() const; + const lexer::Token &GetNextToken() const; + ir::AstNode *GetCurrentTokenParent() const; + ir::AstNode *GetNextTokenParent() const; + const std::string &GetSourceText() const; + const lexer::SourceRange &GetCurrentTokenSpan() const; + const FormatCodeSettings &GetOptions() const; + + bool ContextNodeBlockIsOnOneLine() const; + bool TokensAreOnSameLine() const; + +private: + bool BlockIsOnOneLine(ir::AstNode *node) const; + const std::string &sourceText_; + + lexer::Token currentToken_; + lexer::Token prevToken_; + lexer::Token nextToken_; + ir::AstNode *currentTokenParent_ {nullptr}; + ir::AstNode *nextTokenParent_ {nullptr}; + lexer::SourceRange currentTokenSpan_; + FormatCodeSettings options_; +}; + +} // 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..0c850fb928bdfc73bb4dc364d1ae68f624e561e8 --- /dev/null +++ b/ets2panda/lsp/include/formatting/rule.h @@ -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. + */ + +#ifndef RULE_H +#define RULE_H + +#include +#include +#include "formatting_context.h" + +namespace ark::es2panda::lsp { + +using ContextPredicate = std::function; + +enum class RuleAction : uint32_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, + + STOP_ACTION = STOP_PROCESSING_SPACE_ACTIONS | STOP_PROCESSING_TOKEN_ACTIONS, + MODIFY_SPACE_ACTION = INSERT_SPACE | INSERT_NEWLINE | DELETE_SPACE, + MODIFY_TOKEN_ACTION = DELETE_TOKEN | INSERT_TRAILING_SEMICOLON +}; + +inline RuleAction operator&(RuleAction lhs, RuleAction rhs) +{ + return static_cast(static_cast(lhs) & static_cast(rhs)); +} + +inline RuleAction operator|(RuleAction lhs, RuleAction rhs) +{ + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +inline RuleAction &operator|=(RuleAction &lhs, RuleAction rhs) +{ + lhs = lhs | rhs; + return lhs; +} + +inline RuleAction operator~(RuleAction rhs) +{ + return static_cast(~static_cast(rhs)); +} + +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) + { + } + + const std::vector &GetContext() const + { + return context_; + } + + RuleAction GetRuleAction() const + { + 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_; + } + + void SetSpecific(bool isSpecific) + { + isSpecific_ = isSpecific; + } + + bool GetIsSpecifier() + { + return isSpecific_; + } + +private: + std::vector tokens_; + bool isSpecific_; +}; + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/formatting/rules.h b/ets2panda/lsp/include/formatting/rules.h new file mode 100644 index 0000000000000000000000000000000000000000..bfbff345d5ab556e467f03347730552ea5c9b65b --- /dev/null +++ b/ets2panda/lsp/include/formatting/rules.h @@ -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. + */ + +#ifndef RULES_H +#define RULES_H + +#include +#include "rule.h" + +namespace ark::es2panda::lsp { + +struct RuleSpec { +public: + explicit RuleSpec(Rule rule, TokenRange leftTokenRange, TokenRange rightTokenRange) + : rule_(std::move(rule)), + leftTokenRange_(std::move(leftTokenRange)), + rightTokenRange_(std::move(rightTokenRange)) + { + } + + Rule &GetRule() + { + return rule_; + } + + const Rule &GetRule() const + { + return rule_; + } + + TokenRange &GetLeftTokenRange() + { + return leftTokenRange_; + } + + const TokenRange &GetLeftTokenRange() const + { + return leftTokenRange_; + } + + TokenRange &GetRightTokenRange() + { + return rightTokenRange_; + } + + const TokenRange &GetRightTokenRange() const + { + return rightTokenRange_; + } + +private: + Rule rule_; + TokenRange leftTokenRange_; + TokenRange rightTokenRange_; +}; + +std::vector GetAllRules(); + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/formatting/rules_map.h b/ets2panda/lsp/include/formatting/rules_map.h new file mode 100644 index 0000000000000000000000000000000000000000..5fc8dcff7b1793f6004fc8d4bee0e22dfd734733 --- /dev/null +++ b/ets2panda/lsp/include/formatting/rules_map.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RULES_MAP_H +#define RULES_MAP_H + +#include +#include +#include "rules.h" + +namespace ark::es2panda::lsp { + +using RulesMap = std::function(const FormattingContext &)>; +const lexer::TokenType LAST_TOKEN = lexer::TokenType::KEYW_YIELD; + +class RulesMapCache { +public: + static RulesMapCache &Instance(); + + static RulesMap &GetRulesMap(); + + ~RulesMapCache() = default; + NO_COPY_SEMANTIC(RulesMapCache); + NO_MOVE_SEMANTIC(RulesMapCache); + + RulesMapCache() = default; + + static RulesMap rulesMap_; + + static RulesMap CreateRulesMap(const std::vector &ruleSpec); + + static int GetInsertionIndex(uint32_t bitmap, uint32_t shift); + static int IncreaseInsertionIndex(uint32_t bitmap, uint32_t shift); + static void AddRule(std::vector &ruleSpecs, RuleSpec &ruleSpec, bool specificTokens, + unsigned int &bitmap); + static RuleAction GetRuleActionExclusion(RuleAction ruleAction); + static int GetRuleBucketIndex(lexer::TokenType left, lexer::TokenType right); + static std::unordered_map> BuildMap(const std::vector &ruleSpecs); +}; + +} // namespace ark::es2panda::lsp + +#endif 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_name_or_dotted_name_span.h b/ets2panda/lsp/include/get_name_or_dotted_name_span.h new file mode 100644 index 0000000000000000000000000000000000000000..1835282643f1fbec697975b5190c0cfe1bb3f9c0 --- /dev/null +++ b/ets2panda/lsp/include/get_name_or_dotted_name_span.h @@ -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. + */ + +#ifndef GET_NAME_OR_DOTTED_NAME_SPAN_H +#define GET_NAME_OR_DOTTED_NAME_SPAN_H + +#include "api.h" +#include "ir/astNode.h" +#include "es2panda.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +bool IsRightSideOfPropertyAccess(ir::AstNode *node); +bool IsRightSideOfQualifiedName(ir::AstNode *node); +bool IsNameOfModuleDeclaration(ir::AstNode *node); +ir::AstNode *AscendToRootName(ir::AstNode *node); + +TextSpan *GetNameOrDottedNameSpanImpl(es2panda_Context *context, int startPos); + +} // namespace ark::es2panda::lsp +#endif // GET_NAME_OR_DOTTED_NAME_SPAN_H \ No newline at end of file diff --git a/ets2panda/lsp/include/get_node.h b/ets2panda/lsp/include/get_node.h new file mode 100644 index 0000000000000000000000000000000000000000..b2c63afacb5d3c1240009be2d22ccbcfbda6feb4 --- /dev/null +++ b/ets2panda/lsp/include/get_node.h @@ -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. + */ +#ifndef ES2PANDA_LSP_GET_NODE_H +#define ES2PANDA_LSP_GET_NODE_H + +#include +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +es2panda_AstNode *GetProgramAstImpl(es2panda_Context *context); +es2panda_AstNode *GetClassDefinitionImpl(es2panda_AstNode *astNode, const std::string &nodeName); +es2panda_AstNode *GetIdentifierImpl(es2panda_AstNode *astNode, const std::string &nodeName); +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file 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..b1d9979cd67c56e786f39764e617771131c0af2b --- /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); +} // namespace ark::es2panda::lsp +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/get_signature.h b/ets2panda/lsp/include/get_signature.h new file mode 100644 index 0000000000000000000000000000000000000000..ca8f94c4bd5293650d50410458f9581ff5747871 --- /dev/null +++ b/ets2panda/lsp/include/get_signature.h @@ -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. + */ + +#ifndef LSP_GET_SIGNATURE_H +#define LSP_GET_SIGNATURE_H + +#include +#include "ir/astNode.h" +#include "lsp/include/types.h" +#include "public/es2panda_lib.h" +namespace ark::es2panda::lsp { +size_t FindFirstNonSpaceLeft(const std::string &str, size_t pos); +SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::AstNode *node, ir::AstNode *declNode, + checker::Signature *signature, size_t position); +SignatureHelpItems GetSignature(es2panda_Context *context, size_t position); +} // 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..6777e3729e85559768a65fb5ec1881d638e4204c 100644 --- a/ets2panda/lsp/include/internal_api.h +++ b/ets2panda/lsp/include/internal_api.h @@ -52,6 +52,58 @@ public: impl_->DestroyContext(context); } + const es2panda_DiagnosticKind *CreateDiagnosticKind(es2panda_Context *context, const char *dmessage, + es2panda_PluginDiagnosticType etype) + { + return impl_->CreateDiagnosticKind(context, dmessage, etype); + } + + es2panda_SuggestionInfo *CreateSuggestionInfo(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, const char *substitutionCode, + const char *title, es2panda_SourceRange *range) + { + return impl_->CreateSuggestionInfo(context, kind, args, argc, substitutionCode, title, range); + } + + es2panda_DiagnosticInfo *CreateDiagnosticInfo(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, es2panda_SourcePosition *pos) + { + return impl_->CreateDiagnosticInfo(context, kind, args, argc, pos); + } + + es2panda_SourcePosition *CreateSourcePosition(es2panda_Context *context, size_t index, size_t line) + { + return impl_->CreateSourcePosition(context, index, line); + } + + es2panda_SourceRange *CreateSourceRange(es2panda_Context *context, es2panda_SourcePosition *start, + es2panda_SourcePosition *end) + { + return impl_->CreateSourceRange(context, start, end); + } + + void LogDiagnosticWithSuggestion(es2panda_Context *context, const es2panda_DiagnosticInfo *diagnosticInfo, + const es2panda_SuggestionInfo *suggestionInfo) + { + return impl_->LogDiagnosticWithSuggestion(context, diagnosticInfo, suggestionInfo); + } + + void LogDiagnostic(es2panda_Context *context, const es2panda_DiagnosticKind *ekind, const char **args, size_t argc, + es2panda_SourcePosition *pos) + { + return impl_->LogDiagnostic(context, ekind, args, argc, pos); + } + + void ClassDefinitionSetFromStructModifier(es2panda_Context *context, es2panda_AstNode *classInstance) + { + return impl_->ClassDefinitionSetFromStructModifier(context, classInstance); + } + + bool ClassDefinitionIsFromStructConst(es2panda_Context *context, es2panda_AstNode *classInstance) + { + return impl_->ClassDefinitionIsFromStructConst(context, classInstance); + } + NO_COPY_SEMANTIC(Initializer); NO_MOVE_SEMANTIC(Initializer); @@ -65,9 +117,10 @@ 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, +FileDiagnostic CreateDiagnosticForNode(es2panda_AstNode *node, Diagnostic diagnostic, es2panda_Context *context, const std::vector &args = std::vector()); std::string GetCurrentTokenValueImpl(es2panda_Context *context, size_t position); void GetRangeOfEnclosingComment(es2panda_Context *context, size_t pos, CommentRange *result); @@ -82,10 +135,22 @@ 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); +ir::AstNode *FindAncestor(ir::AstNode *node, const ir::NodePredicate &cb); +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); +ir::Identifier *GetIdentFromNewClassExprPart(const ir::Expression *value); +varbinder::Decl *FindDeclInFunctionScope(varbinder::Scope *scope, const util::StringView &name); +varbinder::Decl *FindDeclInGlobalScope(varbinder::Scope *scope, const util::StringView &name); +varbinder::Decl *FindDeclInScopeWithFallback(varbinder::Scope *scope, const util::StringView &name); +std::string GetImportFilePath(es2panda_Context *context, size_t pos); } // 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..ecf029c9877c1e5eac5afbcc0c3a45f1e4c3dc3e --- /dev/null +++ b/ets2panda/lsp/include/isolated_declaration.h @@ -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. + */ + +#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); +std::string GetReturnTypeStr(const checker::Type *checkerType, checker::ETSChecker *checker); +const checker::Signature *GetFuncSignature(const checker::ETSFunctionType *etsFunctionType, + const ir::MethodDefinition *methodDef); +} // 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/lsp/include/node_matchers.h b/ets2panda/lsp/include/node_matchers.h new file mode 100755 index 0000000000000000000000000000000000000000..7555dd3f8a9729c04a43dced45480017aefb3aec --- /dev/null +++ b/ets2panda/lsp/include/node_matchers.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NODE_MATCHERS_H +#define NODE_MATCHERS_H + +#include +#include +#include "ir/astNode.h" +#include "api.h" + +namespace ark::es2panda::lsp { +using NodeMatcher = std::function; +using NodeExtractor = ir::AstNode *(*)(ir::AstNode *, const NodeInfo *); + +bool MatchClassDefinition(ir::AstNode *childNode, const NodeInfo *info); +bool MatchIdentifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchClassProperty(ir::AstNode *childNode, const NodeInfo *info); +bool MatchProperty(ir::AstNode *childNode, const NodeInfo *info); +bool MatchMethodDefinition(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSEnumDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSEnumMember(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSInterfaceDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSTypeAliasDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchExportSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchMemberExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsStringLiteralType(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsTypeReference(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsKeyofType(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsNewClassInstanceExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsStructDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchSpreadElement(ir::AstNode *childNode, const NodeInfo *info); +bool MatchCallExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTsTypeReference(ir::AstNode *childNode, const NodeInfo *info); +bool MatchScriptFunction(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportDefaultSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportNamespaceSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSTypeParameter(ir::AstNode *childNode, const NodeInfo *info); +bool MatchSwitchStatement(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsParameterExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTsNonNullExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchFunctionDeclaration(ir::AstNode *childNode, const NodeInfo *info); + +ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractETSStringLiteralTypeIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractETSKeyofTypeIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractCallExpressionIdentifier(ir::AstNode *node, const NodeInfo *info); + +const std::unordered_map &GetNodeExtractors(); +const std::unordered_map &GetNodeMatchers(); +} // namespace ark::es2panda::lsp +#endif // NODE_MATCHERS_H \ No newline at end of file diff --git a/ets2panda/lsp/include/organize_imports.h b/ets2panda/lsp/include/organize_imports.h new file mode 100644 index 0000000000000000000000000000000000000000..a178033a459ffa1cc71fe834d5bcb65c790df320 --- /dev/null +++ b/ets2panda/lsp/include/organize_imports.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 ES2PANDA_LSP_ORGANIZE_IMPORTS_H +#define ES2PANDA_LSP_ORGANIZE_IMPORTS_H + +#include +#include +#include "public/es2panda_lib.h" + +struct FileTextChanges; + +namespace ark::es2panda::lsp { + +enum class ImportType { NORMAL, DEFAULT, NAMESPACE, TYPE_ONLY }; + +struct ImportSpecifier { + std::string importedName; + std::string localName; + ImportType type; + size_t start; + size_t length; +}; + +struct ImportInfo { + std::string moduleName; + std::vector namedImports; + size_t startIndex; + size_t endIndex; +}; + +struct OrganizeImports { + static std::vector Organize(es2panda_Context *context, const std::string &fileName); +}; + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/quick_info.h b/ets2panda/lsp/include/quick_info.h index 0c758407817c19eac33bb8b3c9cf043415939c45..a051b6a48f4455b7afcddc43196090c00ec185be 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 { @@ -35,11 +36,19 @@ std::vector CreateDisplayForTypeAlias(ir::AstNode *node); std::vector CreateDisplayForEnum(ir::AstNode *node); std::vector CreateDisplayForEnumMember(ir::AstNode *node); std::vector CreateDisplayForTypeParameter(ir::AstNode *node); -std::vector CreateDisplayForMethodDefinition(ir::AstNode *node, const std::string &kindModifier); -std::vector CreateDisplayForClassProperty(ir::AstNode *node, const std::string &kindModifier); +std::vector CreateDisplayForMethodDefinition(ir::AstNode *node, const std::string &kindModifier, + checker::ETSChecker *checker); +std::vector CreateDisplayForClassProperty(ir::AstNode *node); 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/refactor_provider.h b/ets2panda/lsp/include/refactor_provider.h new file mode 100644 index 0000000000000000000000000000000000000000..dbd529c2c2ef5579f156d61d4456c4dc6a432e69 --- /dev/null +++ b/ets2panda/lsp/include/refactor_provider.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_INCLUDE_REFACTOR_PROVIDER_H +#define ES2PANDA_LSP_INCLUDE_REFACTOR_PROVIDER_H + +#include "refactors/refactor_types.h" +#include +#include +#include + +namespace ark::es2panda::lsp { + +class RefactorProvider { +public: + void RegisterRefactor(const std::string &name, std::unique_ptr refactor); + static RefactorProvider &Instance(); + std::unique_ptr GetEditsForRefactor(const RefactorContext &context, + const std::string &refactorName, + const std::string &actionName) const; + std::vector GetApplicableRefactors(const RefactorContext &context) const; + + const std::unordered_map> &GetRefactors() const; + +private: + std::unordered_map> refactors_; +}; + +template +struct AutoRefactorRegister { + constexpr explicit AutoRefactorRegister(const std::string &name, std::unique_ptr refactor) + { + RefactorProvider::Instance().RegisterRefactor(name, std::move(refactor)); + } + + constexpr explicit AutoRefactorRegister(const std::string &name) : AutoRefactorRegister(name, std::make_unique()) + { + } +}; + +} // namespace ark::es2panda::lsp +#endif // ES2PANDA_LSP_INCLUDE_REFACTOR_PROVIDER_H diff --git a/ets2panda/lsp/include/refactors/convert_chain.h b/ets2panda/lsp/include/refactors/convert_chain.h new file mode 100644 index 0000000000000000000000000000000000000000..44eee480567caa30a2357d474aa5f91c796a20de --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_chain.h @@ -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. + */ + +#ifndef CONVERT_CHAIN_H +#define CONVERT_CHAIN_H + +#include "refactor_types.h" + +namespace ark::es2panda::lsp { + +constexpr RefactorActionView TO_NAMED_CHAIN_ACTION {"Convert to optional chain expression", + "Convert to optional chain expression", + "refactor.rewrite.expression.optionalChain"}; +class ConvertChainRefactor : public Refactor { +public: + ConvertChainRefactor(); + ApplicableRefactorInfo GetAvailableActions(const RefactorContext &context) const override; + std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const override; +}; +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/refactors/convert_export.h b/ets2panda/lsp/include/refactors/convert_export.h new file mode 100644 index 0000000000000000000000000000000000000000..c4d4fd7982004063aa3eee5e2e5ff05f0d2fb9ea --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_export.h @@ -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. + */ + +#ifndef CONVERT_EXPORT_H +#define CONVERT_EXPORT_H + +#include "refactor_types.h" + +namespace ark::es2panda::lsp { + +constexpr RefactorActionView TO_NAMED_EXPORT_ACTION {"Convert default export to named export", + "Convert default export to named export", + "refactor.rewrite.export.named"}; +constexpr RefactorActionView TO_DEFAULT_EXPORT_ACTION {"Convert named export to default export", + "Convert named export to default export", + "refactor.rewrite.export.default"}; + +class ConvertExportRefactor : public Refactor { +public: + ConvertExportRefactor(); + ApplicableRefactorInfo GetAvailableActions(const RefactorContext &context) const override; + std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const override; +}; + +} // namespace ark::es2panda::lsp + +#endif // CONVERT_EXPORT_H diff --git a/ets2panda/lsp/include/refactors/convert_function.h b/ets2panda/lsp/include/refactors/convert_function.h new file mode 100644 index 0000000000000000000000000000000000000000..5581ab3dd52ded479126c416070681b49c9007f3 --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_function.h @@ -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. + */ + +#ifndef CONVERT_FUNCTION_H +#define CONVERT_FUNCTION_H + +#include "refactor_types.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(const RefactorContext &context) const override; + std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const override; +}; + +} // namespace ark::es2panda::lsp + +#endif // CONVERT_FUNCTION_H diff --git a/ets2panda/lsp/include/refactors/convert_import.h b/ets2panda/lsp/include/refactors/convert_import.h new file mode 100644 index 0000000000000000000000000000000000000000..a41f5f5b6dfffa5247828c9074286629b531fed1 --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_import.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 CONVERT_IMPORT_H +#define CONVERT_IMPORT_H + +#include "refactor_types.h" + +namespace ark::es2panda::lsp { + +constexpr RefactorActionView TO_NAMED_IMPORT_ACTION {"Convert namespace import to named imports", + "Convert namespace import to named imports", + "refactor.rewrite.import.named"}; +constexpr RefactorActionView TO_NAMESPACE_IMPORT_ACTION {"Convert named imports to namespace import", + "Convert named imports to namespace import", + "refactor.rewrite.import.namespace"}; +constexpr RefactorActionView TO_DEFAULT_IMPORT_ACTION {"Convert named imports to default import", + "Convert named imports to default import", + "refactor.rewrite.import.default"}; + +class ConvertImportRefactor : public Refactor { +public: + ConvertImportRefactor(); + ApplicableRefactorInfo GetAvailableActions(const RefactorContext &context) const override; + std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const override; +}; + +} // namespace ark::es2panda::lsp + +#endif // CONVERT_IMPORT_H diff --git a/ets2panda/lsp/include/refactors/convert_template.h b/ets2panda/lsp/include/refactors/convert_template.h new file mode 100644 index 0000000000000000000000000000000000000000..4c27a6d9c702fc5feb026f04cfa02e2f149a6c5e --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_template.h @@ -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. + */ + +#ifndef CONVERT_TEMPLATE_H +#define CONVERT_TEMPLATE_H + +#include "refactor_types.h" + +namespace ark::es2panda::lsp { + +constexpr RefactorActionView TO_NAMED_TEMPLATE_ACTION {"Convert to template string", "Convert to template string", + "refactor.rewrite.string"}; +class ConvertTemplateRefactor : public Refactor { +public: + ConvertTemplateRefactor(); + ApplicableRefactorInfo GetAvailableActions(const RefactorContext &context) const override; + std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const override; +}; +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/refactors/refactor_types.h b/ets2panda/lsp/include/refactors/refactor_types.h new file mode 100644 index 0000000000000000000000000000000000000000..513ba22f97608270b811163728c628d656fd6e32 --- /dev/null +++ b/ets2panda/lsp/include/refactors/refactor_types.h @@ -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. + */ + +#ifndef REFACTOR_TYPES_H +#define REFACTOR_TYPES_H + +#include "public/es2panda_lib.h" +#include "../cancellation_token.h" +#include "../user_preferences.h" +#include "../types.h" +#include "es2panda.h" +#include +#include +#include + +namespace ark::es2panda::lsp { + +struct RefactorEditInfo { +private: + std::vector fileTextChanges_; + +public: + explicit RefactorEditInfo(std::vector fileTextChanges = {}) + : fileTextChanges_(std::move(fileTextChanges)) + { + } + + std::vector &GetFileTextChanges() + { + return fileTextChanges_; + } +}; + +struct TextRange { + size_t pos; + size_t end; +}; + +struct RefactorContext { + ark::es2panda::lsp::CancellationToken *cancellationToken = nullptr; + ark::es2panda::lsp::UserPreferences *preferences = nullptr; + TextRange span = {0, 0}; + es2panda_Context *context = nullptr; + std::string kind; +}; + +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"; +constexpr std::string_view CONVERT_EXPORT_REFACTOR_NAME = "Convert export"; +constexpr std::string_view CONVERT_IMPORT_REFACTOR_NAME = "Convert import"; +constexpr std::string_view CONVERT_TEMPLATE_REFACTOR_NAME = "Convert to template string"; +constexpr std::string_view CONVERT_CHAIN_REFACTOR_NAME = "Convert to optional chain expression"; +} // namespace refactor_name + +namespace refactor_description { +constexpr std::string_view CONVERT_FUNCTION_REFACTOR_DESC = "Convert arrow function or function expression"; +constexpr std::string_view CONVERT_TEMPLATE_REFACTOR_DESC = "Convert to template string"; +constexpr std::string_view CONVERT_CHAIN_REFACTOR_DESC = "Convert to optional chain expression"; +} // namespace refactor_description + +class Refactor { +private: + std::vector kinds_; + +public: + bool IsKind(const std::string &kind) const; + void AddKind(const std::string &kind); + virtual ApplicableRefactorInfo GetAvailableActions(const RefactorContext &context) const = 0; + + virtual std::unique_ptr GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const = 0; + virtual ~Refactor() = default; + Refactor() = default; + Refactor &operator=(const Refactor &other); + Refactor &operator=(Refactor &&other); + Refactor(const Refactor &other); + Refactor(Refactor &&other); +}; + +} // namespace ark::es2panda::lsp + +#endif // REFACTOR_TYPES_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/add_local_variable.h b/ets2panda/lsp/include/register_code_fix/add_local_variable.h new file mode 100644 index 0000000000000000000000000000000000000000..79bad1cc4c788812363275998c43fe8d407f1ae5 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/add_local_variable.h @@ -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. + */ + +#ifndef ADD_LOCAL_VARIABLE_H +#define ADD_LOCAL_VARIABLE_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 AddLocalVariable : public CodeFixRegistration { +public: + AddLocalVariable(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForAddLocalVariable(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToAddLocalVariable(const CodeFixContext &context); + + std::string DetermineVariableType(ir::AstNode *unresolvedNode); + std::string GetTypeFromDirectAssignment(ir::AstNode *unresolvedNode, ir::AstNode *parent); + std::string GetTypeFromMemberAssignment(ir::AstNode *unresolvedNode, ir::AstNode *parent); + std::string InferTypeFromExpression(ir::AstNode *expression); + std::string InferTypeFromLiteral(ir::AstNode *expression); + std::string InferTypeFromComplexExpression(ir::AstNode *expression); + std::string InferTypeFromBinaryExpression(ir::AstNode *expression); + std::string InferTypeFromOtherExpressions(ir::AstNode *expression); + std::string GenerateVariableDeclaration(const std::string &variableName, const std::string &variableType); + ir::AstNode *FindInsertionPoint(ir::AstNode *unresolvedNode, bool isThisProperty); + ir::AstNode *FindClassInsertionPoint(ir::AstNode *current); + ir::AstNode *FindFunctionInsertionPoint(ir::AstNode *current); + ir::AstNode *GetFunctionBody(ir::AstNode *node); + bool IsThisPropertyAccess(es2panda_Context *context, size_t pos); +}; + +} // namespace ark::es2panda::lsp + +#endif \ 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/add_missing_new_operator.h b/ets2panda/lsp/include/register_code_fix/add_missing_new_operator.h new file mode 100644 index 0000000000000000000000000000000000000000..8066643d074cbc5fab5ee71577aed40f807248bb --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/add_missing_new_operator.h @@ -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. + */ + +#ifndef FIX_ADD_MISSING_NEW_OPERATOR_H +#define FIX_ADD_MISSING_NEW_OPERATOR_H + +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" +#include +#include + +namespace ark::es2panda::lsp { +class FixAddMissingNewOperator : public CodeFixRegistration { +public: + FixAddMissingNewOperator(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + +private: + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + static bool IsValidTarget(const ir::AstNode *node); +}; + +} // namespace ark::es2panda::lsp +#endif // FIX_ADD_MISSING_NEW_OPERATOR_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/add_name_to_nameless_parameter.h b/ets2panda/lsp/include/register_code_fix/add_name_to_nameless_parameter.h new file mode 100644 index 0000000000000000000000000000000000000000..f761a26d056eaa002866a4db93c79f5f6e6359c6 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/add_name_to_nameless_parameter.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_NAME_TO_NAMELESS_PARAMETER_H +#define ADD_NAME_TO_NAMELESS_PARAMETER_H + +#include +#include +#include +#include "lsp/include/types.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" + +namespace ark::es2panda::lsp { +class AddNameToNamelessParameter : public CodeFixRegistration { +public: + AddNameToNamelessParameter(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + +private: + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + static bool IsIdentifier(const ir::AstNode *node); + static const ir::AstNode *FindParameterNode(const ir::AstNode *start); + static std::string GetNodeText(std::string_view fullSource, const ir::AstNode *node); +}; +} // namespace ark::es2panda::lsp +#endif // ADD_NAME_TO_NAMELESS_PARAMETER_H diff --git a/ets2panda/lsp/include/register_code_fix/constructor_for_derived_need_super_call.h b/ets2panda/lsp/include/register_code_fix/constructor_for_derived_need_super_call.h new file mode 100644 index 0000000000000000000000000000000000000000..f9809d9bc90c964beb90633ccb02f60b35f4ae1f --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/constructor_for_derived_need_super_call.h @@ -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. + */ + +#ifndef CONSTRUCTOR_FOR_DERIVED_NEED_SUPER_CALL_H +#define CONSTRUCTOR_FOR_DERIVED_NEED_SUPER_CALL_H + +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" +#include +#include + +namespace ark::es2panda::lsp { +class ConstructorDerivedNeedSuper : public CodeFixRegistration { +public: + ConstructorDerivedNeedSuper(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + +private: + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + static bool IsValidTarget(const ir::AstNode *node); + static const ir::AstNode *FindEnclosingClassNode(const ir::AstNode *start); + static ir::ClassDefinition *ExtractClassDefinition(const ir::AstNode *classNode); + static ir::MethodDefinition *GetConstructorMethodFromDefinition(ir::ClassDefinition *definition); + static bool NeedsSuperCall(ir::ScriptFunction *scriptFunc); + static ir::Statement *CreateSuperStatement(es2panda_Context *context); +}; +} // namespace ark::es2panda::lsp + +#endif // CONSTRUCTOR_FOR_DERIVED_NEED_SUPER_CALL_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/convert_const_to_let.h b/ets2panda/lsp/include/register_code_fix/convert_const_to_let.h new file mode 100644 index 0000000000000000000000000000000000000000..5ecc8d9259b8a144799e56f3ea635f128ab0bb93 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/convert_const_to_let.h @@ -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. + */ + +#ifndef CONVERT_CONST_TO_LET_H +#define CONVERT_CONST_TO_LET_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 { + +class FixConvertConstToLet : public CodeFixRegistration { +public: + FixConvertConstToLet(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForConvertConstToLet(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToConvertConstToLet(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/fix_add_function_return_statement.h b/ets2panda/lsp/include/register_code_fix/fix_add_function_return_statement.h new file mode 100644 index 0000000000000000000000000000000000000000..f7f5189a99a846d629d1fca45c4cfc2dfe00f2a3 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_add_function_return_statement.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_ADD_FUNCTION_RETURN_STATEMENT_H +#define FIX_ADD_FUNCTION_RETURN_STATEMENT_H + +#include +#include "../services/text_change/change_tracker.h" +#include "lsp/include/types.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "utils/arena_containers.h" + +namespace ark::es2panda::lsp { + +class FixAddFunctionReturnStatement : public CodeFixRegistration { +public: + FixAddFunctionReturnStatement(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &ctx) override; +}; + +struct Info { +private: + ark::es2panda::ir::AstNode *returnTypeNode_; + ark::es2panda::ir::AstNode *body_; + std::vector statements_; + +public: + Info(ark::es2panda::ir::AstNode *returnTypeNode, ark::es2panda::ir::AstNode *body, + std::vector statements) + : returnTypeNode_(returnTypeNode), body_(body), statements_(std::move(statements)) + { + } + ark::es2panda::ir::AstNode *GetReturnTypeNode() const + { + return returnTypeNode_; + } + ark::es2panda::ir::AstNode *GetBody() const + { + return body_; + } + const std::vector &GetStatements() const + { + return statements_; + } +}; + +ir::AstNode *FindAncessor(ir::AstNode *node); +Info GetInfo(es2panda_Context *context, size_t position); +void ReplaceReturnType(ChangeTracker &changes, es2panda_Context *context, Info &info); +void AddReturnStatement(ChangeTracker &changes, es2panda_Context *context, std::vector statements, + ir::AstNode *body); + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.h b/ets2panda/lsp/include/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.h new file mode 100644 index 0000000000000000000000000000000000000000..9fe286472fa54ba30e9718b3ed540eaa950528c9 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.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 FIX_CLASS_DOESNT_IMPLEMENT_INHERITED_ABSTRACT_MEMBER_H +#define FIX_CLASS_DOESNT_IMPLEMENT_INHERITED_ABSTRACT_MEMBER_H + +#include "lsp/include/code_fixes/code_fix_types.h" +#include "public/es2panda_lib.h" +#include "lsp/include/services/text_change/change_tracker.h" + +namespace ark::es2panda::lsp { + +class FixClassNotImplementingInheritedMembers : public CodeFixRegistration { +public: + FixClassNotImplementingInheritedMembers(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeTextChangeForNotImplementedMembers(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::string MakeNewText(ir::AstNode *node); + std::string MakeMethodSignature(ir::AstNode *node); + ir::AstNode *GetSuperClassDefinition(ir::AstNode *node); + std::vector GetCodeActionsForAbstractMissingMembers(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp + +#endif // FIX_CLASS_DOESNT_IMPLEMENT_INHERITED_ABSTRACT_MEMBER_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/fix_class_incorrectly_implements_interface.h b/ets2panda/lsp/include/register_code_fix/fix_class_incorrectly_implements_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..954f25160159b5542ff4c40382a411813ed2dcd5 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_class_incorrectly_implements_interface.h @@ -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. + */ + +#ifndef FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_H +#define FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_H + +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { + +class FixClassIncorrectlyImplementsInterface : public CodeFixRegistration { +public: + FixClassIncorrectlyImplementsInterface(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForMissingInterfaceMembers(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToImplementMissingMembers(const CodeFixContext &context); + + std::string MakeNewTextForMember(ir::AstNode *node); + std::vector FindMissingInterfaceMembers(ir::ClassDefinition *classDef); + std::vector GetInterfaceDefinitions(ir::ClassDefinition *classDef); + bool IsMemberImplemented(ir::ClassDefinition *classDef, const std::string &memberSignature); + + ir::AstNode *FindInterfaceDefinition(ir::TSClassImplements *implement); + void ProcessInterfaceMembers(ir::TSInterfaceDeclaration *interface, ir::ClassDefinition *classDef, + std::vector &missingMembers); + std::string GenerateMemberSignature(ir::MethodDefinition *methodDef, const std::string &memberName); + void GroupMissingMembers(const std::vector &missingMembers, + std::vector &missingGetters, std::vector &missingSetters); + void CreateCodeActionForType(const std::vector &members, const CodeFixContext &context, + bool isGetter, std::vector &returnedActions); +}; + +} // namespace ark::es2panda::lsp + +#endif // FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/fix_class_super_must_precede_this_access.h b/ets2panda/lsp/include/register_code_fix/fix_class_super_must_precede_this_access.h new file mode 100644 index 0000000000000000000000000000000000000000..05a016c1cd54308900b7d923f8db86f3a4c82b45 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_class_super_must_precede_this_access.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS_H +#define FIX_CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS_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 { + +class FixClassSuperMustPrecedeThisAccess : public CodeFixRegistration { +public: + FixClassSuperMustPrecedeThisAccess(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForClassSuperMustPrecedeThisAccess(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos); + std::vector GetCodeActionsForClassSuperMustPrecedeThisAccess(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/fix_expected_comma.h b/ets2panda/lsp/include/register_code_fix/fix_expected_comma.h new file mode 100644 index 0000000000000000000000000000000000000000..d1aea039ba220658cdf9d14f59f03ce2bb6ece13 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_expected_comma.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_EXPECTED_COMMA_H +#define FIX_EXPECTED_COMMA_H + +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/types.h" +#include "lsp/include/api.h" + +namespace ark::es2panda::lsp { + +class FixExpectedComma : public CodeFixRegistration { +public: + FixExpectedComma(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + static ir::AstNode *GetNodeAtLocation(es2panda_Context *context, Range range); + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, Range range, + const std::string &possibleFix); +}; +} // namespace ark::es2panda::lsp +#endif // FIX_EXPECTED_COMMA_H diff --git a/ets2panda/lsp/include/register_code_fix/fix_extends_interface_becomes_implements.h b/ets2panda/lsp/include/register_code_fix/fix_extends_interface_becomes_implements.h new file mode 100644 index 0000000000000000000000000000000000000000..b0ed6fd48c3bb4a254026dae2eaacbb840164b9e --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_extends_interface_becomes_implements.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_EXTENDS_INTERFACE_BECOMES_IMPLEMENTS_H +#define FIX_EXTENDS_INTERFACE_BECOMES_IMPLEMENTS_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 { + +class FixExtendsInterfaceBecomesImplements : public CodeFixRegistration { +public: + FixExtendsInterfaceBecomesImplements(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForExtendsInterfaceBecomesImplements(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos); + std::vector GetCodeActionsToExtendsInterfaceBecomesImplements(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/fix_import_non_exported_member.h b/ets2panda/lsp/include/register_code_fix/fix_import_non_exported_member.h new file mode 100644 index 0000000000000000000000000000000000000000..10ef49e69a348c44ded688e5d064f7f7d8449db8 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_import_non_exported_member.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_IMPORT_NON_EXPORTED_MEMBER_H +#define FIX_IMPORT_NON_EXPORTED_MEMBER_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 { + +class FixImportNonExportedMember : public CodeFixRegistration { +public: + FixImportNonExportedMember(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForImportNonExportedMember(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + bool FindImportDeclaration(ir::AstNode *&importDeclNode); + bool FindFunctionName(ir::AstNode *importDeclNode, util::StringView &functionName); + void ProcessExportPosition(ir::AstNode *funcDecl, const util::StringView &functionName, size_t &exportPosition, + ChangeTracker &changeTracker); + std::vector GetCodeActionsToImportNonExportedMember(const CodeFixContext &context); +}; + +} // 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/fix_remove_override_modifier.h b/ets2panda/lsp/include/register_code_fix/fix_remove_override_modifier.h new file mode 100644 index 0000000000000000000000000000000000000000..d924adbe1d7385715928ec2b6668227cc0ddd9b7 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_remove_override_modifier.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_REMOVE_OVERRIDE_MODIFIER_H +#define FIX_REMOVE_OVERRIDE_MODIFIER_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 { + +class FixRemoveOverrideModifier : public CodeFixRegistration { +public: + FixRemoveOverrideModifier(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForRemoveOverrideModifier(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToRemoveOverrideModifier(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp + +#endif // FIX_REMOVE_OVERRIDE_MODIFIER_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/fix_return_type_in_async_function.h b/ets2panda/lsp/include/register_code_fix/fix_return_type_in_async_function.h new file mode 100644 index 0000000000000000000000000000000000000000..11f34d634d1a58548d6f7173632c606ab999803c --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_return_type_in_async_function.h @@ -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. + */ +#ifndef FIX_RETURN_TYPE_IN_ASYNC_FUNCTION_H +#define FIX_RETURN_TYPE_IN_ASYNC_FUNCTION_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 { + +class FixReturnTypeInAsyncFunction : public CodeFixRegistration { +public: + FixReturnTypeInAsyncFunction(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) override; + std::vector GetChanges(const CodeFixContext &context); + ir::AstNode *GetFunctionReturnType(es2panda_Context *context, size_t position); + +private: + void MakeChangeReturnTypeInAsyncFunction(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); +}; + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/bindings/native/include/callback-resource.h b/ets2panda/lsp/include/register_code_fix/fix_spelling.h similarity index 38% rename from ets2panda/bindings/native/include/callback-resource.h rename to ets2panda/lsp/include/register_code_fix/fix_spelling.h index 5f8346fa78938505b8d5961a989ce90a8f34b834..dbaa22a9cbba326f01cfb75c797a2b9671af678e 100644 --- a/ets2panda/bindings/native/include/callback-resource.h +++ b/ets2panda/lsp/include/register_code_fix/fix_spelling.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,52 +13,48 @@ * limitations under the License. */ -#ifndef INTEROP_CALLBACK_RESOURCE_H -#define INTEROP_CALLBACK_RESOURCE_H +#ifndef FIX_SPELLING_H +#define FIX_SPELLING_H +#include #include -#include "interop-types.h" +#include +#include "lsp/include/code_fixes/code_fix_types.h" +#include "../services/text_change/change_tracker.h" -// NOLINTBEGIN +namespace ark::es2panda::lsp { -class CallbackResourceHolder { +class FixSpelling : public CodeFixRegistration { +public: + FixSpelling(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +struct Info { private: - std::vector heldResources; + std::string findClosestWord_; + ark::es2panda::ir::AstNode *node_; public: - void holdCallbackResource(const InteropCallbackResource *resource) + Info(std::string findClosestWord, ark::es2panda::ir::AstNode *node) + : findClosestWord_(std::move(findClosestWord)), node_(node) { - resource->hold(resource->resourceId); - this->heldResources.push_back(*resource); } - void release() + const std::string &GetFindClosestWord() const { - for (auto resource : this->heldResources) { - resource.release(resource.resourceId); - } - this->heldResources.clear(); + return findClosestWord_; + } + ark::es2panda::ir::AstNode *GetNode() const + { + return node_; } }; -struct CallbackBuffer { - InteropInt32 kind; - uint8_t buffer[60 * 4]; - CallbackResourceHolder resourceHolder; -}; - -enum CallbackEventKind { - EVENT_CALL_CALLBACK = 0, - EVENT_HOLD_MANAGED_RESOURCE = 1, - EVENT_RELEASE_MANAGED_RESOURCE = 2, -}; - -// CC-OFFNXT(G.NAM.01) false positive -void EnqueueCallback(const CallbackBuffer *event); -// CC-OFFNXT(G.NAM.01) false positive -void HoldManagedCallbackResource(InteropInt32 resourceId); -// CC-OFFNXT(G.NAM.01) false positive -void ReleaseManagedCallbackResource(InteropInt32 resourceId); - -// NOLINTEND +Info GetInfoSpelling(es2panda_Context *context, size_t position); +void DoChanges(ChangeTracker &changes, es2panda_Context *context, ir::AstNode *node, const std::string &target); +} // namespace ark::es2panda::lsp #endif diff --git a/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h b/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h new file mode 100644 index 0000000000000000000000000000000000000000..4bdcd028495c0c0c85064f55c12a641127f368a9 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_unreachable_code.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_UNREACHABLE_CODE_H +#define FIX_UNREACHABLE_CODE_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 { + +class FixUnreachableCode : public CodeFixRegistration { +public: + FixUnreachableCode(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForUnreachableCode(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos); + std::vector GetCodeActionsToRemoveUnreachableCode(const CodeFixContext &context); + TextRange HandleUnreachableAfterTerminator(ir::AstNode *stmt); + TextRange HandleUnreachableStatement(ir::AstNode *statement); +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h b/ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h new file mode 100644 index 0000000000000000000000000000000000000000..add5dcdfa74af79a18f05fc07c05ff19064b7cb4 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/forgotten_this_property_access.h @@ -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. + */ + +#ifndef FORGOTTEN_THIS_PROPERTY_ACCESS_H +#define FORGOTTEN_THIS_PROPERTY_ACCESS_H + +#include +#include +#include "lsp/include/code_fixes/code_fix_types.h" +#include "public/es2panda_lib.h" +#include "lsp/include/services/text_change/change_tracker.h" + +namespace ark::es2panda::lsp { + +class ForgottenThisPropertyAccess : public CodeFixRegistration { +public: + ForgottenThisPropertyAccess(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +struct Info { +private: + ark::es2panda::ir::AstNode *node_; + std::string className_; + +public: + Info(ark::es2panda::ir::AstNode *node, std::string className) : node_(node), className_(std::move(className)) {} + + ark::es2panda::ir::AstNode *GetNode() const + { + return node_; + } + const std::string &GetClassName() const + { + return className_; + } +}; + +Info GetInfoThisProp(es2panda_Context *context, size_t offset); +void DoChanges(es2panda_Context *context, ChangeTracker tracker); + +} // namespace ark::es2panda::lsp + +#endif // FORGOTTEN_THIS_PROPERTY_ACCESS_H \ No newline at end of file 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/register_code_fix/remove_accidental_call_parentheses.h b/ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h new file mode 100644 index 0000000000000000000000000000000000000000..ac1f7c17aef5faf3ab00380a01bcbad5be72f322 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H +#define FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H + +#include +#include +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class FixRemoveAccidentalCallParentheses : public CodeFixRegistration { +public: + FixRemoveAccidentalCallParentheses(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &ctx) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + +private: + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + bool static IsValidCallExpression(const ir::AstNode *node); + static TextRange CalculateDeleteRange(const ir::AstNode *callExpr); +}; +} // namespace ark::es2panda::lsp +#endif // FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H diff --git a/ets2panda/lsp/include/register_code_fix/ui_plugin_suggest.h b/ets2panda/lsp/include/register_code_fix/ui_plugin_suggest.h new file mode 100644 index 0000000000000000000000000000000000000000..27862f9b12738161247d6c5c1ec3d307bd9dd960 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/ui_plugin_suggest.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 IMPORT_FIXES_H +#define IMPORT_FIXES_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 UIPluginSuggest : public CodeFixRegistration { +public: + UIPluginSuggest(); + + static std::vector GetUIPluginCodeFixes(es2panda_Context *context, size_t pos, bool isAll); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/rename.h b/ets2panda/lsp/include/rename.h index 6ba6732036d8ddc06af624aefaa82f1156185e59..f872a51f05edb0f06cd269830b29b719a26469b7 100644 --- a/ets2panda/lsp/include/rename.h +++ b/ets2panda/lsp/include/rename.h @@ -22,7 +22,7 @@ #include #include -#include "api.h" +#include "types.h" #include "ir/astNode.h" #include "public/es2panda_lib.h" #include "checker/types/type.h" @@ -106,9 +106,9 @@ public: using RenameInfoType = std::variant; -RenameInfoType GetRenameInfo(es2panda_Context *context, size_t pos); +RenameInfoType GetRenameInfo(es2panda_Context *context, size_t pos, const std::string &pandaLibPath); std::optional GetRenameInfoForNode(ir::AstNode *node, checker::ETSChecker *checker, - parser::Program *program); + parser::Program *program, const std::string &pandaLibPath); std::optional GetContextualTypeFromParentOrAncestorTypeNode(ir::AstNode *node, checker::ETSChecker *checker); std::string GetTextOfNode(ir::AstNode *node, parser::Program *program); 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..d029a37b20d2e91925a4741ac043289b68aa373d --- /dev/null +++ b/ets2panda/lsp/include/services/text_change/change_tracker.h @@ -0,0 +1,248 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "es2panda.h" +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp/include/formatting/formatting.h" +#include "lsp/include/formatting/formatting_context.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/user_preferences.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include +#include +#include "text_change_context.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 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::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 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); + void RfindNearestKeyWordTextRange(const es2panda_Context *context, const size_t pos, + const std::string_view &keywordStr, TextRange &range); +}; + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/services/text_change/text_change_context.h b/ets2panda/lsp/include/services/text_change/text_change_context.h new file mode 100644 index 0000000000000000000000000000000000000000..861d7b877c74c8af65769a9983cc9944ebfe1a8c --- /dev/null +++ b/ets2panda/lsp/include/services/text_change/text_change_context.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 TEXT_CHANGE_H +#define TEXT_CHANGE_H + +#include "lsp/include/formatting/formatting.h" +#include "lsp/include/user_preferences.h" + +struct LanguageServiceHost { + std::string name = "lsp"; +}; + +struct TextChangesContext { + LanguageServiceHost host = {}; + ark::es2panda::lsp::FormatContext formatContext; + ark::es2panda::lsp::UserPreferences preferences; +}; + +#endif \ No newline at end of file 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..0c447ac0ff9128bbfccbf91cc44df642cefb3d0e 100644 --- a/ets2panda/lsp/include/suggestion_diagnostics.h +++ b/ets2panda/lsp/include/suggestion_diagnostics.h @@ -25,10 +25,12 @@ namespace ark::es2panda::lsp { -std::vector GetSuggestionDiagnosticsImpl(ir::AstNode *astNode); -void Check(ir::AstNode *node, std::vector &diag, std::unordered_map &visitedFunc); +std::vector GetSuggestionDiagnosticsImpl(ir::AstNode *astNode, es2panda_Context *context); +void Check(ir::AstNode *node, std::vector &diag, std::unordered_map &visitedFunc, + es2panda_Context *context); void AddConvertToAsyncFunctionDiagnostics(ir::AstNode *node, std::vector &diag, - std::unordered_map &visitedFunc); + std::unordered_map &visitedFunc, + es2panda_Context *context); bool IsConvertibleFunction(ir::AstNode *node, std::unordered_map &visitedFunc); bool HasReturnStatementWithPromiseHandler(ir::AstNode *node, std::unordered_map &visitedFunc); bool IsReturnStatementWithFixablePromiseHandler(ir::AstNode *node, std::unordered_map &visitedFunc); @@ -38,6 +40,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..dab625c4a96aa614b2564ccafdccd60fc86d794b --- /dev/null +++ b/ets2panda/lsp/include/types.h @@ -0,0 +1,314 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + +// 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 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..e354781aeacca35d4bf69ab84df6256eca5b85c9 100644 --- a/ets2panda/lsp/src/api.cpp +++ b/ets2panda/lsp/src/api.cpp @@ -17,41 +17,70 @@ #include #include #include -#include "compiler/lowering/util.h" +#include "class_hierarchy.h" +#include "get_node.h" +#include "lsp/include/organize_imports.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" +#include "get_name_or_dotted_name_span.h" +#include "get_signature.h" +#include "node_matchers.h" + +using ark::es2panda::lsp::details::GetCompletionEntryDetailsImpl; extern "C" { namespace ark::es2panda::lsp { DefinitionInfo GetDefinitionAtPosition(es2panda_Context *context, size_t position) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + auto importFilePath = GetImportFilePath(context, position); + if (!importFilePath.empty()) { + return {importFilePath, 0, 0}; + } auto declInfo = GetDefinitionAtPositionImpl(context, position); DefinitionInfo result {}; + if (declInfo.first == nullptr) { + return result; + } auto node = declInfo.first; + auto targetNode = declInfo.first->FindChild([&declInfo](ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == declInfo.second; + }); + std::string name; while (node != nullptr) { + if (node->Range().start.Program() != nullptr) { + name = std::string(node->Range().start.Program()->SourceFile().GetAbsolutePath().Utf8()); + break; + } if (node->IsETSModule()) { - auto name = std::string(node->AsETSModule()->Program()->SourceFilePath()); - auto targetNode = declInfo.first->FindChild([&declInfo](ir::AstNode *childNode) { - return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == declInfo.second; - }); - if (targetNode != nullptr) { - result = {name, targetNode->Start().index, targetNode->End().index - targetNode->Start().index}; - } + name = std::string(node->AsETSModule()->Program()->SourceFilePath()); break; } node = node->Parent(); } + if (targetNode != nullptr) { + result = {name, targetNode->Start().index, targetNode->End().index - targetNode->Start().index}; + } return result; } @@ -65,13 +94,25 @@ bool IsPackageModule(es2panda_Context *context) return reinterpret_cast(context)->parserProgram->IsPackage(); } +CompletionEntryKind GetAliasScriptElementKind(es2panda_Context *context, size_t position) +{ + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + auto result = GetAliasScriptElementKindImpl(context, position); + return result; +} + References GetFileReferences(char const *fileName, es2panda_Context *context, bool isPackageModule) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); return GetFileReferencesImpl(context, fileName, isPackageModule); } DeclInfo GetDeclInfo(es2panda_Context *context, size_t position) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); DeclInfo result; if (context == nullptr) { return result; @@ -83,8 +124,28 @@ DeclInfo GetDeclInfo(es2panda_Context *context, size_t position) return result; } +std::vector GetClassHierarchies(std::vector *contextList, + const char *fileName, size_t pos) +{ + auto *ctxList = reinterpret_cast *>(contextList); + for (auto *context : *ctxList) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + } + return GetClassHierarchiesImpl(contextList, std::string(fileName), pos); +} + +bool GetSafeDeleteInfo(es2panda_Context *context, size_t position) +{ + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + return GetSafeDeleteInfoImpl(context, position); +} + References GetReferencesAtPosition(es2panda_Context *context, DeclInfo *declInfo) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); auto result = GetReferencesAtPositionImpl(context, {declInfo->fileName, declInfo->fileText}); auto compare = [](const ReferenceInfo &lhs, const ReferenceInfo &rhs) { if (lhs.fileName != rhs.fileName) { @@ -102,29 +163,51 @@ References GetReferencesAtPosition(es2panda_Context *context, DeclInfo *declInfo es2panda_AstNode *GetPrecedingToken(es2panda_Context *context, const size_t pos) { auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); auto ast = ctx->parserProgram->Ast(); return reinterpret_cast(FindPrecedingToken(pos, ast, ctx->allocator)); } std::string GetCurrentTokenValue(es2panda_Context *context, size_t position) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); auto result = GetCurrentTokenValueImpl(context, position); return result; } +std::vector OrganizeImportsImpl(es2panda_Context *context, char const *fileName) +{ + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + auto result = OrganizeImports::Organize(context, fileName); + return result; +} + QuickInfo GetQuickInfoAtPosition(const char *fileName, es2panda_Context *context, size_t position) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); 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 ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + auto result = GetCompletionEntryDetailsImpl(context, position, fileName, entryName); + return result; +} + +TextSpan GetSpanOfEnclosingComment(es2panda_Context *context, size_t pos, bool onlyMultiLine) +{ + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + 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); @@ -134,6 +217,8 @@ DiagnosticReferences GetSemanticDiagnostics(es2panda_Context *context) { DiagnosticReferences result {}; auto ctx = reinterpret_cast(context); + ctx->diagnosticEngine->CleanDuplicateLog(util::DiagnosticType::SEMANTIC); + SetPhaseManager(ctx->phaseManager); const auto &diagnostics = ctx->diagnosticEngine->GetDiagnosticStorage(util::DiagnosticType::SEMANTIC); for (const auto &diagnostic : diagnostics) { result.diagnostic.push_back(CreateDiagnosticForError(context, *diagnostic)); @@ -145,10 +230,22 @@ DiagnosticReferences GetSyntacticDiagnostics(es2panda_Context *context) { DiagnosticReferences result {}; auto ctx = reinterpret_cast(context); + ctx->diagnosticEngine->CleanDuplicateLog(util::DiagnosticType::SYNTAX); + SetPhaseManager(ctx->phaseManager); const auto &diagnostics = ctx->diagnosticEngine->GetDiagnosticStorage(util::DiagnosticType::SYNTAX); + const auto &diagnosticsPluginError = + ctx->diagnosticEngine->GetDiagnosticStorage(util::DiagnosticType::PLUGIN_ERROR); + const auto &diagnosticsPluginWarning = + ctx->diagnosticEngine->GetDiagnosticStorage(util::DiagnosticType::PLUGIN_WARNING); for (const auto &diagnostic : diagnostics) { result.diagnostic.push_back(CreateDiagnosticForError(context, *diagnostic)); } + for (const auto &diagnostic : diagnosticsPluginError) { + result.diagnostic.push_back(CreateDiagnosticForError(context, *diagnostic)); + } + for (const auto &diagnostic : diagnosticsPluginWarning) { + result.diagnostic.push_back(CreateDiagnosticForError(context, *diagnostic)); + } return result; } @@ -179,6 +276,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 +289,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) @@ -198,6 +312,11 @@ std::vector FindReferencesWrapper( return res; } +RenameInfoType GetRenameInfoWrapper(es2panda_Context *context, size_t pos, const char *pandaLibPath) +{ + return GetRenameInfo(context, pos, std::string(pandaLibPath)); +} + std::vector GetBraceMatchingAtPositionWrapper(char const *fileName, size_t position) { Initializer initializer = Initializer(); @@ -208,34 +327,47 @@ std::vector GetBraceMatchingAtPositionWrapper(char const *fileName, si } std::vector FindRenameLocationsWrapper( - const std::vector &srcFiles, const ark::es2panda::SourceFile &srcFile, size_t position) + const std::vector &fileContexts, es2panda_Context *context, size_t position) { - auto tmp = FindRenameLocations(srcFiles, srcFile, position); - std::vector res(tmp.size()); - for (const auto &entry : tmp) { - res.emplace_back(entry); - } - return res; + auto locations = FindRenameLocations(fileContexts, context, position); + return std::vector {locations.begin(), locations.end()}; +} + +std::set FindRenameLocationsInCurrentFileWrapper(es2panda_Context *context, size_t position) +{ + return FindRenameLocationsInCurrentFile(context, position); +} + +bool NeedsCrossFileRenameWrapper(es2panda_Context *context, size_t position) +{ + return NeedsCrossFileRename(context, position); } std::vector FindRenameLocationsWithCancellationWrapper( - ark::es2panda::lsp::CancellationToken *tkn, const std::vector &srcFiles, - const ark::es2panda::SourceFile &srcFile, size_t position) + ark::es2panda::lsp::CancellationToken *tkn, const std::vector &fileContexts, + es2panda_Context *context, size_t position) { - auto tmp = FindRenameLocations(tkn, srcFiles, srcFile, position); - std::vector res(tmp.size()); - for (const auto &entry : tmp) { + auto locations = FindRenameLocations(tkn, fileContexts, context, position); + std::vector res(locations.size()); + for (const auto &entry : locations) { res.emplace_back(entry); } 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 {}; auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); auto ast = ctx->parserProgram->Ast(); - auto vec = GetSuggestionDiagnosticsImpl(ast); + auto vec = GetSuggestionDiagnosticsImpl(ast, context); res.diagnostic.reserve(vec.size()); for (const auto &diag : vec) { res.diagnostic.push_back(diag.diagnostic); @@ -245,43 +377,246 @@ DiagnosticReferences GetSuggestionDiagnostics(es2panda_Context *context) ark::es2panda::lsp::CompletionInfo GetCompletionsAtPosition(es2panda_Context *context, size_t position) { + auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); auto result = CompletionInfo(GetCompletionsAtPositionImpl(context, position)); 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 +std::vector GetApplicableRefactors(es2panda_Context *context, const char *kind, size_t position) +{ + RefactorContext refactorContext; + refactorContext.context = context; + refactorContext.kind = kind; + refactorContext.span.pos = position; + auto result = GetApplicableRefactorsImpl(&refactorContext); + 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) +{ + return ark::es2panda::lsp::GetSignature(context, position); +} + +size_t GetOffsetByColAndLine(const std::string &sourceCode, size_t line, size_t column) +{ + auto index = lexer::LineIndex(util::StringView(sourceCode)); + return index.GetOffset(lexer::SourceLocation(line, column, nullptr)); +} + +std::pair GetColAndLineByOffset(const std::string &sourceCode, size_t offset) +{ + auto index = lexer::LineIndex(util::StringView(sourceCode)); + return index.GetLocation(offset); +} + +std::vector GetCodeFixesAtPosition(es2panda_Context *context, size_t startPosition, + size_t endPosition, std::vector &errorCodes, + CodeFixOptions &codeFixOptions) +{ + auto result = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, startPosition, endPosition, errorCodes, codeFixOptions); + 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; +} + +TextSpan *GetNameOrDottedNameSpan(es2panda_Context *context, int startPos) +{ + auto result = ark::es2panda::lsp::GetNameOrDottedNameSpanImpl(context, startPos); + return result; +} + +es2panda_AstNode *GetProgramAst(es2panda_Context *context) +{ + return GetProgramAstImpl(context); +} + +std::vector GetNodeInfosByDefinitionData(es2panda_Context *context, size_t position) +{ + if (context == nullptr) { + return {}; + } + + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return {}; + } + + std::vector result; + while (node != nullptr) { + switch (node->Type()) { + case ir::AstNodeType::IDENTIFIER: + result.emplace_back(std::string(node->AsIdentifier()->Name()), ir::AstNodeType::IDENTIFIER); + break; + case ir::AstNodeType::CLASS_DEFINITION: + if (auto ident = node->AsClassDefinition()->Ident()) { + result.emplace_back(std::string(ident->Name()), ir::AstNodeType::CLASS_DEFINITION); + } + break; + default: + break; + } + node = node->Parent(); + } + return std::vector(result.rbegin(), result.rend()); +} + +es2panda_AstNode *GetClassDefinition(es2panda_AstNode *astNode, const std::string &nodeName) +{ + return GetClassDefinitionImpl(astNode, nodeName); +} + +es2panda_AstNode *GetIdentifier(es2panda_AstNode *astNode, const std::string &nodeName) +{ + return GetIdentifierImpl(astNode, nodeName); +} + +DefinitionInfo GetDefinitionDataFromNode(es2panda_Context *context, const std::vector &nodeInfos) +{ + DefinitionInfo result {"", 0, 0}; + if (context == nullptr || nodeInfos.empty()) { + return result; + } + auto ctx = reinterpret_cast(context); + auto rootNode = reinterpret_cast(ctx->parserProgram->Ast()); + if (rootNode == nullptr) { + return result; + } + + ir::AstNode *lastFoundNode = nullptr; + NodeInfo *lastNodeInfo = nullptr; + for (auto info : nodeInfos) { + auto foundNode = rootNode->FindChild([info](ir::AstNode *childNode) -> bool { + const auto &nodeMatchers = GetNodeMatchers(); + auto it = nodeMatchers.find(info->kind); + if (it != nodeMatchers.end()) { + return it->second(childNode, info); + } + return false; + }); + if (foundNode == nullptr) { + return {"", 0, 0}; + } + lastFoundNode = foundNode; + lastNodeInfo = info; + } + + if (lastFoundNode != nullptr && lastNodeInfo != nullptr) { + ir::AstNode *identifierNode = ExtractIdentifierFromNode(lastFoundNode, lastNodeInfo); + if (identifierNode != nullptr) { + result = {"", identifierNode->Start().index, identifierNode->End().index - identifierNode->Start().index}; + } else { + result = {"", lastFoundNode->Start().index, lastFoundNode->End().index - lastFoundNode->Start().index}; + } + } + + 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, + FindRenameLocationsInCurrentFileWrapper, + NeedsCrossFileRenameWrapper, FindRenameLocationsWithCancellationWrapper, + FindSafeDeleteLocation, FindReferencesWrapper, + GetRenameInfoWrapper, + GetClassPropertyInfoWrapper, GetSuggestionDiagnostics, GetCompletionsAtPosition, + GetClassHierarchyInfo, GetBraceMatchingAtPositionWrapper, + GetClassConstructorInfo, GetImplementationLocationAtPositionWrapper, - ToLineColumnOffsetWrapper}; + ToLineColumnOffsetWrapper, + GetTodoComments, + ProvideInlayHints, + GetSignatureHelpItems, + GetOffsetByColAndLine, + GetColAndLineByOffset, + GetCodeFixesAtPosition, + GetCombinedCodeFix, + GetNameOrDottedNameSpan, + GetProgramAst, + GetNodeInfosByDefinitionData, + GetClassDefinition, + GetIdentifier, + GetDefinitionDataFromNode}; } // 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..602cfeb76c8a38fd3139a3abc190aa102847003c --- /dev/null +++ b/ets2panda/lsp/src/applicable_refactors.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 +#include +#include "refactors/refactor_types.h" +#include "applicable_refactors.h" +#include "lsp/include/refactor_provider.h" +#include "refactors/convert_function.h" + +namespace ark::es2panda::lsp { + +std::vector GetApplicableRefactorsImpl(const RefactorContext *context) +{ + return RefactorProvider::Instance().GetApplicableRefactors(*context); +} +} // 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..0d7462903a014cd71262103376843168097784ab --- /dev/null +++ b/ets2panda/lsp/src/class_hierarchy.cpp @@ -0,0 +1,855 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 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); + if (partNode == nullptr || !partNode->IsIdentifier()) { + continue; + } + auto interfaceDecl = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (interfaceDecl->IsTSInterfaceDeclaration()) { + result.push_back(interfaceDecl->AsTSInterfaceDeclaration()); + } + } + return result; +} + +/** + * @brief (查找当前类的子类,或者当前接口的子接口) Finds direct descendants (subclasses or subinterfaces) of + * the given node + * @param context - Compiler context containing program AST + * @param node - Class or interface declaration node to find descendants for + * @return Vector of direct descendant nodes (subclasses or subinterfaces) + */ +std::vector FindDirectDescendants(es2panda_Context *context, const ir::AstNode *node) +{ + 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([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; + } + if (!IsChildNode(child, node)) { + return; + } + result.emplace_back(child); + }); + return result; +} + +/** + * @brief (查找当前接口的实现类) Finds classes that directly implement the given interface + * @param context - Compiler context containing program AST + * @param node - Interface declaration node + * @return Vector of class nodes that directly implement the interface + */ +std::vector FindDirectImplementingClasses(es2panda_Context *context, const ir::AstNode *node) +{ + std::vector result; + if (context == nullptr) { + return result; + } + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return result; + } + if (!node->IsTSInterfaceDeclaration()) { + return result; + } + auto astNode = reinterpret_cast(ctx->parserProgram->Ast()); + astNode->IterateRecursively([node, &result](ir::AstNode *child) { + if (child == nullptr || !child->IsClassDeclaration()) { + return; + } + auto name = GetHierarchyDeclarationName(child); + if (name.empty()) { + return; + } + auto fileName = GetHierarchyDeclarationFileName(child); + if (fileName.empty()) { + return; + } + auto impls = GetImplements(child->AsClassDeclaration()->Definition()); + for (auto impl : impls) { + if (GetIdentifierName(const_cast(impl)) == + GetIdentifierName(const_cast(node)) && + impl->Start().index == node->Start().index && + GetHierarchyDeclarationFileName(impl) == GetHierarchyDeclarationFileName(node)) { + result.emplace_back(child); + return; + } + } + }); + return result; +} + +/** + * + * @brief 如果当前node是接口类型,查找有哪些接口是继承或者间接的继承当前的接口;如果当前node是类,查找当前类的子类 + * 以及间接的实现类 + * Recursively collects all descendant nodes (subclasses/subinterfaces) + * @param contextList - List of compiler contexts to search + * @param node - Starting class/interface declaration node + * @param result - Output vector to store all descendant nodes + */ +void CollectAllDescendants(std::vector *contextList, const ir::AstNode *node, + std::vector &result) +{ + for (auto context : *contextList) { + auto rs = FindDirectDescendants(context, node); + result.insert(result.end(), rs.begin(), rs.end()); + for (auto subNode : rs) { + CollectAllDescendants(contextList, subNode, result); + } + } +} + +/** + * @brief 查找当前接口的实现类,或者间接的实现类 + * Recursively collects all implementing classes for an interface + * @param contextList - List of compiler contexts to search + * @param node - Starting interface declaration node + * @param result - Output vector to store implementing classes + */ +void CollectAllImplementingClasses(std::vector *contextList, const ir::AstNode *node, + std::vector &result) +{ + for (auto context : *contextList) { + auto rs = FindDirectImplementingClasses(context, node); + result.insert(result.end(), rs.begin(), rs.end()); + for (auto subNode : rs) { + CollectAllDescendants(contextList, subNode, result); + } + } +} + +/** + * @brief (查找当前类的父类) Find immediate superclass of current class node + * @param node - current class node 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. 查找当前类的(所有)父类) Find all superclasses of the current class node + * @param context - Compiler context (unused) + * @param node - Current class declaration node + * @return Vector of superclass nodes in inheritance order + */ +std::vector GetClassSuperClasses([[maybe_unused]] std::vector *contextList, + 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 (2. 查找当前类的(所有)子类) Find all possible implementing classes of current class node + * @param context - Compiler context containing program AST + * @param node - Current class declaration node + * @return Vector of all subclass nodes + */ +std::vector GetClassSubClasses(std::vector *contextList, ir::AstNode *node) +{ + std::vector result; + CollectAllDescendants(contextList, node, result); + return result; +} + +/** + * @brief (查找当前类的父接口) Find interface of current class node + * @param node - Current 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 (查找当前接口的父接口) Find which interfaces current interface node extends + * @param node - Current 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. 查找当前类的(所有)父接口) Find all interfaces extended by current class node + * @param context - Compiler context (unused) + * @param node - Current class declaration node + * @return Vector of implemented interface nodes + */ +std::vector GetClassImplementedInterfaces([[maybe_unused]] std::vector *contextList, + 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. 查找当前接口的(所有)父接口) Find all interfaces extended by current interface node + * @param context - Compiler context (unused) + * @param node - Current interface node + * @return Vector of ancestor interface nodes + */ +std::vector GetInterfaceSuperInterfaces([[maybe_unused]] std::vector *contextList, + 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 = currentNode->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 (5. 查找当前接口的(所有)子接口) Find all interfaces extended by current interface node + * @param context - Compiler context containing program AST + * @param node - Current interface node + * @return Vector of descendant interface nodes + */ +std::vector GetInterfaceSubInterfaces(std::vector *contextList, ir::AstNode *node) +{ + std::vector result; + CollectAllDescendants(contextList, node, result); + return result; +} + +/** + * @brief (6. 查找当前接口的(所有)子类) Find all interfaces current interface node extends & their corresponding + * implementation classes + * @param context - Compiler context containing program AST + * @param node - Current interface node + * @return Vector of implementing class nodes + */ +std::vector GetInterfaceImplementingClasses(std::vector *contextList, + ir::AstNode *node) +{ + std::vector result; + CollectAllImplementingClasses(contextList, node, result); + return result; +} + +/** + * @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]] std::vector *contextList, 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) +{ + return GetIdentifierName(a) == GetIdentifierName(b); +} + +/** + * @brief Compares member matches and records matched and unmatched items + * @param currentMembers the list of members in the current class + * @param targetMembers the list of members in the target class + * @param matchedContainer the container to record matched members + * @param unmatchedContainer the container to record unmatched members + * @param fileName the file name, used for recording location information + */ +void CompareMembersCommon(const std::vector ¤tMembers, + const std::vector &targetMembers, + std::vector &matchedContainer, + std::vector &unmatchedContainer, + [[maybe_unused]] 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; + std::string fileNamePath(currentMember->Start().ToLocation().Program()->SourceFilePath()); + matchedContainer.emplace_back(fileNamePath, currentMember->Start().index, kind); + break; + } + } + if (!isMatch) { + std::string fileNamePath(targetMember->Start().ToLocation().Program()->SourceFilePath()); + unmatchedContainer.emplace_back(fileNamePath, 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)(std::vector *, ir::AstNode *); + ClassRelationKind kind; + bool swapCompareArgs; + void (*compareFunc)(const std::vector &, const std::vector &, + ClassHierarchyItemInfo &, const std::string &); +}; + +void ProcessItems(std::vector *contextList, ir::AstNode *node, const std::string &fileName, + const ProcessItemsParams ¶ms) +{ + auto itemList = params.getListFunc(contextList, node); + for (auto *item : itemList) { + std::string name = GetIdentifierName(item); + ClassHierarchyItemInfo info(name, params.kind, item->Start().index); + auto itemMembers = GetMembers(contextList, 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(std::vector *contextList, + [[maybe_unused]] const std::string &fileName, size_t pos) +{ + std::vector result; + if (contextList->empty()) { + return result; + } + auto classNode = GetTargetDeclarationNodeByPosition(contextList->at(0), pos); + if (classNode == nullptr) { + return result; + } + std::vector currentMembers = GetMembers(contextList, classNode); + if (classNode->IsClassDeclaration()) { + ProcessItems(contextList, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassSuperClasses, ClassRelationKind::CLASS, false, + CompareMembersForOverride}); + ProcessItems(contextList, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassImplementedInterfaces, + ClassRelationKind::INTERFACE, false, CompareMembersForImplementation}); + ProcessItems(contextList, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassSubClasses, ClassRelationKind::CLASS, true, + CompareMembersForOverride}); + } else if (classNode->IsTSInterfaceDeclaration()) { + ProcessItems(contextList, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetInterfaceSuperInterfaces, + ClassRelationKind::INTERFACE, false, CompareMembersForOverride}); + ProcessItems(contextList, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetInterfaceSubInterfaces, + ClassRelationKind::INTERFACE, true, CompareMembersForOverride}); + ProcessItems(contextList, 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..94aa7c9c7aac1905b049b7f48e5abd194bf4850b --- /dev/null +++ b/ets2panda/lsp/src/class_hierarchy_info.cpp @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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" +#include "quick_info.h" + +namespace ark::es2panda::lsp { +std::string GetNameFromIdentifierNode(const ir::AstNode *node) +{ + if (node == nullptr || !node->IsIdentifier()) { + return ""; + } + return node->AsIdentifier()->ToString(); +} + +// 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 SplicePropertyDetailStr(const std::string &name, const std::string &type) +{ + if (name.empty() || type.empty()) { + return ""; + } + return name + ": " + type; +} + +std::string GetFunctionNameFromScriptFunction(const ir::ScriptFunction *function) +{ + if (function == nullptr || function->Id() == 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 *it : nodeParams) { + if (it == nullptr || !it->IsETSParameterExpression()) { + continue; + } + std::string paramName; + std::string paramKind; + auto nodeParam = it->AsETSParameterExpression(); + if (nodeParam->IsRestParameter()) { + paramName = nodeParam->RestParameter()->ToString(); + } else { + paramName = GetNameFromIdentifierNode(nodeParam->Ident()); + } + if (paramName == INVALID_EXPRESSION || nodeParam->TypeAnnotation() == nullptr) { + continue; + } + paramKind = GetNameForTypeNode(nodeParam->TypeAnnotation()); + params.emplace_back(FunctionParamStyle(std::move(paramName), std::move(paramKind))); + } + return params; +} + +std::string GetReturnTypeFromScriptFunction(const ir::ScriptFunction *function) +{ + if (function == nullptr) { + return ""; + } + auto returnNode = function->ReturnTypeAnnotation(); + if (returnNode == nullptr) { + return ""; + } + auto returnType = GetNameForTypeNode(returnNode); + return returnType; +} + +SetterStyle CreateSetterStyle(ir::MethodDefinitionKind kind) +{ + SetterStyle setter = SetterStyle::NONE; + 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(access, std::move(detail), setter); + item->SetFunctionName(funcName); + return item; +} + +std::shared_ptr CreateClassPropertyItem(const ir::ClassProperty *property, + const std::string &propertyName, std::string detail) +{ + if (property == nullptr || propertyName.empty() || detail.empty()) { + return nullptr; + } + AccessModifierStyle access = AccessModifierStyle::PUBLIC; + if (property->IsProtected()) { + access = AccessModifierStyle::PROTECTED; + } + auto item = std::make_shared(access, std::move(detail)); + item->SetVariableName(propertyName); + 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); +} + +ir::Identifier *GetIdentFromNewClassExprPart(const ir::Expression *value) +{ + if (value == nullptr || !value->IsETSNewClassInstanceExpression()) { + return nullptr; + } + auto typeRef = value->AsETSNewClassInstanceExpression()->GetTypeRef(); + if (typeRef == nullptr || !typeRef->IsETSTypeReference()) { + return nullptr; + } + auto part = typeRef->AsETSTypeReference()->Part(); + if (part == nullptr) { + return nullptr; + } + return part->GetIdent(); +} + +std::shared_ptr ParsePropertyStyleWithCreateItem(const ir::ClassProperty *property, + bool isCurrentToken) +{ + if (property == nullptr) { + return nullptr; + } + if ((isCurrentToken && property->IsStatic()) || + (!isCurrentToken && (property->IsPrivate() || property->IsStatic()))) { + return nullptr; + } + std::string propertyName = GetNameFromIdentifierNode(property->Key()); + std::string type; + if (property->TypeAnnotation() == nullptr) { + auto value = property->Value(); + auto ident = GetIdentFromNewClassExprPart(value); + type = GetNameFromIdentifierNode(ident); + } else { + type = GetNameForTypeNode(property->TypeAnnotation()); + } + if (propertyName == INVALID_EXPRESSION || type == INVALID_EXPRESSION) { + return nullptr; + } + auto detail = SplicePropertyDetailStr(propertyName, type); + return CreateClassPropertyItem(property, propertyName, detail); +} + +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) { + continue; + } + if (node->IsMethodDefinition()) { + auto methodDefinition = node->AsMethodDefinition(); + if (methodDefinition == nullptr) { + continue; + } + auto item = ParseFunctionStyleWithCreateItem(methodDefinition, isCurrentToken); + result.AddItemToMethodList(item); + auto overLoads = methodDefinition->Overloads(); + for (const auto *overLoadMethodDefinition : overLoads) { + auto overLoadItem = ParseFunctionStyleWithCreateItem(overLoadMethodDefinition, isCurrentToken); + result.AddItemToMethodList(overLoadItem); + } + } else if (node->IsClassProperty()) { + auto property = node->AsClassProperty(); + if (property == nullptr) { + continue; + } + auto item = ParsePropertyStyleWithCreateItem(property, isCurrentToken); + result.AddItemToPropertyList(item); + } + } + 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.GetMethodItemList(); + for (const auto &method : deriveMethods) { + superInfo.DeleteTargetItemInMethodList(method.second); + } + auto deriveProperties = deriveInfo.GetPropertyItemList(); + for (const auto &property : deriveProperties) { + superInfo.DeleteTargetItemInPropertyList(property.second); + } +} + +void FillBaseClassHierarchyInfo(const ClassHierarchyInfo &extraInfo, ClassHierarchyInfo &baseInfo) +{ + auto extraMethods = extraInfo.GetMethodItemList(); + for (const auto &method : extraMethods) { + baseInfo.AddItemToMethodList(method.second); + } + auto extraProperties = extraInfo.GetPropertyItemList(); + for (const auto &property : extraProperties) { + baseInfo.AddItemToPropertyList(property.second); + } +} + +void ProcessClassHierarchy(const ir::AstNode *token, 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.GetMethodItemList().empty() || !info.GetPropertyItemList().empty())) { + result.emplace_back(info); + FillBaseClassHierarchyInfo(info, baseInfo); + } + } + 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..ba0150a57572a4a7d0c7772af9b6802d503b98f3 --- /dev/null +++ b/ets2panda/lsp/src/code_fix_provider.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "generated/code_fix_register.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +// Registers a new code fix and maps it to its diagnostic error codes and fix IDs +void CodeFixProvider::RegisterCodeFix(const std::string &aliasName, std::unique_ptr registration) +{ + (void)aliasName; + ASSERT(!aliasName.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) +{ + // This function is a placeholder for future implementation of string formatting with arguments. + return text; +} + +std::string CodeFixProvider::DiagnosticToString(const codefixes::DiagnosticCode &diag) +{ + return std::string(diag.GetMessage()); +} + +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}; +} + +// Creates a code fix action that doesn't include fix-all functionality +CodeFixAction CodeFixProvider::CreateCodeFixActionWithoutFixAll(std::string &fixName, + std::vector &changes, + codefixes::DiagnosticCode &diagCode) +{ + std::string fixId; + std::string descriptionMessage = DiagnosticToString(diagCode); + std::string fixAllDescription; + return CreateCodeFixActionWorker(fixName, descriptionMessage, changes, fixId, fixAllDescription, {}); +} + +// Creates a full code fix action with fix-all and commands +CodeFixAction CodeFixProvider::CreateCodeFixAction(std::string fixName, std::vector changes, + codefixes::DiagnosticCode diagCode, std::string fixId, + std::vector &command) +{ + auto descriptionMessage = std::string(diagCode.GetMessage()); + std::string fixAllDescriptionMessage = "Fix all: " + std::string(diagCode.GetMessage()); + + 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; +} + +std::unique_ptr CodeFixProvider::GetDiagnostics(const CodeFixContextBase &context) +{ + LSPAPI const *lspApi = GetImpl(); + ES2PANDA_ASSERT(lspApi != nullptr); + Initializer initializer = Initializer(); + auto it = reinterpret_cast(context.context); + ES2PANDA_ASSERT(it != nullptr && it->sourceFile != nullptr); + const std::string_view fileName(it->sourceFile->filePath); + const std::string_view source(it->sourceFile->source); + const auto ctx = initializer.CreateContext(fileName.data(), ES2PANDA_STATE_CHECKED, source.data()); + auto [semantic, syntactic, suggestions] = + std::make_tuple(lspApi->getSemanticDiagnostics(ctx), lspApi->getSyntacticDiagnostics(ctx), + lspApi->getSuggestionDiagnostics(ctx)); + + auto result = std::make_unique(); + result->diagnostic.reserve(semantic.diagnostic.size() + syntactic.diagnostic.size() + + suggestions.diagnostic.size()); + std::move(semantic.diagnostic.begin(), semantic.diagnostic.end(), std::back_inserter(result->diagnostic)); + std::move(syntactic.diagnostic.begin(), syntactic.diagnostic.end(), std::back_inserter(result->diagnostic)); + std::move(suggestions.diagnostic.begin(), suggestions.diagnostic.end(), std::back_inserter(result->diagnostic)); + initializer.DestroyContext(ctx); + return result; +} + +// Determines whether fix-all should be enabled for this registration based on diagnostic count +bool CodeFixProvider::ShouldIncludeFixAll(const CodeFixRegistration ®istration, + const std::vector &diagnostics) +{ + int maybeFixableDiagnostics = 0; + const int minFixableDiagnostics = 1; + for (const auto &diag : diagnostics) { + if (std::holds_alternative(diag.code_) && + std::find(registration.GetErrorCodes().begin(), registration.GetErrorCodes().end(), + std::get(diag.code_)) != registration.GetErrorCodes().end()) { + ++maybeFixableDiagnostics; + if (maybeFixableDiagnostics > minFixableDiagnostics) { + break; + } + } + } + return maybeFixableDiagnostics > minFixableDiagnostics; +} + +// Returns all fixes associated with a fixId (used for fix-all) +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); +} + +// Iterates through diagnostics matching given error codes and applies callback on each +void CodeFixProvider::EachDiagnostic(const CodeFixAllContext &context, const std::vector &errorCodes, + const std::function &cb) +{ + if (errorCodes.empty()) { + return; + } + + auto diagnostics = GetDiagnostics(context); + if (diagnostics == nullptr) { + return; + } + + auto it = reinterpret_cast(context.context); + ES2PANDA_ASSERT(it != nullptr && it->sourceFile != nullptr); + auto *parserProgram = it->parserProgram; + auto index = lexer::LineIndex(parserProgram->SourceCode()); + + for (auto &diag : diagnostics->diagnostic) { + auto isTargetError = [&diag](int code) { + return std::holds_alternative(diag.code_) && std::get(diag.code_) == code; + }; + if (!std::any_of(errorCodes.begin(), errorCodes.end(), isTargetError)) { + continue; + } + + size_t startOffset = index.GetOffset( + lexer::SourceLocation(diag.range_.start.line_, diag.range_.start.character_, parserProgram)); + size_t endOffset = + index.GetOffset(lexer::SourceLocation(diag.range_.end.line_, diag.range_.end.character_, parserProgram)); + + ES2PANDA_ASSERT(endOffset >= startOffset); + size_t length = endOffset - startOffset; + auto diagWithLocate = DiagnosticWithLocation(std::move(diag), *it->sourceFile, startOffset, length); + cb(diagWithLocate); + } +} + +// Returns applicable fix actions for a given error code +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); + result.insert(result.end(), actions.begin(), actions.end()); + } + } + return result; +} + +// Applies fix-all logic using a callback for each matching diagnostic +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 \ No newline at end of file diff --git a/ets2panda/lsp/src/completions.cpp b/ets2panda/lsp/src/completions.cpp index 099804f8270e9181b856f2d8cf844f2400ae865f..bfbf76171047b911ed3558a661ec668ae67f914b 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_$\-]*(\?)?\.$)"); @@ -224,17 +303,9 @@ ir::AstNode *GetClassDefinitionFromClassProperty(ir::AstNode *node) return nullptr; } auto value = node->AsClassProperty()->Value(); - if (value != nullptr && value->IsETSNewClassInstanceExpression() && - 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 ident = GetIdentFromNewClassExprPart(value); + if (ident != nullptr) { + return compiler::DeclarationFromIdentifier(ident); } auto type = node->AsClassProperty()->TypeAnnotation(); if (type != nullptr && type->IsETSTypeReference()) { @@ -345,12 +416,19 @@ std::vector GetCompletionFromClassDefinition(ir::ClassDefinitio return res; } -ir::AstNode *GetIdentifierFromTSInterfaceHeritage(ir::TSInterfaceHeritage *extend) +ir::AstNode *GetIdentifierFromTSInterfaceHeritage(ir::AstNode *node) { - if (extend == nullptr) { + 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; } - auto expr = extend->Expr(); if (expr == nullptr) { return nullptr; } @@ -376,6 +454,9 @@ std::vector GetCompletionFromTSInterfaceDeclaration(ir::TSInter auto ident = GetIdentifierFromTSInterfaceHeritage(extend); if (ident != nullptr && ident->IsIdentifier()) { auto extendInterf = compiler::DeclarationFromIdentifier(ident->AsIdentifier()); + if (extendInterf == nullptr) { + continue; + } auto extendCom = extendInterf->IsTSInterfaceDeclaration() ? GetCompletionFromTSInterfaceDeclaration(extendInterf->AsTSInterfaceDeclaration(), triggerWord) @@ -393,11 +474,11 @@ std::vector GetCompletionFromMethodDefinition(ir::MethodDefinit const std::string &triggerWord) { auto value = decl->AsMethodDefinition()->Value(); - if (value == nullptr && !value->IsFunctionExpression()) { + if (value == nullptr || !value->IsFunctionExpression()) { return {}; } auto func = value->AsFunctionExpression()->Function(); - if (func == nullptr && func->ReturnTypeAnnotation() == nullptr) { + if (func == nullptr || func->ReturnTypeAnnotation() == nullptr) { return {}; } auto returnType = func->ReturnTypeAnnotation(); @@ -426,6 +507,70 @@ ir::AstNode *GetIndentifierFromCallExpression(ir::AstNode *node) 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; @@ -435,6 +580,9 @@ std::vector GetPropertyCompletions(ir::AstNode *preNode, const if (preNode->IsCallExpression()) { preNode = GetIndentifierFromCallExpression(preNode); } + if (preNode->IsThisExpression()) { + return GetCompletionFromThisExpression(preNode, triggerWord); + } if (!preNode->IsIdentifier()) { return completions; } @@ -488,7 +636,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) @@ -539,19 +687,19 @@ CompletionEntry InitEntry(const ir::AstNode *decl) } else if (IsConstVar(decl)) { kind = CompletionEntryKind::CONSTANT; } else if (IsGlobalVar(decl)) { - auto globalDefiniton = decl->Parent()->AsClassDefinition(); - auto initMethod = globalDefiniton->FindChild([](ir::AstNode *child) { - return child->IsMethodDefinition() && - child->AsMethodDefinition()->Key()->AsIdentifier()->Name() == compiler::Signatures::INIT_METHOD; + auto globalDefinition = decl->Parent()->AsClassDefinition(); + auto cctor = globalDefinition->FindChild([&globalDefinition](ir::AstNode *child) { + return child->IsClassStaticBlock() && child->Parent()->IsClassDefinition() && + child->Parent()->AsClassDefinition() == globalDefinition; }); - if (initMethod == nullptr) { + if (cctor == nullptr) { return CompletionEntry(name, CompletionEntryKind::CONSTANT, std::string(sortText)); } - auto found = initMethod->FindChild([&name](ir::AstNode *child) { + auto found = cctor->FindChild([&name](ir::AstNode *child) { return child->IsAssignmentExpression() && child->AsAssignmentExpression()->Left()->IsIdentifier() && child->AsAssignmentExpression()->Left()->AsIdentifier()->ToString() == name; }); - if (found != nullptr) { + if (found != nullptr && !decl->AsClassProperty()->IsConst()) { // let variable in global definition need to be assigned in _$init$_ method kind = CompletionEntryKind::VARIABLE; } else { @@ -563,6 +711,58 @@ CompletionEntry InitEntry(const ir::AstNode *decl) return CompletionEntry(name, kind, std::string(sortText)); } +bool IsAnnotationBeginning(std::string sourceCode, size_t pos) +{ + return sourceCode.at(pos - 1) == '@'; +} + +std::vector GetAnnotationCompletions(es2panda_Context *context, size_t pos, + ir::AstNode *node = nullptr) +{ + std::vector completions; + auto ctx = reinterpret_cast(context); + auto ast = ctx->parserProgram->Ast(); + auto importStatements = std::vector(); + auto annotationDeclarations = std::vector(); + for (auto &statement : ast->Statements()) { + if (statement != nullptr && statement->IsETSImportDeclaration()) { + importStatements.push_back(statement); + } + if (statement != nullptr && statement->Range().end.index < pos && statement->IsAnnotationDeclaration()) { + annotationDeclarations.push_back(statement); + } + } + auto addAnnotationCompletion = [&completions, &node](const std::string &name) { + if (node == nullptr || + (node->IsIdentifier() && name.find(node->AsIdentifier()->Name().Utf8()) != std::string::npos)) { + completions.emplace_back(name, CompletionEntryKind::ANNOTATION, + std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + }; + for (auto &import : importStatements) { + auto specifiers = import->AsETSImportDeclaration()->Specifiers(); + for (auto &specifier : specifiers) { + std::string localName; + ir::AstNode *decl = nullptr; + if (specifier->IsImportSpecifier()) { + localName = std::string(specifier->AsImportSpecifier()->Local()->AsIdentifier()->Name()); + decl = compiler::DeclarationFromIdentifier(specifier->AsImportSpecifier()->Imported()); + } else if (specifier->IsImportDefaultSpecifier()) { + localName = std::string(specifier->AsImportDefaultSpecifier()->Local()->AsIdentifier()->Name()); + decl = compiler::DeclarationFromIdentifier(specifier->AsImportDefaultSpecifier()->Local()); + } + if (decl != nullptr && decl->IsAnnotationDeclaration()) { + addAnnotationCompletion(localName); + } + } + } + for (auto &annotation : annotationDeclarations) { + auto annotationName = std::string(annotation->AsAnnotationDeclaration()->GetBaseName()->Name()); + addAnnotationCompletion(annotationName); + } + return completions; +} + void GetIdentifiersInScope(const varbinder::Scope *scope, size_t position, ArenaVector &results) { if (scope->Node() == nullptr) { @@ -615,8 +815,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); @@ -626,6 +824,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; } @@ -670,11 +874,17 @@ std::vector GetCompletionsAtPositionImpl(es2panda_Context *cont } auto allocator = ctx->allocator; std::string sourceCode(ctx->parserProgram->SourceCode()); + if (IsAnnotationBeginning(sourceCode, pos)) { + return GetAnnotationCompletions(context, pos); // need to filter annotation + } // Current GetPrecedingPosition cannot get token of "obj." with position. auto precedingToken = FindPrecedingToken(pos, ctx->parserProgram->Ast(), allocator); if (precedingToken == nullptr) { return {}; } + if (IsAnnotationBeginning(sourceCode, precedingToken->Start().index)) { + return GetAnnotationCompletions(context, pos, precedingToken); // need to filter annotation + } auto triggerValue = GetCurrentTokenValueImpl(context, pos); // Unsupported yet because of ast parsing problem if (IsEndWithValidPoint(triggerValue)) { diff --git a/ets2panda/lsp/src/completions_details.cpp b/ets2panda/lsp/src/completions_details.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c2c29da6cc058b5cad1ea902ff97218f66858192 --- /dev/null +++ b/ets2panda/lsp/src/completions_details.cpp @@ -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. + */ + +#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, checker::ETSChecker *checker) +{ + if (IsClass(node)) { + displayParts = ark::es2panda::lsp::CreateDisplayForClass(node); + } else if (node->IsETSParameterExpression()) { + displayParts = ark::es2panda::lsp::CreateDisplayForETSParameterExpression(node); + } else if (node->IsClassProperty()) { + // 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); + } else { + displayParts = ark::es2panda::lsp::CreateDisplayForClassProperty(node); + } + } else if (node->IsTSInterfaceDeclaration()) { + displayParts = ark::es2panda::lsp::CreateDisplayForInterface(node); + } else if (node->IsTSTypeAliasDeclaration()) { + displayParts = ark::es2panda::lsp::CreateDisplayForTypeAlias(node); + } else if (node->IsTSEnumDeclaration()) { + displayParts = ark::es2panda::lsp::CreateDisplayForEnum(node); + } else if (node->IsImportDeclaration()) { + displayParts = CreateDisplayForImportDeclaration(node); + } else if (node->IsTSTypeParameter()) { + displayParts = ark::es2panda::lsp::CreateDisplayForTypeParameter(node); + } else if (node->IsMethodDefinition()) { + displayParts = ark::es2panda::lsp::CreateDisplayForMethodDefinition(node, kindModifiers, checker); + } + // Unify this kind + kind = GetNodeKindForRenameInfo(node); +} + +CompletionEntryDetails GetCompletionEntryDetails(ir::AstNode *node, const std::string &entryName, + const std::string &fileName, checker::ETSChecker *checker) +{ + 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, checker); + + 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 checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto leIdentifier = + ast->FindChild([entryName](ir::AstNode *node) { return HasPropertyAccessExpressionWithName(node, entryName); }); + if (leIdentifier == nullptr || !leIdentifier->IsIdentifier()) { + return CompletionEntryDetails(); + } + auto targetNode = compiler::DeclarationFromIdentifier(leIdentifier->AsIdentifier()); + if (targetNode == nullptr) { + return CompletionEntryDetails(); + } + return GetCompletionEntryDetails(targetNode, entryName, fileName, checker); +} + +} // 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_references.cpp b/ets2panda/lsp/src/find_references.cpp index 6a5e74324f8b1d3b23baa0fd201402f23da542a1..1e7ad083a58fc0d07caa23d1f882ede9557685a1 100644 --- a/ets2panda/lsp/src/find_references.cpp +++ b/ets2panda/lsp/src/find_references.cpp @@ -138,6 +138,44 @@ std::set FindReferences(const ark::es2panda: initializer.DestroyContext(context); return res; } + +std::set FindReferences(es2panda_Context *context, LocationId tokenLocationId, + std::string tokenName) +{ + auto ctx = reinterpret_cast(context); + auto filePath = std::string {ctx->sourceFile->filePath}; + + // Clear before searching each file + std::set res; + ark::es2panda::parser::Program *pprogram = nullptr; + auto cb = [&tokenName, &pprogram, &filePath, &tokenLocationId, &res](ark::es2panda::ir::AstNode *node) { + if (!node->IsIdentifier()) { + return false; + } + auto nodeName = ::GetIdentifierName(node); + if (nodeName != tokenName) { + return false; + } + auto owner = GetOwner(node); + auto nodeOwnerLocationId = GetLocationId(owner, pprogram); + auto nodeLocationId = GetLocationId(node, pprogram); + bool isDefinition = nodeLocationId == nodeOwnerLocationId; + if (nodeOwnerLocationId == tokenLocationId) { + res.insert(ark::es2panda::lsp::ReferencedNode {filePath, node->Start().index, node->End().index, + node->Start().line, isDefinition}); + } + return false; + }; + + auto ast = ctx->parserProgram->Ast(); + if (ast == nullptr) { + return res; + } + pprogram = ctx->parserProgram; + ast->FindChild(cb); + + return res; +} } // namespace namespace ark::es2panda::lsp { @@ -182,4 +220,37 @@ std::set FindReferences(CancellationToken *tkn, const std::vecto return res; } + +std::set FindReferences(CancellationToken *tkn, const std::vector &fileContexts, + es2panda_Context *context, size_t position) +{ + std::string tokenName; + LocationId tokenLocationId; + // Part 1: Determine the type of token function/variable + { + auto ctx = reinterpret_cast(context); + + auto touchingToken = GetTouchingToken(context, position, false); + tokenName = ::GetIdentifierName(touchingToken); + auto owner = GetOwner(touchingToken); + tokenLocationId = ::GetLocationId(owner, ctx->parserProgram); + } + + if (tokenLocationId.empty()) { + return {}; + } + + std::set res; + for (auto fc : fileContexts) { + // NOTE(muhammet): Need for more fine grained cancellation check but for now doing it before context + // creations + // should be good enough, thats where it's slowest + if (tkn->IsCancellationRequested()) { + return res; + } + res.merge(::FindReferences(fc, tokenLocationId, tokenName)); + } + + return res; +} } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/find_rename_locations.cpp b/ets2panda/lsp/src/find_rename_locations.cpp index 8aa93075085c625d1dcd6eaef28b8f06d012dc79..89c14f2ce95ced85232cc2a77870539b27f8231f 100644 --- a/ets2panda/lsp/src/find_rename_locations.cpp +++ b/ets2panda/lsp/src/find_rename_locations.cpp @@ -18,58 +18,115 @@ #include #include +#include "compiler/lowering/util.h" #include "find_rename_locations.h" #include "find_references.h" +#include "internal_api.h" +#include "public/public.h" namespace ark::es2panda::lsp { -std::set FindRenameLocations(CancellationToken *tkn, - const std::vector &files, - const ark::es2panda::SourceFile &file, size_t position) +bool IsImported(ir::AstNode *node) { - auto references = FindReferences(tkn, files, file, position); - std::set res; + if (node == nullptr || !node->IsIdentifier()) { + return false; + } + auto parent = node->Parent(); + if (parent == nullptr) { + return false; + } + return parent->IsImportSpecifier(); +} - for (auto ref : references) { - auto srcIt = std::find_if(files.begin(), files.end(), [&ref](const SourceFile ¤tFile) { - return currentFile.filePath == ref.filePath; - }); - if (srcIt == files.end()) { - std::cout << "Error: Could not find " << ref.filePath << " in list!\n"; - continue; - } - std::string source = std::string {srcIt->source}; - // Get prefix and suffix texts - std::string prefix; - { - auto end = source.begin() + ref.start; - auto beg = end; - while (beg > source.begin() && *(beg - 1) != '\n') { - --beg; +bool NeedsCrossFileRename(es2panda_Context *context, size_t position) +{ + auto ctx = reinterpret_cast(context); + auto touchingToken = GetTouchingToken(context, position, false); + if (touchingToken == nullptr || !touchingToken->IsIdentifier()) { + return false; + } + auto decl = compiler::DeclarationFromIdentifier(touchingToken->AsIdentifier()); + if (decl == nullptr || decl->Range().start.Program() == nullptr) { + return false; + } + auto declFilePath = decl->Range().start.Program()->SourceFilePath(); + if (!declFilePath.Is(ctx->sourceFile->filePath)) { // the declaration is in a different file + auto parent = touchingToken->Parent(); + if (parent != nullptr && parent->IsMemberExpression()) { + auto property = parent->AsMemberExpression()->Property(); + if (property != nullptr && compiler::DeclarationFromIdentifier(property->AsIdentifier()) == decl) { + return true; } - prefix = std::string {beg, end}; } - // Suffix - std::string suffix; - { - auto beg = source.begin() + ref.end; - auto end = beg; - while (end < source.end() && *end != '\n') { - ++end; - } - suffix = std::string {beg, end}; + } else { // the declaration is in the same file + auto isExported = [](ir::AstNode *node) { + return node != nullptr && (node->IsExported() || node->IsDefaultExported() || node->IsExportedType()); + }; + auto exported = isExported(decl); + if (exported) { + return true; + } + if (decl->IsMethodDefinition() && decl->Parent() != nullptr && decl->Parent()->IsClassDefinition()) { + return decl->IsPublic() && isExported(decl->Parent()); + } + if (decl->IsClassProperty()) { + return decl->IsPublic() && isExported(decl->Parent()); } - res.insert(RenameLocation {ref.filePath, ref.start, ref.end, ref.line, prefix, suffix}); } + return false; +} + +std::set FindRenameLocations(CancellationToken *tkn, + const std::vector &fileContexts, + es2panda_Context *context, size_t position) +{ + auto references = FindReferences(tkn, fileContexts, context, position); + std::set res; + for (const auto &ref : references) { + res.emplace(ref.filePath, ref.start, ref.end, ref.line); + } + + return res; +} + +std::set FindRenameLocations(CancellationToken *tkn, es2panda_Context *context, size_t position) +{ + auto references = FindReferences(tkn, {context}, context, position); + std::set res; + if (references.empty()) { + return res; + } + auto it = references.cbegin(); + if (auto touchingToken = GetTouchingToken(context, it->start, false); IsImported(touchingToken)) { + auto importSpecifier = touchingToken->Parent()->AsImportSpecifier(); + if (!(importSpecifier->Local()->Range() != importSpecifier->Imported()->Range())) { + // this case: `import { SourceFile } from 'module';` + // rename result: `import { SourceFile as sf } from 'module';` + // so we need to add the prefix text `SourceFile as` + res.emplace(it->filePath, it->start, it->end, it->line, + std::string(touchingToken->AsIdentifier()->Name()) + " as "); + ++it; + } + } + for (; it != references.end(); ++it) { + res.emplace(it->filePath, it->start, it->end, it->line); + } return res; } -std::set FindRenameLocations(const std::vector &files, - const ark::es2panda::SourceFile &file, size_t position) +std::set FindRenameLocations(const std::vector &fileContexts, + es2panda_Context *context, size_t position) +{ + time_t tmp = 0; + CancellationToken cancellationToken {tmp, nullptr}; + return FindRenameLocations(&cancellationToken, fileContexts, context, position); +} + +std::set FindRenameLocationsInCurrentFile(es2panda_Context *context, size_t position) { time_t tmp = 0; CancellationToken cancellationToken {tmp, nullptr}; - return FindRenameLocations(&cancellationToken, files, file, position); + return FindRenameLocations(&cancellationToken, context, position); } } // 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..70fd10a669c4074ff65dcafad17ae31089d6eaca --- /dev/null +++ b/ets2panda/lsp/src/formatting/formatting.cpp @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/formatting_context.h" +#include "formatting/rules_map.h" +#include "internal_api.h" +#include "public/public.h" +#include "lexer/lexer.h" +#include "lexer/token/token.h" + +namespace ark::es2panda::lsp { + +// NOLINTNEXTLINE +bool TokenMatch(TokenRange &tokenRange, lexer::TokenType tokenType) +{ + auto &tokens = tokenRange.GetTokens(); + return tokens.empty() || std::find(tokens.begin(), tokens.end(), tokenType) != tokens.end(); +} + +void ApplyInsertSpace(RuleAction action, const TextSpan &span, std::vector &changes) +{ + if ((static_cast(RuleAction::INSERT_SPACE) & static_cast(action)) != 0) { + changes.emplace_back(TextChange {span, " "}); + } +} + +void ApplyDeleteSpace(RuleAction action, const TextSpan &span, std::vector &changes) +{ + if ((static_cast(RuleAction::DELETE_SPACE) & static_cast(action)) != 0) { + if (span.length > 0) { + changes.emplace_back(TextChange {span, ""}); + } + } +} + +void ApplyInsertNewline(RuleAction action, const TextSpan &span, std::vector &changes) +{ + if ((static_cast(RuleAction::INSERT_NEWLINE) & static_cast(action)) != 0) { + changes.emplace_back(TextChange {span, "\n"}); + } +} + +void ApplyDeleteToken(RuleAction action, const lexer::SourceRange &tokenLoc, std::vector &changes) +{ + if ((static_cast(RuleAction::DELETE_TOKEN) & static_cast(action)) != 0) { + TextSpan span {tokenLoc.start.index, tokenLoc.end.index - tokenLoc.start.index}; + changes.emplace_back(TextChange {span, ""}); + } +} + +void ApplyInsertSemicolon(RuleAction action, const lexer::SourceRange &tokenLoc, std::vector &changes) +{ + if ((static_cast(RuleAction::INSERT_TRAILING_SEMICOLON) & static_cast(action)) != 0) { + TextSpan span {tokenLoc.end.index, 0}; + changes.emplace_back(TextChange {span, ";"}); + } +} + +void ExecuteRuleAction(FormattingContext &context, std::vector &changes, Rule &rule) +{ + const auto &prevToken = context.GetPreviousToken(); + const auto ¤tToken = context.GetCurrentToken(); + auto action = rule.GetRuleAction(); + + auto prevLoc = prevToken.Loc(); + auto currLoc = currentToken.Loc(); + + size_t start = prevLoc.end.index; + size_t end = currLoc.start.index; + + if (start <= end) { + TextSpan whitespaceSpan {start, end - start}; + ApplyInsertSpace(action, whitespaceSpan, changes); + ApplyDeleteSpace(action, whitespaceSpan, changes); + ApplyInsertNewline(action, whitespaceSpan, changes); + } + + ApplyDeleteToken(action, currLoc, changes); + ApplyInsertSemicolon(action, currLoc, changes); +} + +void ApplyRulesOnRange(FormattingContext &context, std::vector &changes, RulesMap &rulesMap) +{ + const auto ¤tToken = context.GetCurrentToken(); + const auto &nextToken = context.GetNextToken(); + + if (currentToken.Type() == lexer::TokenType::EOS || nextToken.Type() == lexer::TokenType::EOS) { + return; + } + + auto allRules = rulesMap(context); + + for (auto &ruleSpec : allRules) { + if (!TokenMatch(ruleSpec.GetLeftTokenRange(), currentToken.Type())) { + continue; + } + + if (!TokenMatch(ruleSpec.GetRightTokenRange(), nextToken.Type())) { + continue; + } + + bool predicatesMet = true; + for (const auto &predicate : ruleSpec.GetRule().GetContext()) { + if (!predicate(&context)) { + predicatesMet = false; + break; + } + } + if (predicatesMet) { + ExecuteRuleAction(context, changes, ruleSpec.GetRule()); + if ((static_cast(ruleSpec.GetRule().GetRuleAction()) & + (static_cast(static_cast(RuleAction::STOP_PROCESSING_SPACE_ACTIONS) | + static_cast(RuleAction::STOP_PROCESSING_TOKEN_ACTIONS)))) != 0) { + break; + } + } + } +} + +std::vector FormatDocument(es2panda_Context *context, FormatContext formatContext) +{ + if (context == nullptr) { + return {}; + } + + auto *publicContext = reinterpret_cast(context); + if (publicContext == nullptr || publicContext->parserProgram == nullptr) { + return {}; + } + + RulesMap &rulesMap = formatContext.GetRulesMap(); + [[maybe_unused]] const FormatCodeSettings &options = formatContext.GetFormatCodeSettings(); + + parser::ParserContext parserCtx(publicContext->parserProgram, parser::ParserStatus::NO_OPTS); + lexer::Lexer lexer(&parserCtx, *publicContext->diagnosticEngine); + + std::string sourceText(publicContext->parserProgram->SourceCode().Utf8()); + + FormattingContext formattingContext(sourceText); + std::vector changes; + + lexer::Token prevToken; + prevToken.SetTokenType(lexer::TokenType::EOS); + + lexer.NextToken(); + lexer::Token currentToken = lexer.GetToken(); + if (currentToken.Type() == lexer::TokenType::EOS) { + return {}; + } + lexer.NextToken(); + lexer::Token nextToken = lexer.GetToken(); + + while (currentToken.Type() != lexer::TokenType::EOS) { + formattingContext.SetPreviousToken(prevToken); + formattingContext.SetCurrentToken(currentToken); + formattingContext.SetNextToken(nextToken); + + auto *currentTokenParent = GetTouchingToken(context, currentToken.Loc().start.index, false); + formattingContext.SetCurrentTokenParent(currentTokenParent); + + ir::AstNode *nextTokenParent = nullptr; + if (nextToken.Type() != lexer::TokenType::EOS) { + nextTokenParent = GetTouchingToken(context, nextToken.Loc().start.index, false); + } + formattingContext.SetNextTokenParent(nextTokenParent); + + ApplyRulesOnRange(formattingContext, changes, rulesMap); + + prevToken = currentToken; + currentToken = nextToken; + + if (currentToken.Type() != lexer::TokenType::EOS) { + lexer.NextToken(); + nextToken = lexer.GetToken(); + } else { + nextToken.SetTokenType(lexer::TokenType::EOS); + } + } + return changes; +} + +FormatContext GetFormatContext(FormatCodeSettings &options) +{ + RulesMap &rulesMap = RulesMapCache::Instance().GetRulesMap(); + return FormatContext(options, rulesMap); +} + +} // 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..fa7697aef65ba7e0349f6e292a41877046506a31 --- /dev/null +++ b/ets2panda/lsp/src/formatting/formatting_context.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 "formatting/formatting_context.h" +#include "ir/astNode.h" +#include "ir/statements/blockStatement.h" + +namespace ark::es2panda::lsp { + +FormattingContext::FormattingContext(const std::string &sourceText) : sourceText_(sourceText) {} + +void FormattingContext::SetCurrentToken(const lexer::Token &token) +{ + currentToken_ = token; + currentTokenSpan_ = token.Loc(); +} + +void FormattingContext::SetPreviousToken(const lexer::Token &token) +{ + prevToken_ = token; +} + +void FormattingContext::SetNextToken(const lexer::Token &token) +{ + nextToken_ = token; +} + +void FormattingContext::SetCurrentTokenParent(ir::AstNode *node) +{ + currentTokenParent_ = node; +} + +void FormattingContext::SetNextTokenParent(ir::AstNode *node) +{ + nextTokenParent_ = node; +} + +void FormattingContext::SetOptions(const FormatCodeSettings &options) +{ + options_ = options; +} + +const lexer::Token &FormattingContext::GetCurrentToken() const +{ + return currentToken_; +} + +const lexer::Token &FormattingContext::GetPreviousToken() const +{ + return prevToken_; +} + +const lexer::Token &FormattingContext::GetNextToken() const +{ + return nextToken_; +} + +ir::AstNode *FormattingContext::GetCurrentTokenParent() const +{ + return currentTokenParent_; +} + +ir::AstNode *FormattingContext::GetNextTokenParent() const +{ + return nextTokenParent_; +} + +const std::string &FormattingContext::GetSourceText() const +{ + return sourceText_; +} + +const lexer::SourceRange &FormattingContext::GetCurrentTokenSpan() const +{ + return currentTokenSpan_; +} + +const FormatCodeSettings &FormattingContext::GetOptions() const +{ + return options_; +} + +bool FormattingContext::ContextNodeBlockIsOnOneLine() const +{ + if (currentTokenParent_ == nullptr) { + return true; + } + return BlockIsOnOneLine(currentTokenParent_); +} + +bool FormattingContext::TokensAreOnSameLine() const +{ + return prevToken_.Loc().end.line == currentToken_.Loc().start.line; +} + +bool FormattingContext::BlockIsOnOneLine(ir::AstNode *node) const +{ + if (node->IsBlockStatement()) { + auto block = node->AsBlockStatement(); + if (!block->Statements().empty()) { + return block->Start().line == block->Statements().back()->End().line; + } + } + return node->Start().line == node->End().line; +} + +} // 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..e69ebe7aa772032efc84bc7cdf8ccddf73d0a94f --- /dev/null +++ b/ets2panda/lsp/src/formatting/rules.cpp @@ -0,0 +1,1327 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include "formatting/formatting_context.h" +#include "generated/tokenType.h" +#include "ir/astNode.h" +#include "internal_api.h" + +namespace ark::es2panda::lsp { + +static bool IsOnSameLineContext(FormattingContext *ctx) +{ + return ctx->TokensAreOnSameLine(); +} + +static bool NodeIsTypeScriptDeclWithBlockContext(ir::AstNode *node) +{ + if (node == nullptr) { + return false; + } + switch (node->Type()) { + case ir::AstNodeType::CLASS_DECLARATION: + case ir::AstNodeType::CLASS_EXPRESSION: + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + case ir::AstNodeType::TS_ENUM_DECLARATION: + case ir::AstNodeType::TS_TYPE_LITERAL: + case ir::AstNodeType::TS_MODULE_DECLARATION: + case ir::AstNodeType::EXPORT_NAMED_DECLARATION: + case ir::AstNodeType::IMPORT_DECLARATION: + return true; + default: + return false; + } +} + +static bool NodeIsBlockContext(ir::AstNode *node) +{ + if (node == nullptr) { + return false; + } + if (NodeIsTypeScriptDeclWithBlockContext(node)) { + return true; + } + switch (node->Type()) { + case ir::AstNodeType::BLOCK_STATEMENT: + case ir::AstNodeType::OBJECT_EXPRESSION: + case ir::AstNodeType::TS_MODULE_BLOCK: + case ir::AstNodeType::SWITCH_STATEMENT: + return true; + default: + return false; + } +} + +static bool NodeIsInDecoratorContext(ir::AstNode *node) +{ + while (node != nullptr && node->IsExpression()) { + node = node->Parent(); + } + return node != nullptr && node->Type() == ir::AstNodeType::DECORATOR; +} + +static bool IsBinaryOpContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + const auto ¤tToken = ctx->GetCurrentToken(); + const auto &nextToken = ctx->GetNextToken(); + + switch (parent->Type()) { + case ir::AstNodeType::BINARY_EXPRESSION: + return parent->AsBinaryExpression()->OperatorType() != lexer::TokenType::PUNCTUATOR_COMMA; + case ir::AstNodeType::CONDITIONAL_EXPRESSION: + case ir::AstNodeType::TS_CONDITIONAL_TYPE: + case ir::AstNodeType::TS_AS_EXPRESSION: + case ir::AstNodeType::EXPORT_SPECIFIER: + case ir::AstNodeType::IMPORT_SPECIFIER: + case ir::AstNodeType::TS_TYPE_PREDICATE: + case ir::AstNodeType::TS_UNION_TYPE: + case ir::AstNodeType::ETS_UNION_TYPE: + case ir::AstNodeType::TS_INTERSECTION_TYPE: + return true; + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + case ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION: + case ir::AstNodeType::VARIABLE_DECLARATION: + case ir::AstNodeType::TS_PARAMETER_PROPERTY: + case ir::AstNodeType::TS_ENUM_MEMBER: + case ir::AstNodeType::CLASS_PROPERTY: + case ir::AstNodeType::TS_PROPERTY_SIGNATURE: + return currentToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION || + nextToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION; + case ir::AstNodeType::EXPORT_DEFAULT_DECLARATION: + if (parent->AsExportDefaultDeclaration()->IsExportEquals()) { + return currentToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION || + nextToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION; + } + return false; + case ir::AstNodeType::FOR_IN_STATEMENT: + case ir::AstNodeType::TS_TYPE_PARAMETER: + return currentToken.Type() == lexer::TokenType::KEYW_IN || nextToken.Type() == lexer::TokenType::KEYW_IN || + currentToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION || + nextToken.Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION; + case ir::AstNodeType::FOR_OF_STATEMENT: + return currentToken.Type() == lexer::TokenType::KEYW_OF || nextToken.Type() == lexer::TokenType::KEYW_OF; + default: + return false; + } +} + +static bool IsNotBinaryOpContext(FormattingContext *ctx) +{ + return !IsBinaryOpContext(ctx); +} + +static bool IsFunctionLikeDeclarationKind(ir::AstNodeType kind) +{ + switch (kind) { + case ark::es2panda::ir::AstNodeType::FUNCTION_DECLARATION: + case ark::es2panda::ir::AstNodeType::METHOD_DEFINITION: + case ark::es2panda::ir::AstNodeType::TS_CONSTRUCTOR_TYPE: + case ark::es2panda::ir::AstNodeType::FUNCTION_EXPRESSION: + case ark::es2panda::ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + return true; + default: + return false; + } +} + +static bool IsFunctionLikeKind(ir::AstNodeType kind) +{ + switch (kind) { + case ark::es2panda::ir::AstNodeType::METHOD_DEFINITION: + case ark::es2panda::ir::AstNodeType::CALL_EXPRESSION: + case ark::es2panda::ir::AstNodeType::TS_CONSTRUCTOR_TYPE: + case ark::es2panda::ir::AstNodeType::TS_INDEX_SIGNATURE: + case ark::es2panda::ir::AstNodeType::FUNCTION_DECLARATION: + return true; + default: + return IsFunctionLikeDeclarationKind(kind); + } +} + +static bool IsTypeAnnotationContext(FormattingContext *context) +{ + const auto contextKind = context->GetCurrentTokenParent()->Type(); + return contextKind == ir::AstNodeType::PROPERTY || contextKind == ir::AstNodeType::TS_PROPERTY_SIGNATURE || + contextKind == ir::AstNodeType::TS_TYPE_PARAMETER_DECLARATION || + contextKind == ir::AstNodeType::VARIABLE_DECLARATION || IsFunctionLikeKind(contextKind); +} + +static bool IsNotTypeAnnotationContext(FormattingContext *ctx) +{ + return !IsTypeAnnotationContext(ctx); +} + +static bool IsOptionalPropertyContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::CLASS_PROPERTY: + case ir::AstNodeType::TS_PROPERTY_SIGNATURE: + case ir::AstNodeType::TS_PARAMETER_PROPERTY: + return (parent->Modifiers() & ir::ModifierFlags::OPTIONAL) != 0; + default: + return false; + } +} + +static bool IsNonOptionalPropertyContext(FormattingContext *ctx) +{ + return !IsOptionalPropertyContext(ctx); +} + +static bool IsConditionalOperatorContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && (parent->Type() == ir::AstNodeType::CONDITIONAL_EXPRESSION || + parent->Type() == ir::AstNodeType::TS_CONDITIONAL_TYPE); +} + +static bool IsImportTypeContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && parent->Type() == ir::AstNodeType::TS_IMPORT_TYPE; +} + +static bool IsNotPropertyAccessOnIntegerLiteral(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr || parent->Type() != ir::AstNodeType::MEMBER_EXPRESSION) { + return true; + } + auto *memberExpr = parent->AsMemberExpression(); + if (memberExpr == nullptr || memberExpr->Object() == nullptr || !memberExpr->Object()->IsNumberLiteral()) { + return true; + } + auto *numLiteral = memberExpr->Object()->AsNumberLiteral(); + if (numLiteral == nullptr) { + return true; + } + + auto &numStr = numLiteral->Str(); + std::string str(numStr); + return str.find('.') != std::string::npos; +} + +static bool IsBlockContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return NodeIsBlockContext(parent); +} + +static bool IsMultilineBlockContext(FormattingContext *ctx) +{ + return IsBlockContext(ctx) && !ctx->ContextNodeBlockIsOnOneLine(); +} + +static bool IsAfterCodeBlockContext(FormattingContext *ctx) +{ + auto *currentParent = ctx->GetCurrentTokenParent(); + if (currentParent == nullptr) { + return false; + } + switch (currentParent->Type()) { + case ir::AstNodeType::CLASS_DECLARATION: + case ir::AstNodeType::TS_MODULE_DECLARATION: + case ir::AstNodeType::TS_ENUM_DECLARATION: + case ir::AstNodeType::CATCH_CLAUSE: + case ir::AstNodeType::TS_MODULE_BLOCK: + case ir::AstNodeType::SWITCH_STATEMENT: + return true; + case ir::AstNodeType::BLOCK_STATEMENT: { + auto *blockParent = currentParent->Parent(); + if (blockParent == nullptr || (blockParent->Type() != ir::AstNodeType::ARROW_FUNCTION_EXPRESSION && + blockParent->Type() != ir::AstNodeType::FUNCTION_EXPRESSION)) { + return true; // NOLINT(readability-simplify-boolean-expr) + } + return false; + } + default: + return false; + } +} + +static bool IsControlDeclContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::IF_STATEMENT: + case ir::AstNodeType::SWITCH_STATEMENT: + case ir::AstNodeType::FOR_UPDATE_STATEMENT: + case ir::AstNodeType::FOR_IN_STATEMENT: + case ir::AstNodeType::FOR_OF_STATEMENT: + case ir::AstNodeType::WHILE_STATEMENT: + case ir::AstNodeType::TRY_STATEMENT: + case ir::AstNodeType::DO_WHILE_STATEMENT: + case ir::AstNodeType::CATCH_CLAUSE: + return true; + default: + return false; + } +} + +static bool IsObjectContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && parent->Type() == ir::AstNodeType::OBJECT_EXPRESSION; +} + +static bool IsFunctionDeclContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::FUNCTION_DECLARATION: + case ir::AstNodeType::FUNCTION_EXPRESSION: + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + case ir::AstNodeType::TS_METHOD_SIGNATURE: + case ir::AstNodeType::TS_SIGNATURE_DECLARATION: + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: + case ir::AstNodeType::METHOD_DEFINITION: + case ir::AstNodeType::CLASS_PROPERTY: + return true; + default: + return false; + } +} + +static bool IsNotFunctionDeclContext(FormattingContext *ctx) +{ + return !IsFunctionDeclContext(ctx); +} + +static bool IsFunctionDeclarationOrFunctionExpressionContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && (parent->Type() == ir::AstNodeType::FUNCTION_DECLARATION || + parent->Type() == ir::AstNodeType::FUNCTION_EXPRESSION); +} + +static bool IsFunctionCallOrNewContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::CALL_EXPRESSION: + case ir::AstNodeType::NEW_EXPRESSION: + case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION: + case ir::AstNodeType::ETS_NEW_ARRAY_INSTANCE_EXPRESSION: + case ir::AstNodeType::ETS_NEW_MULTI_DIM_ARRAY_INSTANCE_EXPRESSION: + return true; + default: + return false; + } +} + +static bool IsPreviousTokenNotComma(FormattingContext *ctx) +{ + return ctx->GetCurrentToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA; +} + +static bool IsArrowFunctionContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && parent->Type() == ir::AstNodeType::ARROW_FUNCTION_EXPRESSION; +} + +static bool IsStartOfVariableDeclarationList(FormattingContext *ctx) +{ + auto *currentParent = ctx->GetCurrentTokenParent(); + const auto ¤tSpan = ctx->GetCurrentTokenSpan(); + if (currentParent == nullptr) { + return false; + } + return currentParent->Type() == ir::AstNodeType::VARIABLE_DECLARATION && + currentParent->Start().index == currentSpan.start.index; +} + +static bool IsModuleDeclContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && + (parent->Type() == ir::AstNodeType::TS_MODULE_DECLARATION || parent->Type() == ir::AstNodeType::ETS_MODULE); +} + +static bool IsObjectTypeContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && + (parent->Type() == ir::AstNodeType::TS_TYPE_LITERAL || parent->Type() == ir::AstNodeType::TS_INTERFACE_BODY); +} + +static bool IsConstructorSignatureContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + if (parent->Type() == ir::AstNodeType::TS_SIGNATURE_DECLARATION) { + auto *sigDecl = parent->AsTSSignatureDeclaration(); + return sigDecl != nullptr; + } + if (parent->Type() == ir::AstNodeType::METHOD_DEFINITION) { + auto *methodDef = parent->AsMethodDefinition(); + return methodDef->IsConstructor(); + } + return false; +} + +static bool IsTypeArgumentOrParameterOrAssertion(const lexer::Token &token, ir::AstNode *parent) +{ + if (token.Type() != lexer::TokenType::PUNCTUATOR_LESS_THAN && + token.Type() != lexer::TokenType::PUNCTUATOR_GREATER_THAN) { + return false; + } + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::TS_TYPE_REFERENCE: + case ir::AstNodeType::ETS_TYPE_REFERENCE: + case ir::AstNodeType::TS_TYPE_ASSERTION: + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + case ir::AstNodeType::CLASS_DECLARATION: + case ir::AstNodeType::CLASS_EXPRESSION: + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + case ir::AstNodeType::FUNCTION_DECLARATION: + case ir::AstNodeType::FUNCTION_EXPRESSION: + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + case ir::AstNodeType::METHOD_DEFINITION: + case ir::AstNodeType::TS_METHOD_SIGNATURE: + case ir::AstNodeType::TS_SIGNATURE_DECLARATION: + case ir::AstNodeType::CALL_EXPRESSION: + case ir::AstNodeType::NEW_EXPRESSION: + case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION: + return true; + default: + return false; + } +} + +static bool IsTypeArgumentOrParameterOrAssertionContext(FormattingContext *ctx) +{ + const auto ¤tToken = ctx->GetCurrentToken(); + const auto &nextToken = ctx->GetNextToken(); + auto *currentParent = ctx->GetCurrentTokenParent(); + auto *nextParent = ctx->GetNextTokenParent(); + return IsTypeArgumentOrParameterOrAssertion(currentToken, currentParent) || + IsTypeArgumentOrParameterOrAssertion(nextToken, nextParent); +} + +static bool IsTypeAssertionContext(FormattingContext *context) +{ + return context->GetCurrentTokenParent()->Type() == ir::AstNodeType::TS_TYPE_ASSERTION; +} +static bool IsNonTypeAssertionContext(FormattingContext *ctx) +{ + return !IsTypeAssertionContext(ctx); +} + +static bool IsVoidOpContext(FormattingContext *ctx) +{ + const auto ¤tToken = ctx->GetCurrentToken(); + auto *parent = ctx->GetCurrentTokenParent(); + return currentToken.Type() == lexer::TokenType::KEYW_VOID && parent != nullptr && + parent->Type() == ir::AstNodeType::UNARY_EXPRESSION; +} + +static bool IsYieldOrYieldStarWithOperand(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr || parent->Type() != ir::AstNodeType::YIELD_EXPRESSION) { + return false; + } + auto *yieldExpr = parent->AsYieldExpression(); + return yieldExpr != nullptr && yieldExpr->Argument() != nullptr; +} + +static bool IsEndOfDecoratorContextOnSameLine(FormattingContext *ctx) +{ + if (!ctx->TokensAreOnSameLine()) { + return false; + } + auto *currentParent = ctx->GetCurrentTokenParent(); + auto *nextParent = ctx->GetNextTokenParent(); + return currentParent != nullptr && NodeIsInDecoratorContext(currentParent) && + (nextParent == nullptr || !NodeIsInDecoratorContext(nextParent)); +} + +static bool IsNonNullAssertionContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + return parent != nullptr && parent->Type() == ir::AstNodeType::TS_NON_NULL_EXPRESSION; +} + +static bool IsStatementConditionContext(FormattingContext *ctx) +{ + auto *parent = ctx->GetCurrentTokenParent(); + if (parent == nullptr) { + return false; + } + switch (parent->Type()) { + case ir::AstNodeType::IF_STATEMENT: + case ir::AstNodeType::FOR_UPDATE_STATEMENT: + case ir::AstNodeType::FOR_IN_STATEMENT: + case ir::AstNodeType::FOR_OF_STATEMENT: + case ir::AstNodeType::DO_WHILE_STATEMENT: + case ir::AstNodeType::WHILE_STATEMENT: + return true; + default: + return false; + } +} + +static bool IsNotStatementConditionContext(FormattingContext *ctx) +{ + return !IsStatementConditionContext(ctx); +} + +static TokenRange CreateTokenRange(const std::vector &tokens) +{ + return TokenRange {TokenRange(const_cast &>(tokens), true)}; +} + +static TokenRange CreateAnyTokenExcept(const std::vector &excludeTokens) +{ + std::vector allTokens; + for (int token = static_cast(lexer::TokenType::EOS); token <= static_cast(lexer::TokenType::FIRST_KEYW); + token++) { + auto tokenType = static_cast(token); + bool exclude = false; + for (auto excludeToken : excludeTokens) { + if (tokenType == excludeToken) { + exclude = true; + break; + } + } + if (!exclude) { + allTokens.push_back(tokenType); + } + } + return CreateTokenRange(allTokens); +} + +static void AddPunctuationRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto colon = CreateTokenRange({lexer::TokenType::PUNCTUATOR_COLON}); + auto question = CreateTokenRange({lexer::TokenType::PUNCTUATOR_QUESTION_MARK}); + auto dots = CreateTokenRange({lexer::TokenType::PUNCTUATOR_PERIOD, lexer::TokenType::PUNCTUATOR_QUESTION_DOT}); + auto ellipsis = CreateTokenRange({lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD}); + auto ident = CreateTokenRange({lexer::TokenType::LITERAL_IDENT}); + + Rule rule1({IsOnSameLineContext, IsNotBinaryOpContext, IsNotTypeAnnotationContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule1, anyTokenRange, colon); + + Rule rule2({IsOnSameLineContext, IsNotBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, colon, anyTokenRange); + + Rule rule3({IsOnSameLineContext, IsNotBinaryOpContext, IsNotTypeAnnotationContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule3, anyTokenRange, question); + + Rule rule4({IsOnSameLineContext, IsConditionalOperatorContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, question, anyTokenRange); + + Rule rule5({IsOnSameLineContext, IsNonOptionalPropertyContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, question, anyTokenRange); + + Rule rule6({IsOnSameLineContext, IsNotPropertyAccessOnIntegerLiteral}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule6, anyTokenRange, dots); + + Rule rule7({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule7, dots, anyTokenRange); + + Rule rule8({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule8, ellipsis, ident); +} + +static void AddUnaryOperatorRules(std::vector &rules) +{ + auto unaryPrefixOperators = + CreateTokenRange({lexer::TokenType::PUNCTUATOR_PLUS_PLUS, lexer::TokenType::PUNCTUATOR_MINUS_MINUS, + lexer::TokenType::PUNCTUATOR_TILDE, lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK}); + auto unaryPrefixExpressions = CreateTokenRange( + {lexer::TokenType::LITERAL_NUMBER, lexer::TokenType::LITERAL_IDENT, + lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET, + lexer::TokenType::PUNCTUATOR_LEFT_BRACE, lexer::TokenType::KEYW_THIS, lexer::TokenType::KEYW_NEW}); + auto unaryPreincrementExpressions = + CreateTokenRange({lexer::TokenType::LITERAL_IDENT, lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, + lexer::TokenType::KEYW_THIS, lexer::TokenType::KEYW_NEW}); + auto unaryPostincrementExpressions = + CreateTokenRange({lexer::TokenType::LITERAL_IDENT, lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, + lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::TokenType::KEYW_NEW}); + auto plusPlus = CreateTokenRange({lexer::TokenType::PUNCTUATOR_PLUS_PLUS}); + auto minusMinus = CreateTokenRange({lexer::TokenType::PUNCTUATOR_MINUS_MINUS}); + auto plus = CreateTokenRange({lexer::TokenType::PUNCTUATOR_PLUS}); + auto minus = CreateTokenRange({lexer::TokenType::PUNCTUATOR_MINUS}); + + Rule rule1({IsOnSameLineContext, IsNotBinaryOpContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, unaryPrefixOperators, unaryPrefixExpressions); + + Rule rule2({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, plusPlus, unaryPreincrementExpressions); + + Rule rule3({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule3, minusMinus, unaryPreincrementExpressions); + + Rule rule4({IsOnSameLineContext, IsNotStatementConditionContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, unaryPostincrementExpressions, plusPlus); + + Rule rule5({IsOnSameLineContext, IsNotStatementConditionContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, unaryPostincrementExpressions, minusMinus); + + Rule rule6({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule6, plusPlus, plus); + + Rule rule7({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule7, plus, plus); + + Rule rule8({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule8, plus, plusPlus); + + Rule rule9({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule9, minusMinus, minus); + + Rule rule10({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule10, minus, minus); + + Rule rule11({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule11, minus, minusMinus); +} + +static void AddBraceRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto rightBrace = CreateTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_BRACE}); + auto leftBrace = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_BRACE}); + auto commaColon = CreateTokenRange({lexer::TokenType::PUNCTUATOR_COMMA, lexer::TokenType::PUNCTUATOR_SEMI_COLON}); + auto elseKeyword = CreateTokenRange({lexer::TokenType::KEYW_ELSE}); + auto whileKeyword = CreateTokenRange({lexer::TokenType::KEYW_WHILE}); + + Rule rule1({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, rightBrace, commaColon); + + Rule rule2({IsMultilineBlockContext}, RuleAction::INSERT_NEWLINE, RuleFlags::NONE); + rules.emplace_back(rule2, anyTokenRange, rightBrace); + + Rule rule3({IsOnSameLineContext, IsAfterCodeBlockContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + auto tokenExcept = CreateAnyTokenExcept({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS}); + rules.emplace_back(rule3, rightBrace, tokenExcept); + + Rule rule4({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, rightBrace, elseKeyword); + + Rule rule5({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, rightBrace, whileKeyword); + + Rule rule6({IsOnSameLineContext, IsObjectContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule6, leftBrace, rightBrace); + + Rule rule7({IsMultilineBlockContext}, RuleAction::INSERT_NEWLINE, RuleFlags::NONE); + rules.emplace_back(rule7, leftBrace, anyTokenRange); + + Rule rule8({IsOnSameLineContext, IsObjectTypeContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule8, leftBrace, rightBrace); +} + +static void AddFunctionRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto functionKeyword = CreateTokenRange({lexer::TokenType::KEYW_FUNCTION}); + auto multiply = CreateTokenRange({lexer::TokenType::PUNCTUATOR_MULTIPLY}); + auto ident = CreateTokenRange({lexer::TokenType::LITERAL_IDENT}); + auto getSet = CreateTokenRange({lexer::TokenType::KEYW_GET, lexer::TokenType::KEYW_SET}); + auto rightParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS}); + auto leftBracket = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET}); + auto leftParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + + Rule rule1({IsFunctionDeclarationOrFunctionExpressionContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, functionKeyword, multiply); + + Rule rule2({IsFunctionDeclarationOrFunctionExpressionContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, multiply, ident); + + Rule rule3({IsFunctionDeclContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule3, functionKeyword, anyTokenRange); + + Rule rule4({IsFunctionDeclContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, getSet, ident); + + Rule rule5({IsControlDeclContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, rightParen, leftBracket); + + Rule rule6({IsOnSameLineContext, IsFunctionCallOrNewContext, IsPreviousTokenNotComma}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule6, anyTokenRange, leftParen); +} + +static void AddKeywordRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto binaryKeywordOperators = + CreateTokenRange({lexer::TokenType::KEYW_IN, lexer::TokenType::KEYW_INSTANCEOF, lexer::TokenType::KEYW_OF, + lexer::TokenType::KEYW_AS, lexer::TokenType::KEYW_IS}); + auto spaceAfterKeywords = + CreateTokenRange({lexer::TokenType::KEYW_VAR, lexer::TokenType::KEYW_THROW, lexer::TokenType::KEYW_NEW, + lexer::TokenType::KEYW_DELETE, lexer::TokenType::KEYW_RETURN, lexer::TokenType::KEYW_TYPEOF, + lexer::TokenType::KEYW_AWAIT}); + auto letConst = CreateTokenRange({lexer::TokenType::KEYW_LET, lexer::TokenType::KEYW_CONST}); + auto yield = CreateTokenRange({lexer::TokenType::KEYW_YIELD}); + auto multiply = CreateTokenRange({lexer::TokenType::PUNCTUATOR_MULTIPLY}); + auto yieldMultiply = CreateTokenRange({lexer::TokenType::KEYW_YIELD, lexer::TokenType::PUNCTUATOR_MULTIPLY}); + auto returnKeyword = CreateTokenRange({lexer::TokenType::KEYW_RETURN}); + auto semicolon = CreateTokenRange({lexer::TokenType::PUNCTUATOR_SEMI_COLON}); + auto voidKeyword = CreateTokenRange({lexer::TokenType::KEYW_VOID}); + auto import = CreateTokenRange({lexer::TokenType::KEYW_IMPORT}); + auto leftParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + + Rule rule1({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, anyTokenRange, binaryKeywordOperators); + + Rule rule2({IsOnSameLineContext, IsBinaryOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, binaryKeywordOperators, anyTokenRange); + + Rule rule3({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule3, spaceAfterKeywords, anyTokenRange); + + Rule rule4({IsOnSameLineContext, IsStartOfVariableDeclarationList}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, letConst, anyTokenRange); + + Rule rule5({IsOnSameLineContext, IsYieldOrYieldStarWithOperand}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, yield, multiply); + + Rule rule6({IsOnSameLineContext, IsYieldOrYieldStarWithOperand}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule6, yieldMultiply, anyTokenRange); + + Rule rule7({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule7, returnKeyword, semicolon); + + Rule rule8({IsOnSameLineContext, IsVoidOpContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule8, voidKeyword, anyTokenRange); + + Rule rule9({IsOnSameLineContext, IsImportTypeContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule9, import, leftParen); +} + +static void AddTypeScriptRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto typeScriptKeywords = CreateTokenRange( + {lexer::TokenType::KEYW_ABSTRACT, lexer::TokenType::KEYW_CLASS, lexer::TokenType::KEYW_DECLARE, + lexer::TokenType::KEYW_DEFAULT, lexer::TokenType::KEYW_ENUM, lexer::TokenType::KEYW_EXPORT, + lexer::TokenType::KEYW_EXTENDS, lexer::TokenType::KEYW_GET, lexer::TokenType::KEYW_IMPLEMENTS, + lexer::TokenType::KEYW_IMPORT, lexer::TokenType::KEYW_INTERFACE, lexer::TokenType::KEYW_MODULE, + lexer::TokenType::KEYW_NAMESPACE, lexer::TokenType::KEYW_PRIVATE, lexer::TokenType::KEYW_PUBLIC, + lexer::TokenType::KEYW_PROTECTED, lexer::TokenType::KEYW_READONLY, lexer::TokenType::KEYW_SET, + lexer::TokenType::KEYW_STATIC, lexer::TokenType::KEYW_TYPE, lexer::TokenType::KEYW_FROM, + lexer::TokenType::KEYW_KEYOF, lexer::TokenType::KEYW_INFER}); + auto extendsImplementsFromKeywords = CreateTokenRange( + {lexer::TokenType::KEYW_EXTENDS, lexer::TokenType::KEYW_IMPLEMENTS, lexer::TokenType::KEYW_FROM}); + auto moduleRequire = CreateTokenRange({lexer::TokenType::KEYW_MODULE, lexer::TokenType::KEYW_REQUIRE}); + auto stringLiteral = CreateTokenRange({lexer::TokenType::LITERAL_STRING}); + auto leftBrace = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_BRACE}); + auto leftParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + auto async = CreateTokenRange({lexer::TokenType::KEYW_ASYNC}); + auto functionIdent = CreateTokenRange({lexer::TokenType::KEYW_FUNCTION, lexer::TokenType::LITERAL_IDENT}); + + Rule rule1({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, typeScriptKeywords, anyTokenRange); + + Rule rule2({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, anyTokenRange, extendsImplementsFromKeywords); + + Rule rule3({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule3, moduleRequire, leftParen); + + Rule rule4({IsModuleDeclContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, stringLiteral, leftBrace); + + Rule rule5({IsArrowFunctionContext, IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, async, leftParen); + + Rule rule6({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule6, async, functionIdent); +} + +static void AddArrowAndGenericRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto arrow = CreateTokenRange({lexer::TokenType::PUNCTUATOR_ARROW}); + auto typeNames = + CreateTokenRange({lexer::TokenType::LITERAL_IDENT, lexer::TokenType::KEYW_STRING, lexer::TokenType::KEYW_NUMBER, + lexer::TokenType::KEYW_BOOLEAN, lexer::TokenType::KEYW_OBJECT, lexer::TokenType::KEYW_ANY}); + auto lessThan = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LESS_THAN}); + auto greaterThan = CreateTokenRange({lexer::TokenType::PUNCTUATOR_GREATER_THAN}); + auto rightParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS}); + auto parenBracketComma = CreateTokenRange( + {lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET, + lexer::TokenType::PUNCTUATOR_GREATER_THAN, lexer::TokenType::PUNCTUATOR_COMMA}); + auto question = CreateTokenRange({lexer::TokenType::PUNCTUATOR_QUESTION_MARK}); + auto rightParenComma = + CreateTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::TokenType::PUNCTUATOR_COMMA}); + + Rule rule1({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, anyTokenRange, arrow); + + Rule rule2({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, arrow, anyTokenRange); + + Rule rule3({IsOnSameLineContext, IsTypeArgumentOrParameterOrAssertionContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule3, typeNames, lessThan); + + Rule rule4({IsOnSameLineContext, IsTypeArgumentOrParameterOrAssertionContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule4, rightParen, lessThan); + + Rule rule5({IsOnSameLineContext, IsTypeArgumentOrParameterOrAssertionContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule5, lessThan, anyTokenRange); + + Rule rule6({IsOnSameLineContext, IsTypeArgumentOrParameterOrAssertionContext}, RuleAction::DELETE_SPACE, + RuleFlags::NONE); + rules.emplace_back(rule6, anyTokenRange, greaterThan); + + Rule rule7({IsOnSameLineContext, IsTypeArgumentOrParameterOrAssertionContext, IsNotFunctionDeclContext, + IsNonTypeAssertionContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule7, greaterThan, parenBracketComma); + + Rule rule8({IsOnSameLineContext, IsNotBinaryOpContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule8, question, rightParenComma); + + Rule rule9({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule9, lessThan, lessThan); +} + +static void AddDecoratorRules(std::vector &rules) +{ + auto anyTokenRange = CreateTokenRange({}); + auto rightParenIdent = + CreateTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::TokenType::LITERAL_IDENT}); + auto at = CreateTokenRange({lexer::TokenType::PUNCTUATOR_AT}); + auto afterDecoratorTokens = + CreateTokenRange({lexer::TokenType::KEYW_ABSTRACT, lexer::TokenType::LITERAL_IDENT, + lexer::TokenType::KEYW_EXPORT, lexer::TokenType::KEYW_DEFAULT, lexer::TokenType::KEYW_CLASS, + lexer::TokenType::KEYW_STATIC, lexer::TokenType::KEYW_PUBLIC, lexer::TokenType::KEYW_PRIVATE, + lexer::TokenType::KEYW_PROTECTED, lexer::TokenType::KEYW_GET, lexer::TokenType::KEYW_SET, + lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET, lexer::TokenType::PUNCTUATOR_MULTIPLY}); + auto exclamation = CreateTokenRange({lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK}); + auto newKeyword = CreateTokenRange({lexer::TokenType::KEYW_NEW}); + auto leftParen = CreateTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + + Rule rule1({IsOnSameLineContext}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule1, rightParenIdent, at); + + Rule rule2({IsOnSameLineContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule2, at, anyTokenRange); + + Rule rule3({IsEndOfDecoratorContextOnSameLine}, RuleAction::INSERT_SPACE, RuleFlags::NONE); + rules.emplace_back(rule3, anyTokenRange, afterDecoratorTokens); + + Rule rule4({IsOnSameLineContext, IsNonNullAssertionContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule4, anyTokenRange, exclamation); + + Rule rule5({IsOnSameLineContext, IsConstructorSignatureContext}, RuleAction::DELETE_SPACE, RuleFlags::NONE); + rules.emplace_back(rule5, newKeyword, leftParen); +} + +static bool IsTypeScriptDeclWithBlockContext(FormattingContext *context) +{ + return NodeIsTypeScriptDeclWithBlockContext(context->GetCurrentTokenParent()); +} + +static bool IsBeforeBlockContext(FormattingContext *context) +{ + return NodeIsBlockContext(context->GetCurrentTokenParent()); +} + +static bool IsSameLineTokenOrBeforeBlockContext(FormattingContext *context) +{ + return context->TokensAreOnSameLine() || IsBeforeBlockContext(context); +} + +static bool IsForContext(FormattingContext *context) +{ + return context->GetNextTokenParent()->Type() == ir::AstNodeType::FOR_IN_STATEMENT; +} + +// This check is done before an open brace in a control construct, a function, or a typescript block declaration +static bool IsBeforeMultilineBlockContext(FormattingContext *context) +{ + return IsBeforeBlockContext(context) && !(context->TokensAreOnSameLine() || context->ContextNodeBlockIsOnOneLine()); +} + +std::function IsOptionDisabledOrUndefinedOrTokensOnSameLine( + bool (FormatCodeSettings::*getter)() const) +{ + return [getter](const FormattingContext &context) { + if (!(context.GetOptions().*getter)()) { + return true; + } + + // token'lar aynı satırda ise + return context.TokensAreOnSameLine(); + }; +} + +std::vector GetAllTokenTypes() +{ + std::vector result; + for (int i = static_cast(lexer::TokenType::EOS); i < static_cast(lexer::TokenType::FIRST_KEYW); ++i) { + result.push_back(static_cast(i)); + } + return result; +} + +static bool IsNextTokenNotCloseBracket(FormattingContext *context) +{ + return context->GetCurrentToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE; +} + +static bool IsNextTokenNotCloseParen(FormattingContext *context) +{ + return context->GetCurrentToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS; +} + +const TokenRange &GetBinaryOperators() +{ + static const TokenRange BINARY_OPERATORS = [] { + static const std::vector COMPARISON_OPERATORS = { + lexer::TokenType::PUNCTUATOR_LESS_THAN, lexer::TokenType::PUNCTUATOR_GREATER_THAN, + lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL, lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL, + lexer::TokenType::PUNCTUATOR_EQUAL, lexer::TokenType::PUNCTUATOR_NOT_EQUAL}; + + return TokenRange {COMPARISON_OPERATORS, true}; + }(); + return BINARY_OPERATORS; +} + +// Place a space before open brace in a control flow construct +const TokenRange &GetControlOpenBraceLeftTokenRange() +{ + static const TokenRange CONTROL_OPEN_BRACE_LEFT_TOKEN_RANGE { + std::vector {lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS, lexer::TokenType::KEYW_DO, + lexer::TokenType::KEYW_TRY, lexer::TokenType::KEYW_FINALLY, + lexer::TokenType::KEYW_ELSE}, + true}; + return CONTROL_OPEN_BRACE_LEFT_TOKEN_RANGE; +} + +const TokenRange &GetAnyTokenIncludingMultilineComments() +{ + static const TokenRange RANGE {GetAllTokenTypes(), // vector + true}; + return RANGE; +} + +const TokenRange &GetKeywordsTokenRange() +{ + static const TokenRange RANGE {{lexer::TokenType::FIRST_KEYW, lexer::TokenType::KEYW_OF}, true}; + return RANGE; +} + +const TokenRange &GetTypeScriptOpenBraceLeftTokenRange() +{ + static const TokenRange RANGE {{lexer::TokenType::LITERAL_IDENT, lexer::TokenType::PUNCTUATOR_LEFT_BRACE, + lexer::TokenType::KEYW_CLASS, lexer::TokenType::KEYW_STRUCT, + lexer::TokenType::KEYW_EXPORT, lexer::TokenType::KEYW_IMPORT}, + true}; + return RANGE; +} + +const TokenRange &GetFunctionOpenBraceLeftTokenRange() +{ + return GetAnyTokenIncludingMultilineComments(); +} + +const TokenRange &GetAnyTokenRange() +{ + static const TokenRange RANGE {{}, // empty token list + true}; + return RANGE; +} + +struct UserConfigRule { + TokenRange left; + TokenRange right; + Rule rule; +}; + +static void AddUserConfigRules(std::vector &rules, const std::vector &configRules) +{ + for (auto &cfg : configRules) { + rules.emplace_back(cfg.rule, cfg.left, cfg.right); + } +} +// === Part 1: Constructor & Comma rules === +void AddConstructorAndCommaRules(std::vector &configRules, const TokenRange &leftConstructor, + const TokenRange &rightParen, const TokenRange &leftComma, const TokenRange &any) +{ + configRules.insert( + configRules.end(), + {{leftConstructor, rightParen, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterConstructor(); }}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftConstructor, rightParen, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterConstructor(); }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftComma, any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterConstructor(); }}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftComma, any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterCommaDelimiter(); }, + IsNextTokenNotCloseBracket, IsNextTokenNotCloseParen}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftComma, any, + Rule({[](FormattingContext *c) { return !c->GetOptions().GetInsertSpaceAfterCommaDelimiter(); }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} + +// === Part 2: Parentheses rules === +void AddParenthesesRules(std::vector &configRules, const TokenRange &leftParen, + const TokenRange &rightParenTok, const TokenRange &any) +{ + configRules.insert( + configRules.end(), + {{any, rightParenTok, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis(); + }, + IsControlDeclContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftParen, any, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis(); + }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {any, rightParenTok, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis(); + }, + IsControlDeclContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} + +// === Part 3: Brackets rules === +void AddBracketRules(std::vector &configRules, const TokenRange &leftBracket, + const TokenRange &rightBracket, const TokenRange &any) +{ + configRules.insert(configRules.end(), + {{leftBracket, any, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets(); + }}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + + {any, rightBracket, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets(); + }, + IsControlDeclContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + + {leftBracket, any, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets(); + }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + + {any, rightBracket, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets(); + }, + IsControlDeclContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} + +void AddFunctionAndControlFlowRules(std::vector &configRules, const TokenRange &any, + const TokenRange &leftParen, const TokenRange &rightParenTok, + const TokenRange &functionTokenRange) +{ + configRules.insert( + configRules.end(), + {{functionTokenRange, rightParenTok, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterFunctionKeywordForAnonymousFunctions(); + }, + IsFunctionDeclContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetKeywordsTokenRange(), rightParenTok, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetInsertSpaceAfterKeywordsInControlFlowStatements(); + }, + IsControlDeclContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetKeywordsTokenRange(), rightParenTok, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterKeywordsInControlFlowStatements(); + }, + IsControlDeclContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftParen, any, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis(); + }}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}}); +} + +void AddBraceRules(std::vector &configRules, const TokenRange &leftBrace, const TokenRange &rightBrace, + const TokenRange &any) +{ + configRules.insert(configRules.end(), + {{leftBrace, rightBrace, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces(); + }, + IsObjectContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + + {leftBrace, any, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces(); + }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + + {any, rightBrace, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces(); + }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + + {leftBrace, rightBrace, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingEmptyBraces(); + }}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}}); +} + +void AddSemicolonAndBinaryOpRules(std::vector &configRules, const TokenRange &any) +{ + configRules.insert( + configRules.end(), + {{CreateTokenRange({lexer::TokenType::PUNCTUATOR_SEMI_COLON}), any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterSemicolonInForStatements(); }, + IsForContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {CreateTokenRange({lexer::TokenType::PUNCTUATOR_SEMI_COLON}), any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterSemicolonInForStatements(); }, + IsForContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetBinaryOperators(), any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeAndAfterBinaryOperators(); }, + IsBinaryOpContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {any, GetBinaryOperators(), + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeAndAfterBinaryOperators(); }, + IsBinaryOpContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} +void AddFunctionParensAndControlBlocksRules(std::vector &configRules, const TokenRange &any, + const TokenRange &rightParenTok, const TokenRange &leftBrace) +{ + configRules.insert( + configRules.end(), + {{any, rightParenTok, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeFunctionParenthesis(); }, + IsFunctionDeclContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {any, rightParenTok, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeFunctionParenthesis(); }, + IsFunctionDeclContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetControlOpenBraceLeftTokenRange(), leftBrace, + Rule({[](FormattingContext *c) { return c->GetOptions().GetPlaceOpenBraceOnNewLineForControlBlocks(); }, + IsControlDeclContext, IsBeforeMultilineBlockContext}, + RuleAction::INSERT_NEWLINE, RuleFlags::CAN_DELETE_NEWLINES)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetFunctionOpenBraceLeftTokenRange(), leftBrace, + Rule({[](FormattingContext *c) { return c->GetOptions().GetPlaceOpenBraceOnNewLineForFunctions(); }, + IsControlDeclContext, IsBeforeMultilineBlockContext}, + RuleAction::INSERT_NEWLINE, RuleFlags::CAN_DELETE_NEWLINES)}}); +} + +void AddTypeAssertionsAndAnnotationsRules(std::vector &configRules, const TokenRange &greaterThan, + const TokenRange &colonOrQM, const TokenRange &semiOrColon, + const TokenRange &any) +{ + auto allList = GetAllTokenTypes(); + allList.push_back(lexer::TokenType::EOS); + auto anyWithEOF = CreateTokenRange(allList); + configRules.insert( + configRules.end(), + {{greaterThan, any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterTypeAssertion(); }, + IsTypeAssertionContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {any, colonOrQM, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeTypeAnnotation(); }, + IsTypeAnnotationContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {colonOrQM, any, + Rule({[](FormattingContext *c) { return !c->GetOptions().GetInsertSpaceBeforeTypeAnnotation(); }, + IsTypeAnnotationContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {semiOrColon, anyWithEOF, + Rule({[](FormattingContext *c) { return c->GetOptions().GetSemicolons() == SemicolonPreference::REMOVE; }, + IsTypeAnnotationContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} + +void AddRemainingBraceAndBinaryOpsRules(std::vector &configRules, const TokenRange &leftBrace, + const TokenRange &rightParenTok, const TokenRange &greaterThan, + const TokenRange &any) +{ + configRules.insert( + configRules.end(), + {{GetControlOpenBraceLeftTokenRange(), leftBrace, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetPlaceOpenBraceOnNewLineForControlBlocks() || c->TokensAreOnSameLine(); + }, + IsSameLineTokenOrBeforeBlockContext}, + RuleAction::INSERT_SPACE, RuleFlags::CAN_DELETE_NEWLINES)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetTypeScriptOpenBraceLeftTokenRange(), leftBrace, + Rule({[](FormattingContext *c) { return c->GetOptions().GetPlaceOpenBraceOnNewLineForFunctions(); }, + IsTypeScriptDeclWithBlockContext, IsBeforeMultilineBlockContext}, + RuleAction::INSERT_NEWLINE, RuleFlags::CAN_DELETE_NEWLINES)}, + // CC-OFFNXT(G.FMT.02) project code style + {CreateTokenRange({lexer::TokenType::KEYW_FUNCTION, lexer::TokenType::PUNCTUATOR_MULTIPLY}), rightParenTok, + Rule({[](FormattingContext *c) { + return c->GetOptions().GetInsertSpaceAfterFunctionKeywordForAnonymousFunctions(); + }, + IsFunctionDeclContext}, + RuleAction::INSERT_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {GetBinaryOperators(), any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceBeforeAndAfterBinaryOperators(); }, + IsBinaryOpContext}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {greaterThan, any, + Rule({[](FormattingContext *c) { return c->GetOptions().GetInsertSpaceAfterTypeAssertion(); }, + IsTypeAssertionContext}, + RuleAction::INSERT_NEWLINE, RuleFlags::NONE)}, + // CC-OFFNXT(G.FMT.02) project code style + {leftBrace, leftBrace, + Rule({[](FormattingContext *c) { + return !c->GetOptions().GetInsertSpaceAfterOpeningAndBeforeClosingEmptyBraces(); + }}, + RuleAction::DELETE_SPACE, RuleFlags::NONE)}}); +} + +void GetUserConfigRules(std::vector &rules, + const std::function &)> &createTokenRange) +{ + auto leftConstructor = createTokenRange({lexer::TokenType::KEYW_CONSTRUCTOR}); + auto rightParen = createTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + auto leftComma = createTokenRange({lexer::TokenType::PUNCTUATOR_COMMA}); + auto &any = GetAnyTokenRange(); + + auto leftParen = createTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS}); + auto rightParenTok = createTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS}); + auto leftBracket = createTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET}); + auto rightBracket = createTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET}); + auto leftBrace = createTokenRange({lexer::TokenType::PUNCTUATOR_LEFT_BRACE}); + auto rightBrace = createTokenRange({lexer::TokenType::PUNCTUATOR_RIGHT_BRACE}); + + auto greaterThan = createTokenRange({lexer::TokenType::PUNCTUATOR_GREATER_THAN}); + auto colonOrQM = createTokenRange({lexer::TokenType::PUNCTUATOR_QUESTION_MARK, lexer::TokenType::PUNCTUATOR_COLON}); + auto semiOrColon = createTokenRange({lexer::TokenType::PUNCTUATOR_SEMI_COLON, lexer::TokenType::PUNCTUATOR_COLON}); + + std::vector configRules; + + AddConstructorAndCommaRules(configRules, leftConstructor, rightParen, leftComma, any); + AddParenthesesRules(configRules, leftParen, rightParenTok, any); + AddBracketRules(configRules, leftBracket, rightBracket, any); + AddFunctionAndControlFlowRules( + configRules, any, leftParen, rightParenTok, + createTokenRange({lexer::TokenType::KEYW_FUNCTION, lexer::TokenType::PUNCTUATOR_MULTIPLY})); + AddBraceRules(configRules, leftBrace, rightBrace, any); + AddSemicolonAndBinaryOpRules(configRules, any); + AddFunctionParensAndControlBlocksRules(configRules, any, rightParenTok, leftBrace); + AddTypeAssertionsAndAnnotationsRules(configRules, greaterThan, colonOrQM, semiOrColon, any); + AddRemainingBraceAndBinaryOpsRules(configRules, leftBrace, rightParenTok, greaterThan, any); + + AddUserConfigRules(rules, configRules); +} + +std::vector GetAllRules() +{ + std::vector rules; + + auto createTokenRange = [](const std::vector &tokens) { + return TokenRange {TokenRange(const_cast &>(tokens), true)}; + }; + + { + std::vector p = {[](FormattingContext *ctx) { return ctx->TokensAreOnSameLine(); }, + IsConditionalOperatorContext}; + Rule rule(p, RuleAction::INSERT_SPACE, RuleFlags::NONE); + auto left = createTokenRange({lexer::TokenType::PUNCTUATOR_QUESTION_MARK}); + auto right = GetAnyTokenRange(); + rules.emplace_back(rule, left, right); + } + + AddBraceRules(rules); + AddArrowAndGenericRules(rules); + AddDecoratorRules(rules); + AddFunctionRules(rules); + AddKeywordRules(rules); + AddTypeScriptRules(rules); + AddUnaryOperatorRules(rules); + AddPunctuationRules(rules); + + GetUserConfigRules(rules, createTokenRange); + + 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..f870a4fb6362090e8f6360d13c1f657e5185ea8a --- /dev/null +++ b/ets2panda/lsp/src/formatting/rules_map.cpp @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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" +#include +#include "generated/tokenType.h" + +namespace ark::es2panda::lsp { + +RulesMapCache &RulesMapCache::Instance() +{ + static RulesMapCache cache; + return cache; +} + +RulesMap &RulesMapCache::GetRulesMap() +{ + static RulesMap rulesMap = CreateRulesMap(GetAllRules()); + return rulesMap; +} + +int RulesMapCache::GetRuleBucketIndex(lexer::TokenType left, lexer::TokenType right) +{ + constexpr int MAP_ROW_LENGTH = static_cast(LAST_TOKEN) + 1; + return (static_cast(left) * MAP_ROW_LENGTH) + static_cast(right); +} + +RuleAction RulesMapCache::GetRuleActionExclusion(RuleAction ruleAction) +{ + RuleAction mask = RuleAction::NONE; + + if ((ruleAction & RuleAction::STOP_PROCESSING_SPACE_ACTIONS) != RuleAction::NONE) { + mask |= RuleAction::MODIFY_SPACE_ACTION; + } + if ((ruleAction & RuleAction::STOP_PROCESSING_TOKEN_ACTIONS) != RuleAction::NONE) { + mask |= RuleAction::MODIFY_TOKEN_ACTION; + } + if ((ruleAction & RuleAction::MODIFY_SPACE_ACTION) != RuleAction::NONE) { + mask |= RuleAction::MODIFY_SPACE_ACTION; + } + if ((ruleAction & RuleAction::MODIFY_TOKEN_ACTION) != RuleAction::NONE) { + mask |= RuleAction::MODIFY_TOKEN_ACTION; + } + + return mask; +} + +int RulesMapCache::GetInsertionIndex(uint32_t bitmap, uint32_t shift) +{ + constexpr uint32_t MASK_BIT_SIZE = 5; + constexpr uint32_t MASK = (1U << MASK_BIT_SIZE) - 1U; + + size_t index = 0; + for (uint32_t pos = 0; pos <= shift; pos += MASK_BIT_SIZE) { + index += bitmap & MASK; + bitmap >>= MASK_BIT_SIZE; + } + + return index; +} + +int RulesMapCache::IncreaseInsertionIndex(uint32_t bitmap, uint32_t shift) +{ + constexpr uint32_t MASK_BIT_SIZE = 5; + constexpr uint32_t MASK = (1U << MASK_BIT_SIZE) - 1U; + + uint32_t count = ((bitmap >> shift) & MASK) + 1; + + ES2PANDA_ASSERT((count & MASK) == count); + return (bitmap & ~(MASK << shift)) | (count << shift); +} + +void RulesMapCache::AddRule(std::vector &ruleSpecs, RuleSpec &ruleSpec, bool specificTokens, + unsigned int &bitmap) +{ + constexpr uint32_t MASK_BIT_SIZE = 5; + constexpr int STOP_RULES_SPECIFIC = MASK_BIT_SIZE * 0; + constexpr int STOP_RULES_ANY = MASK_BIT_SIZE * 1; + constexpr int CONTEXT_RULES_SPECIFIC = MASK_BIT_SIZE * 2; + constexpr int CONTEXT_RULES_ANY = MASK_BIT_SIZE * 3; + constexpr int NO_CONTEXT_RULES_SPECIFIC = MASK_BIT_SIZE * 4; + constexpr int NO_CONTEXT_RULES_ANY = MASK_BIT_SIZE * 5; + + int shift = 0; + + if ((ruleSpec.GetRule().GetRuleAction() & RuleAction::STOP_ACTION) != RuleAction::NONE) { + shift = specificTokens ? STOP_RULES_SPECIFIC : STOP_RULES_ANY; + } else if (!ruleSpec.GetRule().GetContext().empty()) { + shift = specificTokens ? CONTEXT_RULES_SPECIFIC : CONTEXT_RULES_ANY; + } else { + shift = specificTokens ? NO_CONTEXT_RULES_SPECIFIC : NO_CONTEXT_RULES_ANY; + } + + int insertAt = GetInsertionIndex(bitmap, shift); + ruleSpecs.insert(ruleSpecs.begin() + insertAt, ruleSpec); + bitmap = IncreaseInsertionIndex(bitmap, shift); +} + +std::unordered_map> RulesMapCache::BuildMap(const std::vector &ruleSpecs) +{ + constexpr int MAP_ROW_LENGTH = static_cast(LAST_TOKEN) + 1; + + std::unordered_map> map; + std::unordered_map bucketState; + + for (auto spec : ruleSpecs) { + auto leftRange = spec.GetLeftTokenRange(); + std::vector leftTokens = leftRange.GetTokens(); + if (leftRange.GetIsSpecifier() && leftTokens.empty()) { + leftTokens.reserve(MAP_ROW_LENGTH); + for (int t = 0; t < MAP_ROW_LENGTH; ++t) { + leftTokens.emplace_back(static_cast(t)); + } + } + + auto rightRange = spec.GetRightTokenRange(); + std::vector rightTokens = rightRange.GetTokens(); + if (rightRange.GetIsSpecifier() && rightTokens.empty()) { + rightTokens.reserve(MAP_ROW_LENGTH); + for (int t = 0; t < MAP_ROW_LENGTH; ++t) { + rightTokens.emplace_back(static_cast(t)); + } + } + + bool specific = leftRange.GetIsSpecifier() && rightRange.GetIsSpecifier(); + + for (auto l : leftTokens) { + for (auto r : rightTokens) { + int idx = GetRuleBucketIndex(l, r); + auto &bucket = map[idx]; + unsigned int &bitmap = bucketState[idx]; + AddRule(bucket, spec, specific, bitmap); + } + } + } + return map; +} + +RulesMap RulesMapCache::CreateRulesMap(const std::vector &ruleSpecs) +{ + auto buckets = BuildMap(ruleSpecs); + return [buckets = std::move(buckets)](const FormattingContext &ctx) -> std::vector { + lexer::TokenType leftKind = ctx.GetCurrentToken().Type(); + lexer::TokenType rightKind = ctx.GetNextToken().Type(); + int index = GetRuleBucketIndex(leftKind, rightKind); + auto it = buckets.find(index); + if (it == buckets.end()) { + return {}; + } + + const auto &bucket = it->second; + std::vector result; + RuleAction mask = RuleAction::NONE; + + for (const auto &spec : bucket) { + auto action = spec.GetRule().GetRuleAction(); + auto exclusion = GetRuleActionExclusion(mask); + auto allowed = static_cast(~exclusion); + auto bitCheck = static_cast(action & allowed); + + if (bitCheck == RuleAction::NONE) { + continue; + } + + bool allPass = true; + for (const auto &pred : spec.GetRule().GetContext()) { + bool ok = pred(const_cast(&ctx)); + if (!ok) { + allPass = false; + break; + } + } + if (!allPass) { + continue; + } + + result.push_back(spec); + mask = static_cast(mask | action); + } + + return result; + }; +} + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/generate_constructor.cpp b/ets2panda/lsp/src/generate_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b78c0c223a369488b744b71284ff3ad28f7db741 --- /dev/null +++ b/ets2panda/lsp/src/generate_constructor.cpp @@ -0,0 +1,302 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { + +ir::AstNode *GetConstructorNode(const 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; +} + +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; + } + if (classNode->AsClassDeclaration()->Definition()->IsAbstract() && node->IsAbstract()) { + continue; + } + classProperties.emplace_back(node); + } + } + + return classProperties; +} + +std::vector GetExtendedClassProperties(ir::AstNode *classNode) +{ + auto baseNode = ark::es2panda::lsp::GetEffectiveBaseTypeNode(classNode); + if (baseNode == nullptr) { + return {}; + } + + auto constructorNode = GetConstructorNode(baseNode); + if (constructorNode == nullptr) { + return {}; + } + + std::vector extendedClassProperties; + auto params = constructorNode->AsMethodDefinition() + ->Value() + ->AsFunctionExpression() + ->Function() + ->AsScriptFunction() + ->Params(); + for (auto param : params) { + auto id = param->AsETSParameterExpression()->Ident(); + auto tmp = compiler::DeclarationFromIdentifier(id); + extendedClassProperties.emplace_back(tmp); + } + + 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); + } + } +} + +std::string FilterSubstring(const std::string &input, const std::string &toRemove) +{ + std::string result = input; + size_t pos = 0; + + while ((pos = result.find(toRemove)) != std::string::npos) { + result.erase(pos, toRemove.length()); + } + + return result; +} + +std::string GetFunctionBody(const std::vector &strVec, bool isSuper) +{ + std::string functionBody; + if (isSuper) { + functionBody += " super("; + for (const auto &str : strVec) { + functionBody += str; + functionBody += ", "; + } + RemoveTrailingChar(functionBody, ","); + functionBody += ");\n"; + } else { + for (const auto &str : strVec) { + functionBody += " this."; + functionBody += str; + functionBody += " = "; + functionBody += str; + functionBody += ";\n"; + } + } + + return functionBody; +} + +std::string GetNameForFunctionExpression(const ir::Expression *type) +{ + auto function = type->AsArrowFunctionExpression()->Function(); + if (function == nullptr || !function->IsScriptFunction()) { + return "undefined"; + } + + std::string returnType; + auto statements = function->AsScriptFunction()->Body()->AsBlockStatement()->Statements(); + if (!statements.empty()) { + auto argType = statements.at(0)->AsReturnStatement()->Argument(); + if (argType->IsStringLiteral()) { + returnType = "String"; + } else if (argType->IsNumberLiteral()) { + returnType = "Number"; + } else if (argType->IsBooleanLiteral()) { + returnType = "Boolean"; + } else { + returnType = "void"; + } + } + + return "(() => " + returnType + ")"; +} + +std::string GetNameForValue(const ir::AstNode *propertyNode) +{ + auto valueType = propertyNode->AsClassProperty()->Value(); + if (valueType == nullptr) { + return "undefined"; + } + + if (valueType->IsStringLiteral()) { + return "String"; + } + if (valueType->IsNumberLiteral()) { + return "Number"; + } + if (valueType->IsBooleanLiteral()) { + return "Boolean"; + } + if (valueType->IsArrowFunctionExpression()) { + return GetNameForFunctionExpression(valueType); + } + + return "undefined"; +} + +void GetParameterListAndFunctionBody(std::string ¶meterList, std::string &functionBody, + const std::vector &nodeList, bool isSuper) +{ + std::vector strVec = {}; + for (auto propertyNode : nodeList) { + auto nodeName = GetIdentifierName(propertyNode); + auto propertyName = FilterSubstring(nodeName, ""); + ark::es2panda::ir::TypeNode *typeAnnotation = nullptr; + if (propertyNode->IsETSParameterExpression()) { + typeAnnotation = propertyNode->AsETSParameterExpression()->TypeAnnotation(); + } else if (propertyNode->IsClassProperty()) { + typeAnnotation = propertyNode->AsClassProperty()->TypeAnnotation(); + } + + std::string propertyType; + if (typeAnnotation == nullptr) { + propertyType = GetNameForValue(propertyNode); + } else { + propertyType = GetNameForTypeNode(typeAnnotation); + } + + auto str = propertyName; + str += ": "; + str += propertyType; + str += ", "; + + if (parameterList.find(str) == std::string::npos) { + parameterList += str; + } + strVec.push_back(propertyName); + } + + auto body = GetFunctionBody(strVec, isSuper); + functionBody += body; +} + +bool HasBaseNode(ir::AstNode *classNode) +{ + return nullptr != ark::es2panda::lsp::GetEffectiveBaseTypeNode(classNode); +} + +std::string CollectConstructorInfo(ir::AstNode *classNode, const std::vector &classProperties, + const std::vector &extendedClassProperties) +{ + std::string constructorInfoText = "constructor("; + std::string parameterList; + std::string functionBody; + + if (HasBaseNode(classNode)) { + 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 (GetConstructorNode(classDeclaration) != nullptr) { + return {}; + } + + std::vector classProperties = GetClassProperties(classDeclaration, properties); + std::vector extendedClassProperties = GetExtendedClassProperties(classDeclaration); + + std::string text = CollectConstructorInfo(classDeclaration, 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..4bb625026e40f09073692956c035918f20c3ede2 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; } @@ -380,6 +383,9 @@ std::optional HandleModulesAndExports(AstNode *node, AstNode *parent, std::optional GetAdjustedLocation(AstNode *node, bool forRename, ArenaAllocator *allocator) { + if (node == nullptr) { + return std::nullopt; + } node = GetOriginalNode(node); auto *parent = node->Parent(); if (parent == nullptr) { 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..750d24fd84f4b49791d7adb62b786f544bea7554 --- /dev/null +++ b/ets2panda/lsp/src/get_class_property_info.cpp @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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); + + std::string name = GetIdentifierName(property); + + constexpr auto K_PROPERTY_PREFIX = ""; + constexpr std::size_t K_PROPERTY_PREFIX_LENGTH = std::char_traits::length(K_PROPERTY_PREFIX); + if (name.size() >= K_PROPERTY_PREFIX_LENGTH && + name.compare(0, K_PROPERTY_PREFIX_LENGTH, K_PROPERTY_PREFIX) == 0) { + name.erase(0, K_PROPERTY_PREFIX_LENGTH); + } + + FieldListProperty propertyInfo("classField", std::move(modifiersOpt), name, 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_name_or_dotted_name_span.cpp b/ets2panda/lsp/src/get_name_or_dotted_name_span.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d942472a405a23b469d0852b5d75d26113e71aa --- /dev/null +++ b/ets2panda/lsp/src/get_name_or_dotted_name_span.cpp @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_name_or_dotted_name_span.h" +#include "get_adjusted_location.h" +#include + +namespace ark::es2panda::lsp { +bool IsRightSideOfPropertyAccess(ir::AstNode *node) +{ + ir::AstNode *parent = node->Parent(); + + if (parent == nullptr) { + return false; + } + + if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { + auto *memberExpr = static_cast(parent); + return memberExpr->Property() == node; + } + + if (parent->Type() == ir::AstNodeType::CALL_EXPRESSION) { + auto *callExpr = static_cast(parent); + ir::AstNode *callee = callExpr->Callee(); + + if (callee->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { + auto *memberExpr = static_cast(callee); + return memberExpr->Property() == node; + } + } + + return false; +} + +bool IsNameOfModuleDeclaration(ir::AstNode *node) +{ + ir::AstNode *parent = node->Parent(); + if (parent == nullptr || parent->Type() != ir::AstNodeType::TS_MODULE_DECLARATION) { + return false; + } + + auto *moduleDecl = static_cast(parent); + return moduleDecl->Name() == node; +} + +bool IsRightSideOfQualifiedName(ir::AstNode *node) +{ + ir::AstNode *parent = node->Parent(); + if (parent == nullptr || (parent->Type() != ir::AstNodeType::TS_QUALIFIED_NAME && + parent->Type() != ir::AstNodeType::MEMBER_EXPRESSION)) { + return false; + } + + if (parent->Type() == ir::AstNodeType::TS_QUALIFIED_NAME) { + auto *qualifiedName = static_cast(parent); + return qualifiedName->Right() == node; + } + + if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { + auto *memberExpr = static_cast(parent); + return memberExpr->Property() == node; + } + + return false; +} + +ir::AstNode *AscendToRootName(ir::AstNode *node) +{ + while (node != nullptr) { + if (IsRightSideOfPropertyAccess(node) || IsRightSideOfQualifiedName(node)) { + node = node->Parent(); + continue; + } + + if (!IsNameOfModuleDeclaration(node)) { + break; + } + + ir::AstNode *parentDecl = node->Parent(); + if (parentDecl == nullptr || parentDecl->Parent() == nullptr) { + break; + } + + if (parentDecl->Parent()->Type() != ir::AstNodeType::TS_MODULE_DECLARATION) { + break; + } + + auto *grandParent = static_cast(parentDecl->Parent()); + if (grandParent->Body() != parentDecl) { + break; + } + + node = const_cast(static_cast(grandParent->Name())); + } + + return node; +} + +TextSpan *GetNameOrDottedNameSpanImpl(es2panda_Context *context, int startPos) +{ + ir::AstNode *astNode = ark::es2panda::lsp::GetTouchingPropertyName(context, startPos); + if (astNode == nullptr) { + return nullptr; + } + + switch (astNode->Type()) { + case ir::AstNodeType::TS_QUALIFIED_NAME: + case ir::AstNodeType::STRING_LITERAL: + case ir::AstNodeType::TS_BOOLEAN_KEYWORD: + case ir::AstNodeType::TS_NULL_KEYWORD: + case ir::AstNodeType::SUPER_EXPRESSION: + case ir::AstNodeType::THIS_EXPRESSION: + case ir::AstNodeType::TS_THIS_TYPE: + case ir::AstNodeType::IDENTIFIER: + break; + default: + return nullptr; + } + + auto nodeForStartPos = AscendToRootName(astNode); + if (nodeForStartPos == nullptr) { + return nullptr; + } + size_t start = nodeForStartPos->Start().index; + size_t end = nodeForStartPos->End().index; + if (start >= end) { + return nullptr; + } + + auto span = new TextSpan(start, end - start); + return span; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/get_node.cpp b/ets2panda/lsp/src/get_node.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa9ea5fea6026f135008bce38bcce5cdd328db09 --- /dev/null +++ b/ets2panda/lsp/src/get_node.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "get_node.h" +#include "public/es2panda_lib.h" +#include "public/public.h" + +namespace ark::es2panda::lsp { +es2panda_AstNode *GetProgramAstImpl(es2panda_Context *context) +{ + if (context == nullptr) { + return nullptr; + } + auto ctx = reinterpret_cast(context); + return reinterpret_cast(ctx->parserProgram->Ast()); +} + +es2panda_AstNode *GetClassDefinitionImpl(es2panda_AstNode *astNode, const std::string &nodeName) +{ + if (astNode == nullptr) { + return nullptr; + } + auto ast = reinterpret_cast(astNode); + auto targetNode = ast->FindChild([&nodeName](ir::AstNode *childNode) { + return childNode->IsClassDefinition() && + std::string(childNode->AsClassDefinition()->Ident()->Name()) == nodeName; + }); + return reinterpret_cast(targetNode); +} + +es2panda_AstNode *GetIdentifierImpl(es2panda_AstNode *astNode, const std::string &nodeName) +{ + if (astNode == nullptr) { + return nullptr; + } + auto ast = reinterpret_cast(astNode); + auto targetNode = ast->FindChild([&nodeName](ir::AstNode *childNode) { + return childNode->IsIdentifier() && std::string(childNode->AsIdentifier()->Name()) == nodeName; + }); + return reinterpret_cast(targetNode); +} + +} // 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..ddeeb93ddee4413b46e33d058bf5db65b957aab3 --- /dev/null +++ b/ets2panda/lsp/src/get_safe_delete_info.cpp @@ -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. + */ + +#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 { +constexpr size_t BUILTIN_TYPE_COUNT = 9; +constexpr std::array BUILTIN_TYPES = { + "Number", "String", "Boolean", "void", "BigInt", "Never", "undefined", "null", "Object"}; +} // namespace + +namespace ark::es2panda::lsp { + +bool IsBuiltinTypeReference(ir::AstNode *node) +{ + if (node == nullptr || node->Type() != ir::AstNodeType::IDENTIFIER) { + return false; + } + auto *parent = node->Parent(); + while (parent != nullptr) { + if (parent->Type() == ir::AstNodeType::ETS_TYPE_REFERENCE_PART || + parent->Type() == ir::AstNodeType::ETS_TYPE_REFERENCE) { + std::string nameStr(node->AsIdentifier()->Name()); + auto it = + std::find_if(BUILTIN_TYPES.begin(), BUILTIN_TYPES.end(), [&](const char *s) { return nameStr == s; }); + if (it != BUILTIN_TYPES.end()) { + return true; + } + } + parent = parent->Parent(); + } + return false; +} + +bool IsDeletableDecl(ir::AstNode *node) +{ + return node->IsFunctionDeclaration() || node->IsVariableDeclarator() || node->IsClassProperty() || + node->Type() == ir::AstNodeType::METHOD_DEFINITION || node->Type() == ir::AstNodeType::CLASS_DECLARATION || + node->IsTSTypeParameterDeclaration() || node->IsImportDefaultSpecifier() || + node->Type() == ir::AstNodeType::ETS_TYPE_REFERENCE_PART || node->IsCallExpression() || + node->IsETSImportDeclaration() || node->IsImportSpecifier() || node->IsBinaryExpression() || + node->IsTSInterfaceDeclaration() || node->IsETSTypeReferencePart() || node->IsImportNamespaceSpecifier() || + node->IsTSTypeAliasDeclaration() || node->IsExpressionStatement() || node->IsMemberExpression() || + node->IsTypeofExpression(); +} + +ir::AstNode *FindNearestDeletableDecl(ir::AstNode *node) +{ + ir::AstNode *cur = node; + while (cur != nullptr) { + if (IsDeletableDecl(cur)) { + return cur; + } + cur = cur->Parent(); + } + return nullptr; +} + +std::string NormalizeFilePath(const std::string &filePath) +{ + std::string normPath = filePath; + std::transform(normPath.begin(), normPath.end(), normPath.begin(), ::tolower); + std::replace(normPath.begin(), normPath.end(), '\\', '/'); + return normPath; +} + +/** + * Distinguish a namespace from a class by checking whether the class body contains only the $init$ method and has + * no constructor + */ +bool IsNamespaceClass(ir::AstNode *astNode) +{ + if (astNode->Type() != ir::AstNodeType::CLASS_DECLARATION) { + return false; + } + auto *classDecl = static_cast(astNode); + const auto &body = classDecl->Definition()->Body(); + bool hasConstructor = false; + bool onlyInit = true; + for (auto *member : body) { + if (member->Type() == ir::AstNodeType::METHOD_DEFINITION) { + auto *method = static_cast(member); + util::StringView keyName = method->Key()->AsIdentifier()->Name(); + if (keyName == "constructor") { + hasConstructor = true; + } + if (keyName != "_$init$_") { + onlyInit = false; + } + } + } + return !hasConstructor && onlyInit; +} + +bool GetSafeDeleteInfoImpl(es2panda_Context *context, size_t position) +{ + auto astNode = GetTouchingToken(context, position, false); + if (astNode == nullptr) { + return false; + } + + auto declInfo = GetDeclInfoImpl(astNode); + auto fileName = std::get<0>(declInfo); + std::string normFileName = NormalizeFilePath(fileName); + if (!normFileName.empty() && normFileName.find("ets1.2/build-tools/ets2panda/lib/stdlib") != std::string::npos) { + return false; + } + if (!normFileName.empty() && normFileName.find("/sdk/") != std::string::npos) { + return false; + } + + if (IsBuiltinTypeReference(astNode)) { + return false; + } + + astNode = FindNearestDeletableDecl(astNode); + if (astNode == nullptr) { + return false; + } + + if (IsNamespaceClass(astNode)) { + return false; + } + + if (astNode->IsTSTypeParameterDeclaration()) { + return false; + } + + return true; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/get_signature.cpp b/ets2panda/lsp/src/get_signature.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3247ca95ad78697fa2cb63a7c39433cc298f98e0 --- /dev/null +++ b/ets2panda/lsp/src/get_signature.cpp @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "checker/types/signature.h" +#include "compiler/lowering/util.h" +#include "get_signature.h" +#include "internal_api.h" +#include "ir/astNode.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +namespace ark::es2panda::lsp { + +size_t FindFirstNonSpaceLeft(const std::string &str, size_t pos) +{ + if (str.empty()) { + return std::string::npos; + } + + if (pos >= str.size()) { + pos = str.size() - 1; + } + + for (size_t i = pos;; --i) { + if (std::isspace(static_cast(str[i])) == 0) { + return i; + } + + if (i == 0) { + break; + } + } + + return std::string::npos; +} + +SignatureHelpItems MakeSignatureHelpItem(ir::AstNode *callExpressionNode, ir::AstNode *node, ir::AstNode *declNode, + checker::Signature *signature, size_t position) +{ + SignatureHelpItems res; + res.SetApplicableSpan(node->End().index + 1, position - node->End().index - 1); + res.SetArgumentIndex(callExpressionNode->AsCallExpression()->Arguments().size()); + auto params = signature->GetSignatureInfo()->params; + auto returnType = signature->ReturnType(); + res.SetArgumentCount(params.size()); + + SignatureHelpItem item; + auto methodName = std::string(declNode->AsMethodDefinition()->Id()->Name()); + item.SetPrefixDisplayParts(SymbolDisplayPart(methodName, "functionName")); + item.SetPrefixDisplayParts(SymbolDisplayPart("(", "punctuation")); + + item.SetSeparatorDisplayParts(SymbolDisplayPart(",", "punctuation")); + item.SetSeparatorDisplayParts(SymbolDisplayPart(" ", "space")); + + item.SetSuffixDisplayParts(SymbolDisplayPart(")", "punctuation")); + item.SetSuffixDisplayParts(SymbolDisplayPart(" ", "space")); + item.SetSuffixDisplayParts(SymbolDisplayPart("=>", "punctuation")); + item.SetSuffixDisplayParts(SymbolDisplayPart(" ", "space")); + item.SetSuffixDisplayParts(SymbolDisplayPart(returnType->ToString(), "keyword")); + + for (auto param : params) { + SignatureHelpParameter paramItem; + auto paramName = std::string(param->Name()); + auto paramType = param->TsType()->ToString(); + paramItem.SetName(paramName); + paramItem.SetDisplayParts(SymbolDisplayPart(paramName, "parameterNmae")); + paramItem.SetDisplayParts(SymbolDisplayPart(":", "punctuation")); + paramItem.SetDisplayParts(SymbolDisplayPart(" ", "space")); + paramItem.SetDisplayParts(SymbolDisplayPart(paramType, "keyword")); + item.SetParameters(paramItem); + } + + res.SetItems(item); + return res; +} + +SignatureHelpItems GetSignature(es2panda_Context *context, size_t position) +{ + SignatureHelpItems res; + if (context == nullptr) { + return res; + } + + auto callExpressionNode = GetTouchingToken(context, position, false); + if (callExpressionNode == nullptr || !callExpressionNode->IsCallExpression()) { + return res; + } + + auto ctx = reinterpret_cast(context); + auto sourceCode = ctx->parserProgram->SourceCode(); + if (position >= sourceCode.Length()) { + return res; + } + + auto foundPos = std::string(sourceCode).rfind('(', position); + auto targetPos = FindFirstNonSpaceLeft(std::string(sourceCode), foundPos); + auto node = GetTouchingToken(context, targetPos - 1, false); + if (node == nullptr || !node->IsIdentifier()) { + return res; + } + + auto declNode = compiler::DeclarationFromIdentifier(node->AsIdentifier()); + if (declNode == nullptr || !declNode->IsMethodDefinition()) { + return res; + } + + auto function = declNode->AsMethodDefinition()->Function(); + if (function == nullptr) { + return res; + } + + auto signature = function->Signature(); + if (signature == nullptr) { + return res; + } + res = MakeSignatureHelpItem(callExpressionNode, node, declNode, signature, position); + return res; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/inlay_hints.cpp b/ets2panda/lsp/src/inlay_hints.cpp index 57694175958c2b984b985bd264747ae7a355e2d2..4aecc7a552c694a4bf1ea0453506da112d0da80c 100644 --- a/ets2panda/lsp/src/inlay_hints.cpp +++ b/ets2panda/lsp/src/inlay_hints.cpp @@ -13,17 +13,37 @@ * limitations under the License. */ -#include "inlay_hints.h" #include #include #include -#include "public/public.h" -#include "internal_api.h" #include "cancellation_token.h" +#include "compiler/lowering/util.h" +#include "inlay_hints.h" +#include "public/public.h" #include "utils/arena_containers.h" namespace ark::es2panda::lsp { +/** + * this function tries to find the first child node that includes the given span. + * It can be used to avoid double processing of the same node, like in the following case in global scope: + * 1) let a = map.get("a"); + * In this case, the call expression node will be included both in the init method and in the global class property. + */ +ir::AstNode *TryGetIncludingNode(const ir::AstNode *ast, const TextSpan *span) +{ + if (ast == nullptr || span == nullptr) { + return nullptr; + } + auto expectedStart = span->start; + auto expectedEnd = expectedStart + span->length; + auto checkFunc = [&expectedStart, &expectedEnd](ir::AstNode *node) { + return expectedStart <= node->Range().end.index && node->Range().start.index <= expectedEnd; + }; + auto *found = ast->FindChild(checkFunc); + return found; +} + int GetFullWidth(const ir::AstNode *node) { return node->End().index - node->Start().index; @@ -77,7 +97,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 || node->Type() == ir::AstNodeType::NEW_EXPRESSION; } void GetVariableDeclarationTypeForHints(const ir::AstNode *decl, InlayHintList *result) @@ -105,21 +125,23 @@ void GetVariableDeclarationTypeForHints(const ir::AstNode *decl, InlayHintList * return false; }); } -void AddParamIfTypeRef(const ir::AstNode *childNode, const ArenaVector &args, InlayHintList *result) + +void AddParamIfTypeRef(const ir::MethodDefinition *decl, const ArenaVector &args, + InlayHintList *result) { int paramIndex = 0; - childNode->FindChild([¶mIndex, args, &result](ark::es2panda::ir::AstNode *node) { - if (node->IsETSParameterExpression()) { - auto part = node->AsETSParameterExpression()->Name().Utf8(); - std::string s1 {part.data(), part.size()}; - AddParameterHints(std::string(s1), args.at(paramIndex)->Start().index, false, result); + auto params = decl->Function()->Params(); + for (const auto ¶m : params) { + if (param->IsETSParameterExpression()) { + auto part = param->AsETSParameterExpression()->Name().Utf8(); + std::string text {part.data(), part.size()}; + AddParameterHints(text, args.at(paramIndex)->Start().index, false, result); paramIndex++; } - return false; - }); + } } -void GetCallExpTypeForHints(const ir::AstNode *expr, const ir::AstNode *parent, InlayHintList *result) +void GetCallExpTypeForHints(const ir::AstNode *expr, [[maybe_unused]] const ir::AstNode *parent, InlayHintList *result) { const ir::Expression *callee; if (expr->IsCallExpression()) { @@ -129,7 +151,7 @@ void GetCallExpTypeForHints(const ir::AstNode *expr, const ir::AstNode *parent, } else { return; } - if (!callee->IsIdentifier()) { + if (!(callee->IsIdentifier() || callee->IsMemberExpression())) { return; } const auto args = @@ -138,13 +160,12 @@ void GetCallExpTypeForHints(const ir::AstNode *expr, const ir::AstNode *parent, return; } - parent->FindChild([args, callee, &result](ark::es2panda::ir::AstNode *childNode) { - if (childNode->IsMethodDefinition() && - childNode->AsMethodDefinition()->Function()->Id()->ToString() == callee->AsIdentifier()->Name().Utf8()) { - AddParamIfTypeRef(childNode, args, result); - } - return false; - }); + auto *decl = callee->IsIdentifier() + ? compiler::DeclarationFromIdentifier(callee->AsIdentifier()) + : compiler::DeclarationFromIdentifier(callee->AsMemberExpression()->Property()->AsIdentifier()); + if (decl != nullptr && decl->IsMethodDefinition()) { + AddParamIfTypeRef(decl->AsMethodDefinition(), args, result); + } } bool ShouldShowParameterNameHints(const UserPreferences &preferences) @@ -357,24 +378,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 +418,14 @@ 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}; + const auto *searchNode = TryGetIncludingNode(parent, span); + searchNode = searchNode == nullptr ? parent : searchNode; + searchNode->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..3162e6643295cb7fc310239fb1f99547801c46bf 100644 --- a/ets2panda/lsp/src/internal_api.cpp +++ b/ets2panda/lsp/src/internal_api.cpp @@ -20,6 +20,7 @@ #include "api.h" #include "internal_api.h" #include "checker/types/type.h" +#include "code_fixes/code_fix_types.h" #include "compiler/lowering/util.h" #include "ir/astNode.h" #include "lexer/token/sourceLocation.h" @@ -27,6 +28,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 "generated/code_fix_register.h" namespace ark::es2panda::lsp { @@ -113,27 +118,37 @@ std::string FormatStringFromArgs(const std::string &textStr, return ss.str(); } -FileDiagnostic CreateFileDiagnostic(es2panda_AstNode *node, lexer::SourceRange span, Diagnostic diagnostic, +FileDiagnostic CreateFileDiagnostic(es2panda_AstNode *node, Range span, Diagnostic diagnostic, const std::vector &args = std::vector()) { if (!args.empty()) { std::string newMessageStr = FormatStringFromArgs(diagnostic.message_, args); diagnostic.message_ = newMessageStr; } - FileDiagnostic fileDiagnostic(node, diagnostic, TransSourcePositionToPosition(span.start), - TransSourcePositionToPosition(span.end)); + FileDiagnostic fileDiagnostic(node, diagnostic, span.start, span.end); return fileDiagnostic; } -lexer::SourceRange GetErrorRangeForNode(ir::AstNode *node) +Range GetErrorRangeForNode(ir::AstNode *node, es2panda_Context *context) { - return lexer::SourceRange(node->Start(), node->End()); + auto ctx = reinterpret_cast(context); + // The line and col should start from 1 istead of 0 + auto index = lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto sourceStartLocation = index.GetLocation(node->Range().start); + auto sourceEndLocation = index.GetLocation(node->Range().end); + Position posStart(sourceStartLocation.line, sourceStartLocation.col); + Position posEnd(sourceEndLocation.line, sourceEndLocation.col); + return Range(posStart, posEnd); } -FileDiagnostic CreateDiagnosticForNode(es2panda_AstNode *node, Diagnostic diagnostic, +FileDiagnostic CreateDiagnosticForNode(es2panda_AstNode *node, Diagnostic diagnostic, es2panda_Context *context, const std::vector &args) { - auto span = GetErrorRangeForNode(reinterpret_cast(node)); + auto span = diagnostic.range_; + // Only genereate range when original range is invalid + if (span.start.character_ <= 0 || span.end.character_ <= 0 || span.start.line_ <= 0 || span.end.line_ <= 0) { + span = GetErrorRangeForNode(reinterpret_cast(node), context); + } auto res = CreateFileDiagnostic(node, span, std::move(diagnostic), args); return res; } @@ -506,16 +521,28 @@ std::string GetOwnerId(ir::AstNode *node) DiagnosticSeverity GetSeverity(util::DiagnosticType errorType) { ES2PANDA_ASSERT(errorType != util::DiagnosticType::INVALID); - if (errorType == util::DiagnosticType::WARNING) { + if (errorType == util::DiagnosticType::WARNING || errorType == util::DiagnosticType::PLUGIN_WARNING) { return DiagnosticSeverity::Warning; } if (errorType == util::DiagnosticType::SYNTAX || errorType == util::DiagnosticType::SEMANTIC || - errorType == util::DiagnosticType::FATAL || errorType == util::DiagnosticType::ARKTS_CONFIG_ERROR) { + errorType == util::DiagnosticType::FATAL || errorType == util::DiagnosticType::ARKTS_CONFIG_ERROR || + errorType == util::DiagnosticType::PLUGIN_ERROR) { return DiagnosticSeverity::Error; } throw std::runtime_error("Unknown error type!"); } +// Temp design only support UI Plugin Diag. +int CreateCodeForDiagnostic(const util::DiagnosticBase *error) +{ + const int uiCode = 4000; + if (error->Type() == util::DiagnosticType::PLUGIN_ERROR || error->Type() == util::DiagnosticType::PLUGIN_WARNING) { + return uiCode; + } + auto code = static_cast(error)->GetId(); + return static_cast(error->Type()) * codefixes::DiagnosticCode::DIAGNOSTIC_CODE_MULTIPLIER + code; +} + Diagnostic CreateDiagnosticForError(es2panda_Context *context, const util::DiagnosticBase &error) { auto ctx = reinterpret_cast(context); @@ -539,7 +566,7 @@ Diagnostic CreateDiagnosticForError(es2panda_Context *context, const util::Diagn auto range = Range(Position(sourceStartLocation.line, sourceStartLocation.col), Position(sourceEndLocation.line, sourceEndLocation.col)); auto severity = GetSeverity(error.Type()); - auto code = 1; + auto code = CreateCodeForDiagnostic(&error); std::string message = error.Message(); auto codeDescription = CodeDescription("test code description"); auto tags = std::vector(); @@ -592,13 +619,33 @@ 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()}; return res; } +std::string GetImportFilePath(es2panda_Context *context, size_t pos) +{ + std::string res; + auto node = GetTouchingToken(context, pos, false); + if (node == nullptr) { + return res; + } + auto parent = node->Parent(); + if (parent != nullptr && parent->IsETSImportDeclaration() && parent->AsETSImportDeclaration()->Source() == node) { + res = std::string(parent->AsETSImportDeclaration()->ImportMetadata().resolvedSource); + } + return res; +} + ArenaVector RemoveRefDuplicates(const ArenaVector &nodes, ArenaAllocator *allocator) { auto hashFunc = [](const ir::AstNode *node) { @@ -631,6 +678,17 @@ void FindAllChild(const ir::AstNode *ast, const ir::NodePredicate &cb, ArenaVect ast->Iterate([&results, cb](ir::AstNode *child) { FindAllChildHelper(child, cb, results); }); } +ir::AstNode *FindAncestor(ir::AstNode *node, const ir::NodePredicate &cb) +{ + while (node != nullptr) { + if (cb(node)) { + return node; + } + node = node->Parent(); + } + return node; +} + ArenaVector FindReferencesByName(ir::AstNode *ast, ir::AstNode *decl, ir::AstNode *node, ArenaAllocator *allocator) { @@ -663,6 +721,8 @@ HighlightSpanKind GetHightlightSpanKind(ir::AstNode *identifierDeclaration, ir:: DocumentHighlights GetSemanticDocumentHighlights(es2panda_Context *context, size_t position) { auto ctx = reinterpret_cast(context); + SetPhaseManager(ctx->phaseManager); + auto ast = ctx->parserProgram->Ast(); std::string fileName(ctx->sourceFile->filePath); auto touchingToken = GetTouchingToken(context, position, false); if (!touchingToken->IsIdentifier()) { @@ -672,13 +732,24 @@ DocumentHighlights GetSemanticDocumentHighlights(es2panda_Context *context, size if (decl == nullptr) { return DocumentHighlights(fileName, {}); } - auto references = FindReferencesByName(ctx->parserProgram->Ast(), decl, touchingToken, ctx->allocator); + auto checkFunc = [&touchingToken](ir::AstNode *child) { + return child->IsIdentifier() && child->AsIdentifier()->Name() == touchingToken->AsIdentifier()->Name(); + }; + // Find the identifier's declaration. We consider the first found to be the identifier's declaration. + auto identifierDeclaration = decl->FindChild(checkFunc); + if (identifierDeclaration == nullptr) { + // If the identifier is not found in the declaration, we try to find it in the AST. + // This is needed for cases like `import {Foo as foo} from './a';` where + // `foo` is a alias for the imported `Foo` identifier. + identifierDeclaration = ast->FindChild(checkFunc); + } + if (identifierDeclaration == nullptr) { + return DocumentHighlights(fileName, {}); + } + + auto references = FindReferencesByName(ast, decl, touchingToken, ctx->allocator); auto highlightSpans = std::vector(); - // Find the identifier's declaration. We consider the first found to be the identifier's declaration. - ir::AstNode *identifierDeclaration = decl->FindChild([&touchingToken](ir::AstNode *child) { - return child->IsIdentifier() && child->AsIdentifier()->Name() == touchingToken->AsIdentifier()->Name(); - }); for (const auto &reference : references) { auto start = reference->Start().index; auto length = reference->AsIdentifier()->Name().Length(); @@ -695,4 +766,116 @@ 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); +} + +varbinder::Decl *FindDeclInGlobalScope(varbinder::Scope *scope, const util::StringView &name) +{ + const auto *scopeIter = scope; + varbinder::Decl *resolved = nullptr; + while (scopeIter != nullptr && !scopeIter->IsGlobalScope()) { + bool isModule = scopeIter->Node() != nullptr && scopeIter->Node()->IsClassDefinition() && + scopeIter->Node()->AsClassDefinition()->IsModule(); + if (isModule) { + resolved = scopeIter->FindDecl(name); + if (resolved != nullptr) { + break; + } + } + scopeIter = scopeIter->Parent(); + } + if (resolved == nullptr && scopeIter != nullptr && scopeIter->IsGlobalScope()) { + resolved = scopeIter->FindDecl(name); + } + return resolved; +} + +varbinder::Decl *FindDeclInFunctionScope(varbinder::Scope *scope, const util::StringView &name) +{ + const auto *scopeIter = scope; + while (scopeIter != nullptr && !scopeIter->IsGlobalScope()) { + if (!scopeIter->IsClassScope()) { + if (auto *const resolved = scopeIter->FindDecl(name); resolved != nullptr) { + return resolved; + } + } + scopeIter = scopeIter->Parent(); + } + + return nullptr; +} + +varbinder::Decl *FindDeclInScopeWithFallback(varbinder::Scope *scope, const util::StringView &name) +{ + if (auto *decl = FindDeclInFunctionScope(scope, name)) { + return decl; + } + return FindDeclInGlobalScope(scope, name); +} + } // 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..77f06d2da7ae35876a82c166d868c86a8942a97d --- /dev/null +++ b/ets2panda/lsp/src/isolated_declaration.cpp @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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, + [[maybe_unused]] 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::GRADUAL_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/node_matchers.cpp b/ets2panda/lsp/src/node_matchers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6b8e9c7b562730b132745351b6af3c0e6197bf4 --- /dev/null +++ b/ets2panda/lsp/src/node_matchers.cpp @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "node_matchers.h" +#include +#include +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include "ir/statements/annotationDeclaration.h" +#include "ir/statements/annotationUsage.h" + +namespace ark::es2panda::lsp { + +bool MatchClassDefinition(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsClassDefinition() && std::string(childNode->AsClassDefinition()->Ident()->Name()) == info->name; +} + +bool MatchIdentifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsIdentifier() && std::string(childNode->AsIdentifier()->Name()) == info->name; +} + +bool MatchClassProperty(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsClassProperty() && std::string(childNode->AsClassProperty()->Id()->Name()) == info->name; +} + +bool MatchProperty(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsProperty() && std::string(childNode->AsProperty()->Key()->AsIdentifier()->Name()) == info->name; +} + +bool MatchMethodDefinition(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsMethodDefinition() && + std::string(childNode->AsMethodDefinition()->Function()->Id()->Name()) == info->name; +} + +bool MatchTSEnumDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSEnumDeclaration() && + std::string(childNode->AsTSEnumDeclaration()->Key()->Name()) == info->name; +} + +bool MatchTSEnumMember(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSEnumMember() && std::string(childNode->AsTSEnumMember()->Name()) == info->name; +} + +bool MatchTSInterfaceDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSInterfaceDeclaration() && + std::string(childNode->AsTSInterfaceDeclaration()->Id()->Name()) == info->name; +} + +bool MatchTSTypeAliasDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSTypeAliasDeclaration() && + std::string(childNode->AsTSTypeAliasDeclaration()->Id()->Name()) == info->name; +} + +bool MatchExportSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSReExportDeclaration()) { + return false; + } + auto specifiers = childNode->AsETSReExportDeclaration()->GetETSImportDeclarations()->Specifiers(); + if (specifiers.empty()) { + return false; + } + for (auto *importSpecifier : specifiers) { + if (importSpecifier->IsImportSpecifier() && + importSpecifier->AsImportSpecifier()->Local()->Name().Mutf8() == info->name) { + return true; + } + if (importSpecifier->IsImportSpecifier() && + importSpecifier->AsImportSpecifier()->Imported()->Name().Mutf8() == info->name) { + return true; + } + } + return false; +} + +bool MatchMemberExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsMemberExpression() && childNode->AsMemberExpression()->Property()->ToString() == info->name; +} + +bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsTSClassImplements()) { + return false; + } + auto dd = childNode->AsTSClassImplements()->Expr()->AsETSTypeReference()->Part(); + return std::string(dd->GetIdent()->Name()) == info->name; +} + +bool MatchCallExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (childNode->IsCallExpression()) { + auto callExpr = childNode->AsCallExpression(); + auto callee = callExpr->Callee(); + if (callee->IsIdentifier()) { + return std::string(callee->AsIdentifier()->Name()) == info->name; + } + if (callee->IsSuperExpression() && info->name == "super") { + return true; + } + if (callee->IsMemberExpression()) { + return callee->AsMemberExpression()->Property()->ToString() == info->name; + } + } + return false; +} + +bool MatchTsTypeReference(ir::AstNode *childNode, const NodeInfo *info) +{ + if (childNode->IsETSTypeReference()) { + auto typeRef = childNode->AsETSTypeReference(); + auto part = typeRef->Part(); + if (part != nullptr && part->Name()->IsIdentifier()) { + auto identifier = part->Name()->AsIdentifier(); + if (std::string(identifier->Name()) == info->name) { + return true; + } + } + } + return false; +} + +bool MatchScriptFunction(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsScriptFunction() && std::string(childNode->AsScriptFunction()->Id()->Name()) == info->name; +} + +ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsETSReExportDeclaration()) { + return node; + } + + auto specifiers = node->AsETSReExportDeclaration()->GetETSImportDeclarations()->Specifiers(); + if (specifiers.empty()) { + return node; + } + + for (auto *importSpecifier : specifiers) { + if (!importSpecifier->IsImportSpecifier()) { + continue; + } + + if (importSpecifier->AsImportSpecifier()->Local()->Name().Mutf8() == info->name) { + return importSpecifier->AsImportSpecifier()->Local(); + } + if (importSpecifier->AsImportSpecifier()->Imported()->Name().Mutf8() == info->name) { + return importSpecifier->AsImportSpecifier()->Imported(); + } + } + + return node; +} + +ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsTSClassImplements()) { + return node; + } + + auto expr = node->AsTSClassImplements()->Expr(); + if ((expr == nullptr) || !expr->IsETSTypeReference()) { + return node; + } + + auto part = expr->AsETSTypeReference()->Part(); + if ((part == nullptr) || (part->GetIdent() == nullptr)) { + return node; + } + + if (std::string(part->GetIdent()->Name()) == info->name) { + return part->GetIdent(); + } + + return node; +} + +bool GetNodeNameIsStringLiteralType(ir::AstNode *childNode, const std::string &nodeName) +{ + if (childNode->Parent() == nullptr) { + return false; + } + auto parentNode = reinterpret_cast(childNode->Parent()); + if (parentNode->IsClassProperty()) { + return std::string(parentNode->AsClassProperty()->Id()->Name()) == nodeName; + } + if (parentNode->IsIdentifier()) { + return std::string(parentNode->AsIdentifier()->Name()) == nodeName; + } + if (parentNode->IsETSUnionType()) { + auto unionTypeParentAst = reinterpret_cast(parentNode->Parent()); + if (unionTypeParentAst->IsTSTypeAliasDeclaration()) { + return std::string(unionTypeParentAst->AsTSTypeAliasDeclaration()->Id()->Name()) == nodeName; + } + } + if (parentNode->IsETSParameterExpression()) { + return std::string(parentNode->AsETSParameterExpression()->Name()) == nodeName; + } + if (parentNode->IsTSTypeAliasDeclaration()) { + return std::string(parentNode->AsTSTypeAliasDeclaration()->Id()->Name()) == nodeName; + } + return false; +} + +bool MatchEtsStringLiteralType(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSStringLiteralType()) { + return false; + } + return GetNodeNameIsStringLiteralType(childNode, std::string(info->name)); +} + +ir::AstNode *ExtractETSStringLiteralTypeIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsETSStringLiteralType()) { + return nullptr; + } + if (GetNodeNameIsStringLiteralType(node, std::string(info->name))) { + return node->Parent(); + } + return nullptr; +} + +bool MatchEtsTypeReference(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSTypeReference()) { + return false; + } + return std::string(childNode->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +bool MatchEtsKeyofType(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSKeyofType()) { + return false; + } + + auto typeRef = childNode->AsETSKeyofType()->GetTypeRef(); + if (typeRef == nullptr) { + return false; + } + return typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +ir::AstNode *ExtractETSKeyofTypeIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsETSKeyofType()) { + return nullptr; + } + auto typeRef = node->AsETSKeyofType()->GetTypeRef(); + if (typeRef == nullptr) { + return nullptr; + } + bool result = typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; + if (result) { + return node->Parent(); + } + return nullptr; +} + +bool MatchEtsNewClassInstanceExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSNewClassInstanceExpression()) { + return false; + } + + auto typeRef = childNode->AsETSNewClassInstanceExpression()->GetTypeRef(); + if (typeRef == nullptr) { + return false; + } + return typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +bool MatchEtsStructDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSStructDeclaration()) { + return false; + } + return std::string(childNode->AsETSStructDeclaration()->Definition()->Ident()->Name()) == info->name; +} + +bool MatchSpreadElement(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsSpreadElement()) { + return false; + } + auto argument = childNode->AsSpreadElement()->Argument(); + if (argument == nullptr) { + return false; + } + + if (argument->IsIdentifier()) { + return std::string(argument->AsIdentifier()->Name()) == info->name; + } + if (argument->IsMemberExpression()) { + return std::string(argument->AsMemberExpression()->Property()->ToString()) == info->name; + } + + return false; +} + +ir::AstNode *ExtractCallExpressionIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (node->IsCallExpression()) { + auto callExpr = node->AsCallExpression(); + auto callee = callExpr->Callee(); + if (callee->IsIdentifier() && std::string(callee->AsIdentifier()->Name()) == info->name) { + return callee->AsIdentifier(); + } + if (callee->IsSuperExpression() && info->name == "super") { + return callee->AsSuperExpression(); + } + if (callee->IsMemberExpression() && callee->AsMemberExpression()->Property()->ToString() == info->name) { + return callee->AsMemberExpression()->Property()->AsIdentifier(); + } + } + return node; +} + +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclarator() && + std::string(childNode->AsVariableDeclarator()->Id()->AsIdentifier()->Name()) == info->name; +} + +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclaration() && + std::string(childNode->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name()) == + info->name; +} + +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsClassDeclaration() && + std::string(childNode->AsClassDeclaration()->Definition()->Ident()->Name()) == info->name; +} + +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationDeclaration() && + std::string(childNode->AsAnnotationDeclaration()->GetBaseName()->Name()) == info->name; +} + +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationUsage() && + std::string(childNode->AsAnnotationUsage()->GetBaseName()->Name()) == info->name; +} + +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsAwaitExpression()) { + return false; + } + auto awaitExpr = childNode->AsAwaitExpression(); + if ((awaitExpr != nullptr) && (awaitExpr->Argument() != nullptr) && awaitExpr->Argument()->IsIdentifier()) { + auto identifier = awaitExpr->Argument()->AsIdentifier(); + return (identifier != nullptr) && std::string(identifier->Name()) == info->name; + } + return false; +} + +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsBigIntLiteral()) { + return false; + } + std::string bigIntLiteral = std::string(childNode->AsBigIntLiteral()->Str()); + if (childNode->Parent()->IsUnaryExpression()) { + bigIntLiteral.insert(0, lexer::TokenToString(childNode->Parent()->AsUnaryExpression()->OperatorType())); + return bigIntLiteral == info->name; + } + return bigIntLiteral == info->name; +} + +ir::AstNode *ExtractAwaitExpressionIdentifier(ir::AstNode *node, [[maybe_unused]] const NodeInfo *info) +{ + if (!node->IsAwaitExpression()) { + return node; + } + + if ((node->AsAwaitExpression()->Argument() != nullptr) && node->AsAwaitExpression()->Argument()->IsIdentifier()) { + return const_cast(node->AsAwaitExpression()->Argument()->AsIdentifier()); + } + return node; +} + +bool MatchImportSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportSpecifier() && + std::string(childNode->AsImportSpecifier()->Imported()->Name()) == info->name; +} + +bool MatchImportDefaultSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportDefaultSpecifier() && + std::string(childNode->AsImportDefaultSpecifier()->Local()->Name()) == info->name; +} + +bool MatchImportNamespaceSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportNamespaceSpecifier() && + std::string(childNode->AsImportNamespaceSpecifier()->Local()->Name()) == info->name; +} + +bool MatchTSTypeParameter(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSTypeParameter() && std::string(childNode->AsTSTypeParameter()->Name()->Name()) == info->name; +} + +bool MatchEtsParameterExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsETSParameterExpression() && + std::string(childNode->AsETSParameterExpression()->Ident()->Name()) == info->name; +} + +bool MatchSwitchStatement(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsSwitchStatement()) { + return false; + } + auto discriminant = childNode->AsSwitchStatement()->Discriminant(); + if (discriminant == nullptr) { + return false; + } + if (discriminant->IsIdentifier()) { + return std::string(discriminant->AsIdentifier()->Name()) == info->name; + } + if (discriminant->IsMemberExpression()) { + return std::string(discriminant->AsMemberExpression()->Object()->AsIdentifier()->Name()) == info->name; + } + return false; +} + +bool MatchTsNonNullExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsTSNonNullExpression()) { + return false; + } + auto expression = childNode->AsTSNonNullExpression()->Expr(); + if (expression == nullptr) { + return false; + } + if (expression->IsIdentifier()) { + return std::string(expression->AsIdentifier()->Name()) == info->name; + } + if (expression->IsMemberExpression()) { + return std::string(expression->AsMemberExpression()->Object()->AsIdentifier()->Name()) == info->name || + std::string(expression->AsMemberExpression()->Property()->AsIdentifier()->Name()) == info->name; + } + return false; +} + +bool MatchFunctionDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsFunctionDeclaration()) { + return false; + } + return std::string(childNode->AsFunctionDeclaration()->Function()->Id()->Name()) == info->name; +} + +ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info) +{ + if (node == nullptr) { + return node; + } + + const auto &nodeExtractors = GetNodeExtractors(); + auto it = nodeExtractors.find(info->kind); + if (it != nodeExtractors.end()) { + return it->second(node, info); + } + return node; +} + +static std::unordered_map GetClassAndIdentifierExtractors() +{ + // clang-format off + return {{ir::AstNodeType::CLASS_DEFINITION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsClassDefinition() ? node->AsClassDefinition()->Ident() : node; + }}, + {ir::AstNodeType::IDENTIFIER, + [](ir::AstNode *node, const NodeInfo *) { return node->IsIdentifier() ? node->AsIdentifier() : node; }}, + {ir::AstNodeType::CLASS_PROPERTY, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsClassProperty() ? node->AsClassProperty()->Id() : node; + }}, + {ir::AstNodeType::PROPERTY, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsProperty() ? node->AsProperty()->Key()->AsIdentifier() : node; + }}, + {ir::AstNodeType::METHOD_DEFINITION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsMethodDefinition() ? node->AsMethodDefinition()->Function()->Id() : node; + }}, + {ir::AstNodeType::CLASS_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsClassDeclaration() ? node->AsClassDeclaration()->Definition()->Ident() : node; + }} + }; + // clang-format on +} + +static std::unordered_map GetEnumAndInterfaceExtractors() +{ + // clang-format off + return {{ir::AstNodeType::TS_ENUM_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSEnumDeclaration() ? node->AsTSEnumDeclaration()->Key() : node; + }}, + {ir::AstNodeType::TS_ENUM_MEMBER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSEnumMember() ? node->AsTSEnumMember()->Key() : node; + }}, + {ir::AstNodeType::TS_INTERFACE_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSInterfaceDeclaration() ? node->AsTSInterfaceDeclaration()->Id() : node; + }}, + {ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSTypeAliasDeclaration() ? node->AsTSTypeAliasDeclaration()->Id() : node; + }} + }; + // clang-format on +} + +static std::unordered_map GetExportExtractors() +{ + return {{ir::AstNodeType::EXPORT_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractExportSpecifierIdentifier(node, info); }}, + {ir::AstNodeType::REEXPORT_STATEMENT, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractExportSpecifierIdentifier(node, info); }}}; +} + +static std::unordered_map GetExpressionExtractors() +{ + return {{ir::AstNodeType::MEMBER_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsMemberExpression() ? node->AsMemberExpression()->Property()->AsIdentifier() : node; + }}, + {ir::AstNodeType::CALL_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractCallExpressionIdentifier(node, info); }}, + {ir::AstNodeType::SUPER_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractCallExpressionIdentifier(node, info); }}, + {ir::AstNodeType::AWAIT_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractAwaitExpressionIdentifier(node, info); }}}; +} + +static std::unordered_map GetTypeReferenceExtractors() +{ + // clang-format off + return {{ir::AstNodeType::TS_CLASS_IMPLEMENTS, + [](ir::AstNode *node, const NodeInfo *info) { + return ExtractTSClassImplementsIdentifier(node, info); + }}, + {ir::AstNodeType::ETS_STRING_LITERAL_TYPE, + [](ir::AstNode *node, const NodeInfo *info) { + return ExtractETSStringLiteralTypeIdentifier(node, info); + }}, + {ir::AstNodeType::ETS_KEYOF_TYPE, + [](ir::AstNode *node, const NodeInfo *info) { + return ExtractETSKeyofTypeIdentifier(node, info); + }}, + {ir::AstNodeType::TS_TYPE_REFERENCE, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsETSTypeReference() + ? node->AsETSTypeReference()->Part()->Name()->AsIdentifier() : node; + }} + }; + // clang-format on +} + +static std::unordered_map GetFunctionAndVariableExtractors() +{ + // clang-format off + return {{ir::AstNodeType::SCRIPT_FUNCTION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsScriptFunction() ? node->AsScriptFunction()->Id() : node; + }}, + {ir::AstNodeType::VARIABLE_DECLARATOR, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclarator() ? node->AsVariableDeclarator()->Id()->AsIdentifier() : node; + }}, + {ir::AstNodeType::VARIABLE_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclaration() + ? node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier() + : node; + }} + }; + // clang-format on +} + +static std::unordered_map GetAnnotationAndImportExtractors() +{ + // clang-format off + return { + {ir::AstNodeType::ANNOTATION_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationDeclaration() ? node->AsAnnotationDeclaration()->GetBaseName() : node; + }}, + {ir::AstNodeType::ANNOTATION_USAGE, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationUsage() ? node->AsAnnotationUsage()->GetBaseName() : node; + }}, + {ir::AstNodeType::BIGINT_LITERAL, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsBigIntLiteral() ? node->AsBigIntLiteral() : node; + }}, + {ir::AstNodeType::IMPORT_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportSpecifier() ? node->AsImportSpecifier()->Imported() : node; + }}, + {ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportDefaultSpecifier() ? node->AsImportDefaultSpecifier()->Local() : node; + }}, + {ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportNamespaceSpecifier() ? node->AsImportNamespaceSpecifier()->Local() : node; + }}, + {ir::AstNodeType::TS_TYPE_PARAMETER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSTypeParameter() ? node->AsTSTypeParameter()->Name() : node; + }} + }; + // clang-format on +} + +const std::unordered_map &GetNodeExtractors() +{ + static std::unordered_map nodeExtractors; + static bool initialized = false; + + if (!initialized) { + auto classExtractors = GetClassAndIdentifierExtractors(); + auto enumExtractors = GetEnumAndInterfaceExtractors(); + auto exportExtractors = GetExportExtractors(); + auto expressionExtractors = GetExpressionExtractors(); + auto typeRefExtractors = GetTypeReferenceExtractors(); + auto funcVarExtractors = GetFunctionAndVariableExtractors(); + auto annotationImportExtractors = GetAnnotationAndImportExtractors(); + + nodeExtractors.insert(classExtractors.begin(), classExtractors.end()); + nodeExtractors.insert(enumExtractors.begin(), enumExtractors.end()); + nodeExtractors.insert(exportExtractors.begin(), exportExtractors.end()); + nodeExtractors.insert(expressionExtractors.begin(), expressionExtractors.end()); + nodeExtractors.insert(typeRefExtractors.begin(), typeRefExtractors.end()); + nodeExtractors.insert(funcVarExtractors.begin(), funcVarExtractors.end()); + nodeExtractors.insert(annotationImportExtractors.begin(), annotationImportExtractors.end()); + + initialized = true; + } + + return nodeExtractors; +} + +const std::unordered_map &GetNodeMatchers() +{ + static const std::unordered_map NODE_MATCHERS = { + {ir::AstNodeType::CLASS_DEFINITION, MatchClassDefinition}, + {ir::AstNodeType::IDENTIFIER, MatchIdentifier}, + {ir::AstNodeType::CLASS_PROPERTY, MatchClassProperty}, + {ir::AstNodeType::PROPERTY, MatchProperty}, + {ir::AstNodeType::METHOD_DEFINITION, MatchMethodDefinition}, + {ir::AstNodeType::TS_ENUM_DECLARATION, MatchTSEnumDeclaration}, + {ir::AstNodeType::TS_ENUM_MEMBER, MatchTSEnumMember}, + {ir::AstNodeType::TS_INTERFACE_DECLARATION, MatchTSInterfaceDeclaration}, + {ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, MatchTSTypeAliasDeclaration}, + {ir::AstNodeType::EXPORT_SPECIFIER, MatchExportSpecifier}, + {ir::AstNodeType::MEMBER_EXPRESSION, MatchMemberExpression}, + {ir::AstNodeType::TS_CLASS_IMPLEMENTS, MatchTSClassImplements}, + {ir::AstNodeType::ETS_STRING_LITERAL_TYPE, MatchEtsStringLiteralType}, + {ir::AstNodeType::ETS_TYPE_REFERENCE, MatchEtsTypeReference}, + {ir::AstNodeType::ETS_KEYOF_TYPE, MatchEtsKeyofType}, + {ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION, MatchEtsNewClassInstanceExpression}, + {ir::AstNodeType::STRUCT_DECLARATION, MatchEtsStructDeclaration}, + {ir::AstNodeType::SPREAD_ELEMENT, MatchSpreadElement}, + {ir::AstNodeType::REEXPORT_STATEMENT, MatchExportSpecifier}, + {ir::AstNodeType::CALL_EXPRESSION, MatchCallExpression}, + {ir::AstNodeType::SUPER_EXPRESSION, MatchCallExpression}, + {ir::AstNodeType::TS_TYPE_REFERENCE, MatchTsTypeReference}, + {ir::AstNodeType::SCRIPT_FUNCTION, MatchScriptFunction}, + {ir::AstNodeType::VARIABLE_DECLARATOR, MatchVariableDeclarator}, + {ir::AstNodeType::VARIABLE_DECLARATION, MatchVariableDeclaration}, + {ir::AstNodeType::CLASS_DECLARATION, MatchClassDeclaration}, + {ir::AstNodeType::ANNOTATION_DECLARATION, MatchAnnotationDeclaration}, + {ir::AstNodeType::ANNOTATION_USAGE, MatchAnnotationUsage}, + {ir::AstNodeType::AWAIT_EXPRESSION, MatchAwaitExpression}, + {ir::AstNodeType::BIGINT_LITERAL, MatchBigIntLiteral}, + {ir::AstNodeType::IMPORT_SPECIFIER, MatchImportSpecifier}, + {ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER, MatchImportDefaultSpecifier}, + {ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER, MatchImportNamespaceSpecifier}, + {ir::AstNodeType::TS_TYPE_PARAMETER, MatchTSTypeParameter}, + {ir::AstNodeType::ETS_PARAMETER_EXPRESSION, MatchEtsParameterExpression}, + {ir::AstNodeType::SWITCH_STATEMENT, MatchSwitchStatement}, + {ir::AstNodeType::TS_NON_NULL_EXPRESSION, MatchTsNonNullExpression}, + {ir::AstNodeType::FUNCTION_DECLARATION, MatchFunctionDeclaration}}; + return NODE_MATCHERS; +} +} // 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..e0a74cee5cbd2a660225fd04b3fb4cc739088fbd --- /dev/null +++ b/ets2panda/lsp/src/organize_imports.cpp @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "compiler/lowering/util.h" +#include "internal_api.h" +#include "public/public.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; + + auto checkFunction = [&ctx, &spec, &found](ir::AstNode *node) { + if (spec.type == ImportType::NAMESPACE) { + if (node->IsTSQualifiedName()) { + auto *qname = node->AsTSQualifiedName(); + found = qname->Left()->IsIdentifier() && + (std::string(qname->Left()->AsIdentifier()->Name()) == spec.localName); + return found; + } + + 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 touchingToken = GetTouchingToken(ctx, spec.start, false); + if (touchingToken == nullptr || !touchingToken->IsIdentifier()) { + return false; + } + auto decl = compiler::DeclarationFromIdentifier(node->AsIdentifier()); + auto specDecl = compiler::DeclarationFromIdentifier(touchingToken->AsIdentifier()); + if (decl == nullptr || specDecl == nullptr) { + return false; + } + if (decl == specDecl) { + found = true; + return true; + } + + return false; + }; + + for (auto &statement : ast->Statements()) { + if (statement == nullptr || statement->IsETSImportDeclaration() || statement->IsETSReExportDeclaration()) { + continue; + } + statement->FindChild(checkFunction); + } + + 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(); + bool isDefault = false; + auto decl = compiler::DeclarationFromIdentifier(imported); + if (decl != nullptr) { + isDefault = decl->IsDefaultExported(); + } + specInfo.importedName = imported != nullptr ? std::string(imported->Name()) : std::string(local->Name()); + specInfo.type = isTypeOnly ? ImportType::TYPE_ONLY : isDefault ? ImportType::DEFAULT : 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) { + if (importNode == nullptr || !importNode->IsETSImportDeclaration()) { + continue; + } + auto *importDecl = importNode->AsETSImportDeclaration(); + if (importDecl->Source() == nullptr) { + continue; + } + if (importDecl->Start().index == importDecl->End().index) { + continue; // Skip empty import declarations + } + + 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::tuple HasDefaultSpecifier(const std::vector &namedImports) +{ + auto it = std::find_if(namedImports.begin(), namedImports.end(), + [](const ImportSpecifier &spec) { return spec.type == ImportType::DEFAULT; }); + return std::make_tuple(it != namedImports.end(), + it != namedImports.end() ? std::distance(namedImports.begin(), it) : -1); +} + +void ExtractDefaultImport(const ImportInfo &imp, std::ostringstream &osst, const std::string &prefix, + const std::tuple &hasDefault) +{ + auto [_, defaultIndex] = hasDefault; + osst << prefix; + osst << imp.namedImports[defaultIndex].localName; + if (imp.namedImports.size() > 1) { + osst << ", { "; + } + for (size_t i = 0; i < imp.namedImports.size(); ++i) { + if (i != defaultIndex) { + const auto &spec = imp.namedImports[i]; + if (spec.importedName != spec.localName) { + osst << spec.importedName << " as " << spec.localName; + } else { + osst << spec.localName; + } + if (i + 1 == defaultIndex && defaultIndex == imp.namedImports.size() - 1) { + continue; // Skip if the default import is the last one + } + if (i + 1 < imp.namedImports.size()) { + osst << ", "; + } + } + } + if (imp.namedImports.size() > 1) { + osst << " }"; + } + osst << " from \'" << imp.moduleName << "\';\n"; +} + +void 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 << ", "; + } + index++; + } + osst << " } from \'" << imp.moduleName << "\';\n"; +} + +std::vector GenerateTextChanges(const std::vector &imports) +{ + if (imports.empty()) { + return {}; + } + + std::ostringstream oss; + + for (const auto &imp : imports) { + if (imp.namedImports.empty()) { + continue; + } + + auto hasDefault = HasDefaultSpecifier(imp.namedImports); + if (std::get<0>(hasDefault) && imp.namedImports.size() > 1) { + ExtractDefaultImport(imp, oss, "import ", hasDefault); + 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; + } + } + + std::string result = oss.str(); + if (!result.empty() && result.back() == '\n') { + result.pop_back(); // Remove trailing newline to avoid adding newlines repeatedly. + } + + return { + TextChange(TextSpan(imports.front().startIndex, imports.back().endIndex - imports.front().startIndex), result)}; +} + +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..c7ac6bf677b265b616236d9bb38c3185474bf553 100644 --- a/ets2panda/lsp/src/quick_info.cpp +++ b/ets2panda/lsp/src/quick_info.cpp @@ -17,8 +17,11 @@ #include "internal_api.h" #include "ir/astNode.h" #include "public/public.h" +#include "ir/ets/etsTuple.h" #include "ir/ets/etsUnionType.h" #include "api.h" +#include "rename.h" +#include "isolated_declaration.h" #include "compiler/lowering/util.h" namespace ark::es2panda::lsp { @@ -190,24 +193,8 @@ ir::AstNode *GetNodeAtLocation(ir::AstNode *node) if (node->IsProgram()) { return node->Modifiers() == ir::ModifierFlags::EXPORT ? node : nullptr; } - auto parent = node->Parent(); - if (IsIdentifierOfDeclaration(node)) { - return parent; - } if (node->Type() == ir::AstNodeType::IDENTIFIER) { - if (IsDeclaration(parent) || IsDefinition(parent)) { - if (compiler::ClassDefinitionIsEnumTransformed(parent)) { - parent = parent->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration(); - } - return parent; - } - if (parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { - auto declNode = compiler::DeclarationFromIdentifier(parent->AsMemberExpression()->Object()->AsIdentifier()); - if (compiler::ClassDefinitionIsEnumTransformed(declNode)) { - declNode = declNode->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration(); - } - return declNode; - } + // could get decl instead of getting parant declaration and then child return compiler::DeclarationFromIdentifier(node->AsIdentifier()); } @@ -264,7 +251,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 +341,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; @@ -477,14 +383,38 @@ std::string GetNameForUnionType(const ir::TypeNode *unionType) for (size_t i = 0; i < types.size(); ++i) { newstr += GetNameForTypeNode(types[i]); if (i != types.size() - 1) { - newstr += "|"; + newstr += " | "; } } return newstr; } +std::string GetNameForTupleType(const ir::TypeNode *tupleType) +{ + const auto &types = tupleType->AsETSTuple()->GetTupleTypeAnnotationsList(); + std::string newstr = "["; + for (size_t i = 0; i < types.size(); ++i) { + newstr += GetNameForTypeNode(types[i]); + if (i != types.size() - 1) { + newstr += ", "; + } + } + newstr += "]"; + return newstr; +} + std::string GetNameForTypeReference(const ir::TypeNode *typeReference) { + auto type = typeReference->AsETSTypeReference()->Part(); + if (type != nullptr && type->IsETSTypeReferencePart()) { + auto tmp = type->AsETSTypeReferencePart()->Name(); + if (tmp != nullptr && tmp->IsTSQualifiedName()) { + auto leftStr = tmp->AsTSQualifiedName()->Left()->AsIdentifier()->Name().Mutf8(); + auto rightStr = tmp->AsTSQualifiedName()->Right()->AsIdentifier()->Name().Mutf8(); + return leftStr + "." + rightStr; + } + } + std::string typeParamNames; auto typeParam = typeReference->AsETSTypeReference()->Part()->TypeParams(); if (typeParam != nullptr && typeParam->IsTSTypeParameterInstantiation()) { @@ -512,6 +442,68 @@ std::string GetNameForFunctionType(const ir::TypeNode *functionType) return "((" + params + ") => " + returnType + ")"; } +std::string EscapeJsonString(const std::string &input) +{ + std::ostringstream oss; + oss << "\""; + for (char c : input) { + switch (c) { + case '\"': + oss << "\\\""; + break; + case '\\': + oss << "\\\\"; + break; + case '\n': + oss << "\\n"; + break; + case '\r': + oss << "\\r"; + break; + case '\t': + oss << "\\t"; + break; + default: + oss << c; + break; + } + } + oss << "\""; + return oss.str(); +} + +std::string GetNameForLiteralTypeNode(const ir::AstNode *node, bool iskindModifier = false) +{ + if (node == nullptr) { + return "undefined"; + } + if (node->IsStringLiteral()) { + return iskindModifier ? EscapeJsonString(std::string(node->AsStringLiteral()->Str())) : "String"; + } + if (node->IsNumberLiteral()) { + return iskindModifier ? std::string(node->AsNumberLiteral()->Str()) : "Number"; + } + if (node->IsBooleanLiteral()) { + return iskindModifier ? node->AsBooleanLiteral()->Value() ? "true" : "false" : "Boolean"; + } + if (node->IsBigIntLiteral()) { + return "Bigint"; + } + if (node->IsIdentifier()) { + auto name = node->AsIdentifier()->Name(); + if (name.Is("NaN")) { + return "Number"; + } + } + if (node->IsNullLiteral()) { + return "null"; + } + if (node->IsETSStringLiteralType()) { + return "String"; + } + return "undefined"; +} + std::string GetNameForTypeNode(const ir::TypeNode *typeAnnotation) { if (typeAnnotation->IsETSUnionType()) { @@ -520,27 +512,25 @@ std::string GetNameForTypeNode(const ir::TypeNode *typeAnnotation) if (typeAnnotation->IsETSPrimitiveType()) { return PrimitiveTypeToName(typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType()); } - if (typeAnnotation->IsETSTypeReference()) { return GetNameForTypeReference(typeAnnotation); } - if (typeAnnotation->IsETSFunctionType()) { return GetNameForFunctionType(typeAnnotation); } - if (typeAnnotation->IsTSArrayType()) { return GetNameForTypeNode(typeAnnotation->AsTSArrayType()->ElementType()) + "[]"; } - if (typeAnnotation->IsETSNullType()) { return "null"; } - if (typeAnnotation->IsETSUndefinedType()) { return "undefined"; } - return "undefined"; + if (typeAnnotation->IsETSTuple()) { + return GetNameForTupleType(typeAnnotation); + } + return GetNameForLiteralTypeNode(typeAnnotation); } std::string GetNameForETSUnionType(const ir::TypeNode *typeAnnotation) @@ -552,7 +542,7 @@ std::string GetNameForETSUnionType(const ir::TypeNode *typeAnnotation) std::string str = GetNameForTypeNode(type); newstr += str; if (i != typeAnnotation->AsETSUnionType()->Types().size() - 1) { - newstr += "|"; + newstr += " | "; } } return newstr; @@ -645,9 +635,23 @@ std::vector CreateDisplayForClass(ir::AstNode *node) displayParts.emplace_back(CreateClassName(GetNameFromClassDeclaration(node))); } else { // class definition - displayParts.emplace_back(CreateKeyword("class")); - displayParts.emplace_back(CreateSpace()); - displayParts.emplace_back(CreateClassName(GetNameFromClassDefinition(node))); + if (node->AsClassDefinition()->OrigEnumDecl() != nullptr) { + displayParts.emplace_back(CreateKeyword("enum")); + displayParts.emplace_back(CreateSpace()); + displayParts.emplace_back(CreateEnumName(GetNameFromClassDefinition(node))); + } else if (node->AsClassDefinition()->IsNamespaceTransformed()) { + displayParts.emplace_back(CreateKeyword("namespace")); + displayParts.emplace_back(CreateSpace()); + displayParts.emplace_back(CreateNamespace(GetNameFromClassDefinition(node))); + } else if (node->AsClassDefinition()->IsFromStruct() || node->Parent()->IsETSStructDeclaration()) { + displayParts.emplace_back(CreateKeyword("struct")); + displayParts.emplace_back(CreateSpace()); + displayParts.emplace_back(SignatureCreateStructName(GetNameFromClassDefinition(node))); + } else { + displayParts.emplace_back(CreateKeyword("class")); + displayParts.emplace_back(CreateSpace()); + displayParts.emplace_back(CreateClassName(GetNameFromClassDefinition(node))); + } } return displayParts; } @@ -757,11 +761,30 @@ std::vector CreateDisplayOfReturnType(ark::es2panda::ir::Type std::vector displayParts; displayParts.emplace_back(CreatePunctuation(":")); displayParts.emplace_back(CreateSpace()); + if (returnType == nullptr) { + displayParts.emplace_back(CreateReturnType("void")); + return displayParts; + } if (returnType->Type() == ir::AstNodeType::ETS_TYPE_REFERENCE) { auto part = returnType->AsETSTypeReference()->Part()->AsETSTypeReferencePart(); auto typeName = part->Name()->AsIdentifier()->Name(); displayParts.emplace_back(CreateReturnType(std::string(typeName))); } + if (returnType->Type() == ir::AstNodeType::ETS_UNION_TYPE) { + auto unionType = returnType->AsETSUnionType(); + auto types = unionType->Types(); + for (size_t i = 0; i < types.size(); ++i) { + auto typeName = GetNameForTypeNode(types[i]); + displayParts.emplace_back(CreateReturnType(typeName)); + if (i != types.size() - 1) { + displayParts.emplace_back(CreatePunctuation("|")); + displayParts.emplace_back(CreateSpace()); + } + } + } + if (returnType->Type() == ir::AstNodeType::TS_THIS_TYPE) { + displayParts.emplace_back(CreateReturnType("this")); + } return displayParts; } @@ -870,7 +893,7 @@ std::vector CreateDisplayForEnumMember(ir::AstNode *node) displayParts.emplace_back(CreateSpace()); auto init = node->AsTSEnumMember()->Init(); if (init->Type() == ir::AstNodeType::NUMBER_LITERAL) { - displayParts.emplace_back(CreateText(std::string(init->AsNumberLiteral()->Str()))); + displayParts.emplace_back(CreateText(std::to_string(init->AsNumberLiteral()->Number().GetInt()))); } if (init->Type() == ir::AstNodeType::STRING_LITERAL) { displayParts.emplace_back(CreatePunctuation("\"")); @@ -1007,7 +1030,73 @@ std::vector CreateDisplayForMethodDefinitionOfInterfaceBody(i return displayParts; } -std::vector CreateDisplayForMethodDefinition(ir::AstNode *node, const std::string &kindModifier) +void AppendClassOrGlobalPrefix(std::vector &parts, ir::AstNode *parent) +{ + if (!parent->IsClassDefinition()) { + return; + } + + auto className = parent->AsClassDefinition()->Ident()->Name(); + if (className != "ETSGLOBAL") { + parts.emplace_back(CreateClassName(std::string(className))); + parts.emplace_back(CreatePunctuation(".")); + } else { + parts.emplace_back(CreateKeyword("function")); + parts.emplace_back(CreateSpace()); + } +} + +void AppendFunctionName(std::vector &parts, ir::MethodDefinition *method) +{ + auto name = method->Key()->AsIdentifier()->Name(); + parts.emplace_back(CreateFunctionName(std::string(name))); +} + +static void AppendSignature(std::vector &parts, ir::MethodDefinition *method, + checker::ETSChecker *checker) +{ + auto *funcExpr = method->Value(); + if (funcExpr == nullptr) { + return; + } + auto *script = funcExpr->AsFunctionExpression()->Function(); + if (script == nullptr || script->Type() != ir::AstNodeType::SCRIPT_FUNCTION) { + return; + } + // + if (auto *typeParams = script->TypeParams()) { + auto display = CreateDisplayOfTypeParams(typeParams->AsTSTypeParameterDeclaration()->Params()); + parts = MergeSymbolDisplayPart(parts, display); + } + // (a: number, b: string) + auto paramDisplay = CreateDisplayOfFunctionParams(script); + parts = MergeSymbolDisplayPart(parts, paramDisplay); + // return type + auto returnType = script->ReturnTypeAnnotation(); + if (returnType == nullptr) { + auto signature = GetFuncSignature(method->TsType()->AsETSFunctionType(), method); + auto typeStr = GetReturnTypeStr(signature->ReturnType(), checker); + parts.emplace_back(CreatePunctuation(":")); + parts.emplace_back(CreateSpace()); + parts.emplace_back(CreateReturnType(typeStr)); + } else { + auto retDisplay = CreateDisplayOfReturnType(script->ReturnTypeAnnotation()); + parts = MergeSymbolDisplayPart(parts, retDisplay); + } +} + +static std::vector CreateDisplayForRegularOrClassMethod(ir::AstNode *node, + checker::ETSChecker *checker) +{ + std::vector parts; + AppendClassOrGlobalPrefix(parts, node->Parent()); + AppendFunctionName(parts, node->AsMethodDefinition()); + AppendSignature(parts, node->AsMethodDefinition(), checker); + return parts; +} + +std::vector CreateDisplayForMethodDefinition(ir::AstNode *node, const std::string &kindModifier, + checker::ETSChecker *checker) { std::vector displayParts; if (node->Type() != ir::AstNodeType::METHOD_DEFINITION) { @@ -1024,38 +1113,10 @@ std::vector CreateDisplayForMethodDefinition(ir::AstNode *nod return CreateDisplayForMethodDefinitionOfInterfaceBody(node); } - displayParts.emplace_back(CreateKeyword("function")); - displayParts.emplace_back(CreateSpace()); - auto functionName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name(); - displayParts.emplace_back(CreateFunctionName(std::string(functionName))); - - if (node->AsMethodDefinition()->Value() == nullptr) { - return displayParts; - } - auto scriptFunction = node->AsMethodDefinition()->Value()->AsFunctionExpression()->Function(); - if (scriptFunction == nullptr) { - return displayParts; - } - if (scriptFunction->Type() == ir::AstNodeType::SCRIPT_FUNCTION) { - auto script = scriptFunction->AsScriptFunction(); - auto typeParameter = script->TypeParams(); - if (typeParameter != nullptr) { - auto params = typeParameter->AsTSTypeParameterDeclaration()->Params(); - auto displayOfTypeParams = CreateDisplayOfTypeParams(params); - displayParts = MergeSymbolDisplayPart(displayParts, displayOfTypeParams); - } - - auto displayOfFunctionParam = CreateDisplayOfFunctionParams(script); - displayParts = MergeSymbolDisplayPart(displayParts, displayOfFunctionParam); - - auto returnType = script->ReturnTypeAnnotation(); - auto displayOfReturnType = CreateDisplayOfReturnType(returnType); - displayParts = MergeSymbolDisplayPart(displayParts, displayOfReturnType); - } - return displayParts; + return CreateDisplayForRegularOrClassMethod(node, checker); } -std::vector CreateDisplayForClassProperty(ir::AstNode *node, const std::string &kindModifier) +std::vector CreateDisplayForClassProperty(ir::AstNode *node) { std::vector displayParts; if (node->Type() != ir::AstNodeType::CLASS_PROPERTY) { @@ -1064,10 +1125,11 @@ std::vector CreateDisplayForClassProperty(ir::AstNode *node, auto classDef = node->Parent(); if (classDef->Type() == ir::AstNodeType::CLASS_DEFINITION) { auto className = classDef->AsClassDefinition()->Ident()->Name(); + auto isConst = (node->Modifiers() & ir::ModifierFlags::CONST) != 0; if (className != "ETSGLOBAL") { displayParts.emplace_back(CreateClassName(std::string(className))); displayParts.emplace_back(CreatePunctuation(".")); - } else if (kindModifier == "const") { + } else if (isConst) { displayParts.emplace_back(CreateKeyword("const")); displayParts.emplace_back(CreateSpace()); } else { @@ -1082,6 +1144,12 @@ std::vector CreateDisplayForClassProperty(ir::AstNode *node, auto typeAnnotation = node->AsClassProperty()->TypeAnnotation(); std::string type; if (typeAnnotation == nullptr) { + if (node->AsClassProperty()->Value() == nullptr || + !node->AsClassProperty()->Value()->IsETSNewClassInstanceExpression()) { + displayParts.emplace_back( + CreateTypeName(GetNameForLiteralTypeNode(node->AsClassProperty()->Value(), isConst))); + return displayParts; + } auto newClassExpr = node->AsClassProperty()->Value()->AsETSNewClassInstanceExpression(); if (newClassExpr != nullptr) { type = std::string(newClassExpr->GetTypeRef()->AsETSTypeReference()->Part()->GetIdent()->Name()); @@ -1142,14 +1210,13 @@ std::vector CreateDisplayForImportDeclaration(ir::AstNode *no } QuickInfo GetQuickInfo(ir::AstNode *node, ir::AstNode *containerNode, ir::AstNode *nodeForQuickInfo, - const std::string &fileName) + const std::string &fileName, checker::ETSChecker *checker) { if (containerNode == nullptr || nodeForQuickInfo == nullptr || node == nullptr) { return QuickInfo(); } auto kindModifiers = GetKindModifiers(node); TextSpan span(nodeForQuickInfo->Start().index, nodeForQuickInfo->End().index - nodeForQuickInfo->Start().index); - auto nodeKind = GetNodeKind(node); std::vector displayParts; std::string kind; @@ -1158,7 +1225,6 @@ QuickInfo GetQuickInfo(ir::AstNode *node, ir::AstNode *containerNode, ir::AstNod if (IsClass(node)) { displayParts = CreateDisplayForClass(node); - kind = "class"; } else if (node->Type() == ir::AstNodeType::ETS_PARAMETER_EXPRESSION) { displayParts = CreateDisplayForETSParameterExpression(node); } else if (node->Type() == ir::AstNodeType::CLASS_PROPERTY) { @@ -1168,12 +1234,12 @@ QuickInfo GetQuickInfo(ir::AstNode *node, ir::AstNode *containerNode, ir::AstNod auto enumMember = GetEnumMemberByName(enumDecl, node->AsClassProperty()->Key()->AsIdentifier()->Name()); displayParts = CreateDisplayForEnumMember(enumMember); } else { - displayParts = CreateDisplayForClassProperty(node, kindModifiers); - kind = "property"; + displayParts = CreateDisplayForClassProperty(node); } + } else if (node->Type() == ir::AstNodeType::TS_ENUM_MEMBER) { + displayParts = CreateDisplayForEnumMember(node); } else if (node->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) { displayParts = CreateDisplayForInterface(node); - kind = "interface"; } else if (node->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) { displayParts = CreateDisplayForTypeAlias(node); } else if (node->Type() == ir::AstNodeType::TS_ENUM_DECLARATION) { @@ -1183,12 +1249,10 @@ QuickInfo GetQuickInfo(ir::AstNode *node, ir::AstNode *containerNode, ir::AstNod } else if (node->Type() == ir::AstNodeType::TS_TYPE_PARAMETER) { displayParts = CreateDisplayForTypeParameter(node); } else if (node->Type() == ir::AstNodeType::METHOD_DEFINITION) { - displayParts = CreateDisplayForMethodDefinition(node, kindModifiers); - kind = "function"; - if (node->Parent() != nullptr && node->Parent()->Type() == ir::AstNodeType::TS_INTERFACE_BODY) { - kind = "property"; - } + displayParts = CreateDisplayForMethodDefinition(node, kindModifiers, checker); } + // Unify this kind + kind = GetNodeKindForRenameInfo(node); return QuickInfo(kind, kindModifiers, span, displayParts, document, tags, fileName); } @@ -1201,6 +1265,9 @@ QuickInfo GetQuickInfoAtPositionImpl(es2panda_Context *context, size_t position, if (touchingToken == nullptr || touchingToken->IsProgram()) { return QuickInfo(); } + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + // The nodeForQuickInfo will be identifier in all of currently known scenarios auto nodeForQuickInfo = GetTokenForQuickInfo(context, position); auto node = GetNodeAtLocationForQuickInfo(nodeForQuickInfo); auto object = GetContainingObjectLiteralNode(nodeForQuickInfo); @@ -1215,7 +1282,7 @@ QuickInfo GetQuickInfoAtPositionImpl(es2panda_Context *context, size_t position, return QuickInfo(); } - return GetQuickInfo(node, GetContainerNode(nodeForQuickInfo), nodeForQuickInfo, nodeFileName); + return GetQuickInfo(node, GetContainerNode(nodeForQuickInfo), nodeForQuickInfo, nodeFileName, checker); } } // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/refactor_provider.cpp b/ets2panda/lsp/src/refactor_provider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6e8e598ff5a354a28f1632e82d77a8e40b16ba2 --- /dev/null +++ b/ets2panda/lsp/src/refactor_provider.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 "refactor_provider.h" +#include "refactors/refactor_types.h" + +namespace ark::es2panda::lsp { + +void RefactorProvider::RegisterRefactor(const std::string &name, std::unique_ptr refactor) +{ + refactors_.emplace(name, std::move(refactor)); +} + +RefactorProvider &RefactorProvider::Instance() +{ + static RefactorProvider instance; + return instance; +} + +std::unique_ptr RefactorProvider::GetEditsForRefactor(const RefactorContext &context, + const std::string &refactorName, + const std::string &actionName) const +{ + auto it = refactors_.find(refactorName); + if (it == refactors_.end()) { + return nullptr; + } + + return it->second->GetEditsForAction(context, actionName); +} + +std::vector RefactorProvider::GetApplicableRefactors(const RefactorContext &context) const +{ + std::vector applicable; + + for (const auto &[name, refactor] : refactors_) { + auto result = refactor->GetAvailableActions(context); + if (!result.name.empty()) { + applicable.push_back(result); + } + } + + return applicable; +} + +const std::unordered_map> &RefactorProvider::GetRefactors() const +{ + return refactors_; +} + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/refactors/convert_chain.cpp b/ets2panda/lsp/src/refactors/convert_chain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6923a02fe90816753f533564055b1bdbe267d59e --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_chain.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 "refactors/convert_chain.h" +#include "refactor_provider.h" +#include "internal_api.h" +#include "public/public.h" + +namespace ark::es2panda::lsp { +ConvertChainRefactor::ConvertChainRefactor() +{ + AddKind(std::string(TO_NAMED_CHAIN_ACTION.kind)); +} + +ark::es2panda::ir::AstNode *FindETSNullType(ark::es2panda::ir::AstNode *node, es2panda_Context *context) +{ + auto consequent = node->AsConditionalExpression()->Consequent(); + auto nodeproperty = consequent->AsMemberExpression()->Property(); + auto ctx = reinterpret_cast(context); + auto targetNode = ctx->parserProgram->Ast()->FindChild([&nodeproperty](ir::AstNode *childNode) { + return childNode->IsScriptFunction() && + childNode->AsScriptFunction()->Id()->AsIdentifier()->Name() == nodeproperty->AsIdentifier()->Name(); + }); + auto etc = targetNode->FindChild([](ir::AstNode *childNode) { return childNode->IsETSNullType(); }); + + return etc; +} + +ApplicableRefactorInfo ConvertChainRefactor::GetAvailableActions(const RefactorContext &refContext) const +{ + es2panda_Context *context = refContext.context; + size_t position = refContext.span.pos; + + ApplicableRefactorInfo res; + + if (!IsKind(refContext.kind)) { + return res; + } + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return res; + } + + auto parent = node->Parent(); + if (parent == nullptr) { + return res; + } + if (parent->IsExpression()) { + if (parent->IsConditionalExpression()) { + auto etc = FindETSNullType(parent, context); + if (etc != nullptr) { + return res; + } + } + res.name = refactor_name::CONVERT_CHAIN_REFACTOR_NAME; + res.description = refactor_description::CONVERT_CHAIN_REFACTOR_DESC; + res.action.kind = std::string(TO_NAMED_CHAIN_ACTION.kind); + res.action.name = std::string(TO_NAMED_CHAIN_ACTION.name); + res.action.description = std::string(TO_NAMED_CHAIN_ACTION.description); + } + return res; +} + +std::unique_ptr ConvertChainRefactor::GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const +{ + (void)context; + (void)actionName; + return std::make_unique(); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoRefactorRegister g_convertChainRefactorRegister("ConvertChainRefactor"); + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/refactors/convert_export.cpp b/ets2panda/lsp/src/refactors/convert_export.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c76a5760961589b98b34a6edf3b8e4727bbe5ce --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_export.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 "refactors/convert_export.h" +#include "refactor_provider.h" +#include "internal_api.h" + +namespace ark::es2panda::lsp { + +ConvertExportRefactor::ConvertExportRefactor() +{ + AddKind(std::string(TO_NAMED_EXPORT_ACTION.kind)); + AddKind(std::string(TO_DEFAULT_EXPORT_ACTION.kind)); +} + +ApplicableRefactorInfo ConvertExportRefactor::GetAvailableActions(const RefactorContext &refContext) const +{ + es2panda_Context *context = refContext.context; + size_t position = refContext.span.pos; + + ApplicableRefactorInfo res; + + if (!IsKind(refContext.kind)) { + return res; + } + + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return res; + } + auto cb = [](ir::AstNode *ancestorNode) { return ancestorNode->IsDefaultExported() || ancestorNode->IsExported(); }; + auto ancestor = FindAncestor(node, cb); + if (ancestor == nullptr) { + return res; + } + if (ancestor->IsDefaultExported()) { + res.name = refactor_name::CONVERT_EXPORT_REFACTOR_NAME; + res.description = std::string(TO_NAMED_EXPORT_ACTION.description); + res.action.kind = std::string(TO_NAMED_EXPORT_ACTION.kind); + res.action.name = std::string(TO_NAMED_EXPORT_ACTION.name); + res.action.description = std::string(TO_NAMED_EXPORT_ACTION.description); + } else if (ancestor->IsExported()) { + res.name = refactor_name::CONVERT_EXPORT_REFACTOR_NAME; + res.description = std::string(TO_DEFAULT_EXPORT_ACTION.description); + res.action.kind = std::string(TO_DEFAULT_EXPORT_ACTION.kind); + res.action.name = std::string(TO_DEFAULT_EXPORT_ACTION.name); + res.action.description = std::string(TO_DEFAULT_EXPORT_ACTION.description); + } + + return res; +} + +std::unique_ptr ConvertExportRefactor::GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const +{ + (void)context; + (void)actionName; + return std::make_unique(); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoRefactorRegister g_convertExportRefactorRegister("ConvertExportRefactor"); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/refactors/convert_function.cpp b/ets2panda/lsp/src/refactors/convert_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..097fe6fe6592ba119ee5f0d62bcf054604516b89 --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_function.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 +#include "refactors/convert_function.h" +#include "refactor_provider.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)); +} + +bool HasArrowFunction(ark::es2panda::ir::AstNode *node) +{ + if (!node->IsCallExpression() && !node->IsClassProperty() && !node->IsVariableDeclarator()) { + return false; + } + if ((node->IsClassProperty() && node->AsClassProperty()->Value() != nullptr && + node->AsClassProperty()->Value()->IsArrowFunctionExpression()) || + (node->IsVariableDeclarator() && node->AsVariableDeclarator()->Init() != nullptr && + node->AsVariableDeclarator()->Init()->IsArrowFunctionExpression())) { + return true; + } + if (node->IsCallExpression()) { + auto arguments = node->AsCallExpression()->Arguments(); + for (auto argument : arguments) { + if (argument->IsArrowFunctionExpression()) { + return true; + } + } + } + return false; +} + +ApplicableRefactorInfo ConvertFunctionRefactor::GetAvailableActions(const RefactorContext &refContext) const +{ + es2panda_Context *context = refContext.context; + size_t position = refContext.span.pos; + + ApplicableRefactorInfo res; + + if (!IsKind(refContext.kind)) { + return res; + } + + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return res; + } + auto cb = [](ir::AstNode *ancestorNode) { return HasArrowFunction(ancestorNode); }; + auto ancestor = FindAncestor(node, cb); + if (ancestor != nullptr && ancestor->IsClassProperty()) { + 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; +} + +std::unique_ptr ConvertFunctionRefactor::GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const +{ + (void)context; + (void)actionName; + return std::make_unique(); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoRefactorRegister g_convertFunctionRefactorRegister("ConvertFunctionRefactor"); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/refactors/convert_import.cpp b/ets2panda/lsp/src/refactors/convert_import.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fbe48a59f99a326a634918e055bca11775e71f7e --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_import.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 "refactors/convert_import.h" +#include "refactor_provider.h" +#include "internal_api.h" + +namespace ark::es2panda::lsp { + +ConvertImportRefactor::ConvertImportRefactor() +{ + AddKind(std::string(TO_NAMED_IMPORT_ACTION.kind)); + AddKind(std::string(TO_NAMESPACE_IMPORT_ACTION.kind)); + AddKind(std::string(TO_DEFAULT_IMPORT_ACTION.kind)); +} + +ApplicableRefactorInfo ConvertImportRefactor::GetAvailableActions(const RefactorContext &refContext) const +{ + es2panda_Context *context = refContext.context; + size_t position = refContext.span.pos; + + ApplicableRefactorInfo res; + + if (!IsKind(refContext.kind)) { + return res; + } + + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return res; + } + auto cb = [](ir::AstNode *ancestorNode) { + return ancestorNode->IsETSImportDeclaration() || ancestorNode->IsImportNamespaceSpecifier() || + ancestorNode->IsImportSpecifier(); + }; + auto ancestor = FindAncestor(node, cb); + if (ancestor != nullptr && ancestor->IsETSImportDeclaration()) { + auto specifiers = ancestor->AsETSImportDeclaration()->Specifiers(); + if (!specifiers.empty()) { + ancestor = specifiers[0]; + } + } + if (ancestor == nullptr) { + return res; + } + if (ancestor->IsImportNamespaceSpecifier()) { + res.name = refactor_name::CONVERT_IMPORT_REFACTOR_NAME; + res.description = std::string(TO_NAMED_IMPORT_ACTION.description); + res.action.kind = std::string(TO_NAMED_IMPORT_ACTION.kind); + res.action.name = std::string(TO_NAMED_IMPORT_ACTION.name); + res.action.description = std::string(TO_NAMED_IMPORT_ACTION.description); + } else if (ancestor->IsImportSpecifier()) { + res.name = refactor_name::CONVERT_IMPORT_REFACTOR_NAME; + res.description = std::string(TO_NAMESPACE_IMPORT_ACTION.description); + res.action.kind = std::string(TO_NAMESPACE_IMPORT_ACTION.kind); + res.action.name = std::string(TO_NAMESPACE_IMPORT_ACTION.name); + res.action.description = std::string(TO_NAMESPACE_IMPORT_ACTION.description); + } + + return res; +} + +std::unique_ptr ConvertImportRefactor::GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const +{ + (void)context; + (void)actionName; + return std::make_unique(); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoRefactorRegister g_convertImportRefactorRegister("ConvertImportRefactor"); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/refactors/convert_template.cpp b/ets2panda/lsp/src/refactors/convert_template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed3e76f0e739ae3054f1271fb759d3ae51f5dd58 --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_template.cpp @@ -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. + */ + +#include +#include "refactors/convert_template.h" +#include "refactor_provider.h" +#include "internal_api.h" + +namespace ark::es2panda::lsp { + +ConvertTemplateRefactor::ConvertTemplateRefactor() +{ + AddKind(std::string(TO_NAMED_TEMPLATE_ACTION.kind)); +} + +ApplicableRefactorInfo ConvertTemplateRefactor::GetAvailableActions(const RefactorContext &refContext) const +{ + es2panda_Context *context = refContext.context; + size_t position = refContext.span.pos; + + ApplicableRefactorInfo res; + + if (!IsKind(refContext.kind)) { + return res; + } + auto node = GetTouchingToken(context, position, false); + if (node == nullptr) { + return res; + } + + if (node != nullptr && node->Parent() != nullptr && + (node->Parent()->IsExpression() && node->Parent()->IsBinaryExpression())) { + res.name = refactor_name::CONVERT_TEMPLATE_REFACTOR_NAME; + res.description = refactor_description::CONVERT_TEMPLATE_REFACTOR_DESC; + res.action.kind = std::string(TO_NAMED_TEMPLATE_ACTION.kind); + res.action.name = std::string(TO_NAMED_TEMPLATE_ACTION.name); + res.action.description = std::string(TO_NAMED_TEMPLATE_ACTION.description); + } + + return res; +} + +std::unique_ptr ConvertTemplateRefactor::GetEditsForAction(const RefactorContext &context, + const std::string &actionName) const +{ + (void)context; + (void)actionName; + return std::make_unique(); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoRefactorRegister g_convertTemplateRefactorRegister("ConvertTemplateRefactor"); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/refactors/refactor_types.cpp b/ets2panda/lsp/src/refactors/refactor_types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a9c1a1980ea54739c968e77aa90539f0c460961 --- /dev/null +++ b/ets2panda/lsp/src/refactors/refactor_types.cpp @@ -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. + */ + +#include "refactors/refactor_types.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) const +{ + 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); +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/references.cpp b/ets2panda/lsp/src/references.cpp index cf4b87a9f13c317468d5f0e7cc5c1cc8a9bfd744..2370edb0e3cea65ad694452ad4b0c795fd148482 100644 --- a/ets2panda/lsp/src/references.cpp +++ b/ets2panda/lsp/src/references.cpp @@ -41,6 +41,10 @@ DeclInfoType GetDeclInfoImpl(ir::AstNode *astNode) auto declNode = compiler::DeclarationFromIdentifier(astNode->AsIdentifier()); auto node = declNode; while (node != nullptr) { + if (node->Range().start.Program() != nullptr) { + auto name = std::string(node->Range().start.Program()->SourceFilePath()); + return std::make_tuple(name, declNode->DumpEtsSrc()); + } if (node->IsETSModule()) { auto name = std::string(node->AsETSModule()->Program()->SourceFilePath()); return std::make_tuple(name, declNode->DumpEtsSrc()); diff --git a/ets2panda/lsp/src/register_code_fix/add_local_variable.cpp b/ets2panda/lsp/src/register_code_fix/add_local_variable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..22cfec61702d450f8f3b57e7e2d924f18d7c5375 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/add_local_variable.cpp @@ -0,0 +1,430 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_local_variable.h" + +#include +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" +#include "ir/astNode.h" +#include "ir/base/classDefinition.h" +#include "ir/expressions/identifier.h" +#include "ir/statements/functionDeclaration.h" +#include "ir/base/methodDefinition.h" + +namespace ark::es2panda::lsp { +using codefixes::ADD_LOCAL_VARIABLE; +using codefixes::ADD_LOCAL_VARIABLE_FOR_CLASS; + +namespace { +constexpr const char *OBJECT_TYPE = "Object"; +constexpr const char *DOUBLE_TYPE = "Double"; +constexpr const char *STRING_TYPE = "String"; +constexpr const char *BOOLEAN_TYPE = "Boolean"; +constexpr const char *BIGINT_TYPE = "BigInt"; +constexpr const char *CHAR_TYPE = "Char"; +constexpr const char *ARRAY_SUFFIX = "[]"; +constexpr const char *LET_KEYWORD = "let "; +constexpr const char *TYPE_SEPARATOR = ": "; +constexpr const char *STATEMENT_TERMINATOR = ";"; +constexpr const char *INDENT = " "; +constexpr const char *CLASS_FIELD_DESCRIPTION = "Add class field declaration"; +constexpr const char *CLASS_FIELD_FIX_ALL_DESCRIPTION = "Add all missing class fields"; +constexpr const char *LOCAL_VARIABLE_DESCRIPTION = "Add local variable declaration"; +constexpr const char *LOCAL_VARIABLE_FIX_ALL_DESCRIPTION = "Add all missing variable declarations"; +} // namespace + +std::string AddLocalVariable::GetTypeFromDirectAssignment(ir::AstNode *unresolvedNode, ir::AstNode *parent) +{ + if (!parent->IsAssignmentExpression()) { + return ""; + } + + auto *assignment = parent->AsAssignmentExpression(); + if (assignment->Left() != unresolvedNode) { + return ""; + } + + auto *rightSide = assignment->Right(); + if (rightSide == nullptr) { + return ""; + } + + return InferTypeFromExpression(rightSide); +} + +std::string AddLocalVariable::GetTypeFromMemberAssignment(ir::AstNode *unresolvedNode, ir::AstNode *parent) +{ + if (!parent->IsMemberExpression()) { + return ""; + } + + auto *memberExpr = parent->AsMemberExpression(); + if (memberExpr->Property() != unresolvedNode) { + return ""; + } + + auto *memberParent = memberExpr->Parent(); + if (memberParent == nullptr || !memberParent->IsAssignmentExpression()) { + return ""; + } + + auto *assignment = memberParent->AsAssignmentExpression(); + if (assignment->Left() != memberExpr) { + return ""; + } + + auto *rightSide = assignment->Right(); + if (rightSide == nullptr) { + return ""; + } + + return InferTypeFromExpression(rightSide); +} + +std::string AddLocalVariable::DetermineVariableType(ir::AstNode *unresolvedNode) +{ + if (unresolvedNode == nullptr) { + return OBJECT_TYPE; + } + + auto *parent = unresolvedNode->Parent(); + if (parent == nullptr) { + return OBJECT_TYPE; + } + + std::string directType = GetTypeFromDirectAssignment(unresolvedNode, parent); + if (!directType.empty()) { + return directType; + } + + std::string memberType = GetTypeFromMemberAssignment(unresolvedNode, parent); + if (!memberType.empty()) { + return memberType; + } + + return OBJECT_TYPE; +} + +std::string AddLocalVariable::InferTypeFromLiteral(ir::AstNode *expression) +{ + if (expression->IsNumberLiteral()) { + return DOUBLE_TYPE; + } + + if (expression->IsStringLiteral()) { + return STRING_TYPE; + } + + if (expression->IsBooleanLiteral()) { + return BOOLEAN_TYPE; + } + + if (expression->IsBigIntLiteral()) { + return BIGINT_TYPE; + } + + if (expression->IsCharLiteral()) { + return CHAR_TYPE; + } + + if (expression->IsNullLiteral()) { + return OBJECT_TYPE; + } + + if (expression->IsUndefinedLiteral()) { + return OBJECT_TYPE; + } + + return ""; +} + +std::string AddLocalVariable::InferTypeFromBinaryExpression(ir::AstNode *expression) +{ + auto *binary = expression->AsBinaryExpression(); + auto leftType = InferTypeFromExpression(binary->Left()); + auto rightType = InferTypeFromExpression(binary->Right()); + if (leftType == BIGINT_TYPE || rightType == BIGINT_TYPE) { + return BIGINT_TYPE; + } + if (leftType == DOUBLE_TYPE || rightType == DOUBLE_TYPE) { + return DOUBLE_TYPE; + } + if (leftType == STRING_TYPE || rightType == STRING_TYPE) { + return STRING_TYPE; + } + if (leftType == BOOLEAN_TYPE && rightType == BOOLEAN_TYPE) { + return BOOLEAN_TYPE; + } + if (leftType == CHAR_TYPE || rightType == CHAR_TYPE) { + return CHAR_TYPE; + } + + return OBJECT_TYPE; +} + +std::string AddLocalVariable::InferTypeFromOtherExpressions(ir::AstNode *expression) +{ + if (expression->IsArrayExpression()) { + auto *arrayExpr = expression->AsArrayExpression(); + auto elements = arrayExpr->Elements(); + if (!elements.empty()) { + auto elementType = InferTypeFromExpression(elements[0]); + return elementType + std::string(ARRAY_SUFFIX); + } + return std::string(OBJECT_TYPE) + ARRAY_SUFFIX; + } + + if (expression->IsCallExpression()) { + return OBJECT_TYPE; + } + + if (expression->IsObjectExpression()) { + return OBJECT_TYPE; + } + + if (expression->IsThisExpression()) { + return OBJECT_TYPE; + } + + if (expression->IsNewExpression()) { + return OBJECT_TYPE; + } + + return OBJECT_TYPE; +} + +std::string AddLocalVariable::InferTypeFromComplexExpression(ir::AstNode *expression) +{ + if (expression->IsBinaryExpression()) { + return InferTypeFromBinaryExpression(expression); + } + + return InferTypeFromOtherExpressions(expression); +} + +std::string AddLocalVariable::InferTypeFromExpression(ir::AstNode *expression) +{ + if (expression == nullptr) { + return OBJECT_TYPE; + } + + std::string literalType = InferTypeFromLiteral(expression); + if (!literalType.empty()) { + return literalType; + } + + return InferTypeFromComplexExpression(expression); +} + +std::string AddLocalVariable::GenerateVariableDeclaration(const std::string &variableName, + const std::string &variableType) +{ + return std::string(LET_KEYWORD) + variableName + TYPE_SEPARATOR + variableType + STATEMENT_TERMINATOR; +} + +bool AddLocalVariable::IsThisPropertyAccess(es2panda_Context *context, size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr || !token->IsIdentifier()) { + return false; + } + + auto *parent = token->Parent(); + if (parent == nullptr) { + return false; + } + + if (parent->IsMemberExpression()) { + auto *memberExpr = parent->AsMemberExpression(); + if (memberExpr->Object() != nullptr && memberExpr->Object()->IsThisExpression()) { + return true; + } + } + + return false; +} + +ir::AstNode *AddLocalVariable::FindClassInsertionPoint(ir::AstNode *current) +{ + while (current != nullptr) { + if (current->IsClassDefinition()) { + return current; + } + current = current->Parent(); + } + return nullptr; +} + +ir::AstNode *AddLocalVariable::FindFunctionInsertionPoint(ir::AstNode *current) +{ + while (current != nullptr) { + if (current->IsBlockStatement()) { + return current; + } + + ir::AstNode *functionBody = GetFunctionBody(current); + if (functionBody != nullptr) { + return functionBody; + } + + current = current->Parent(); + } + return nullptr; +} + +ir::AstNode *AddLocalVariable::GetFunctionBody(ir::AstNode *node) +{ + if (!node->IsFunctionDeclaration() && !node->IsMethodDefinition()) { + return nullptr; + } + + auto *functionNode = node->IsFunctionDeclaration() ? node->AsFunctionDeclaration()->Function() + : node->AsMethodDefinition()->Function(); + + if (functionNode == nullptr || functionNode->Body() == nullptr) { + return nullptr; + } + + return functionNode->Body(); +} + +ir::AstNode *AddLocalVariable::FindInsertionPoint(ir::AstNode *unresolvedNode, bool isThisProperty) +{ + if (unresolvedNode == nullptr) { + return nullptr; + } + + if (isThisProperty) { + return FindClassInsertionPoint(unresolvedNode); + } + + return FindFunctionInsertionPoint(unresolvedNode); +} + +void AddLocalVariable::MakeChangeForAddLocalVariable(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr || !token->IsIdentifier()) { + return; + } + + auto *identifier = token->AsIdentifier(); + std::string variableName = std::string(identifier->Name()); + + bool isThisProperty = IsThisPropertyAccess(context, pos); + + auto *insertionPoint = FindInsertionPoint(token, isThisProperty); + if (insertionPoint == nullptr) { + return; + } + + std::string variableType = DetermineVariableType(token); + std::string declaration; + size_t insertPos = insertionPoint->Start().index; + + auto *ctx = reinterpret_cast(context); + auto sourceCode = std::string(ctx->parserProgram->SourceCode()); + + size_t bracePos = sourceCode.find('{', insertPos); + if (bracePos != std::string::npos) { + insertPos = bracePos + 1; + } + + if (isThisProperty) { + declaration = std::string(INDENT) + variableName + TYPE_SEPARATOR + variableType + STATEMENT_TERMINATOR; + } else { + declaration = std::string(INDENT) + GenerateVariableDeclaration(variableName, variableType); + } + + TextRange insertRange = {insertPos, insertPos}; + auto astContext = reinterpret_cast(context); + changeTracker.ReplaceRangeWithText(astContext->sourceFile, insertRange, declaration); +} + +std::vector AddLocalVariable::GetCodeActionsToAddLocalVariable(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForAddLocalVariable(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +AddLocalVariable::AddLocalVariable() +{ + auto functionErrorCodes = ADD_LOCAL_VARIABLE.GetSupportedCodeNumbers(); + auto classErrorCodes = ADD_LOCAL_VARIABLE_FOR_CLASS.GetSupportedCodeNumbers(); + + std::vector allErrorCodes; + allErrorCodes.insert(allErrorCodes.end(), functionErrorCodes.begin(), functionErrorCodes.end()); + allErrorCodes.insert(allErrorCodes.end(), classErrorCodes.begin(), classErrorCodes.end()); + + SetErrorCodes(allErrorCodes); + SetFixIds({ADD_LOCAL_VARIABLE.GetFixId().data(), ADD_LOCAL_VARIABLE_FOR_CLASS.GetFixId().data()}); +} + +std::vector AddLocalVariable::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToAddLocalVariable(context); + if (!changes.empty()) { + CodeFixAction codeAction; + + bool isThisProperty = IsThisPropertyAccess(context.context, context.span.start); + if (isThisProperty) { + codeAction.fixName = ADD_LOCAL_VARIABLE_FOR_CLASS.GetFixId().data(); + codeAction.fixId = ADD_LOCAL_VARIABLE_FOR_CLASS.GetFixId().data(); + codeAction.description = CLASS_FIELD_DESCRIPTION; + codeAction.fixAllDescription = CLASS_FIELD_FIX_ALL_DESCRIPTION; + } else { + codeAction.fixName = ADD_LOCAL_VARIABLE.GetFixId().data(); + codeAction.fixId = ADD_LOCAL_VARIABLE.GetFixId().data(); + codeAction.description = LOCAL_VARIABLE_DESCRIPTION; + codeAction.fixAllDescription = LOCAL_VARIABLE_FIX_ALL_DESCRIPTION; + } + + codeAction.changes = changes; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions AddLocalVariable::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForAddLocalVariable(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_addLocalVariable(ADD_LOCAL_VARIABLE.GetFixId().data()); + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_addLocalVariableForClass(ADD_LOCAL_VARIABLE_FOR_CLASS.GetFixId().data()); + +} // namespace ark::es2panda::lsp 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..2f032995dfc8e22470c850b7928935d9e157645d --- /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.GetStart(), 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/add_missing_new_operator.cpp b/ets2panda/lsp/src/register_code_fix/add_missing_new_operator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c678ce14e1fa1174cc39a274a7dc87584449f63 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/add_missing_new_operator.cpp @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp/include/internal_api.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/add_missing_new_operator.h" + +namespace ark::es2panda::lsp { +const int G_ADD_MISSING_NEW_OPERATOR_CODE = 1022; +FixAddMissingNewOperator::FixAddMissingNewOperator() +{ + const char *fixId = "FixAddMissingNewOperator"; + SetErrorCodes({G_ADD_MISSING_NEW_OPERATOR_CODE}); + SetFixIds({fixId}); +} + +bool FixAddMissingNewOperator::IsValidTarget(const ir::AstNode *node) +{ + return node != nullptr && node->IsCallExpression(); +} + +void FixAddMissingNewOperator::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + const auto *impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + const ir::AstNode *callExpr = token; + while (callExpr != nullptr && !callExpr->IsCallExpression()) { + callExpr = callExpr->Parent(); + } + if (!IsValidTarget(callExpr)) { + return; + } + auto *call = const_cast(callExpr->AsCallExpression()); + auto *callee = const_cast(call->Callee()); + if (callee == nullptr) { + return; + } + auto *calleeNode = reinterpret_cast(callee); + if (calleeNode == nullptr) { + return; + } + es2panda_AstNode *part = impl->CreateETSTypeReferencePart1(context, calleeNode); + impl->AstNodeSetParent(context, calleeNode, part); + es2panda_AstNode *typeRef = impl->CreateETSTypeReference(context, part); + impl->AstNodeSetParent(context, part, typeRef); + es2panda_AstNode *newExpr = impl->CreateETSNewClassInstanceExpression(context, typeRef, nullptr, 0); + impl->AstNodeSetParent(context, typeRef, newExpr); + auto *newExprNode = reinterpret_cast(newExpr); + if (newExprNode == nullptr) { + return; + } + newExprNode->SetParent(call->Parent()); + changeTracker.ReplaceNode(context, call, newExprNode, {}); + fixedNodes.push_back(newExprNode); +} + +std::vector FixAddMissingNewOperator::GetCodeActionsToFix(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, context.span.start, fixedNodes); + }); + return fileTextChanges; +} + +std::vector FixAddMissingNewOperator::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = "addMissingNewOperator"; + codeAction.description = "Add missing 'new' operator to constructor call"; + codeAction.changes = changes; + codeAction.fixId = "AddMissingNewOperator"; + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions FixAddMissingNewOperator::GetAllCodeActions([[maybe_unused]] const CodeFixAllContext &codeFixAll) +{ + return {}; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_addMissingNew("AddMissingNewOperator"); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/add_name_to_nameless_parameter.cpp b/ets2panda/lsp/src/register_code_fix/add_name_to_nameless_parameter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..284a1b881639486001e0506f9c95e40f04017fd7 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/add_name_to_nameless_parameter.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 +#include +#include +#include "public/es2panda_lib.h" +#include "lsp/include/internal_api.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/add_name_to_nameless_parameter.h" + +namespace ark::es2panda::lsp { +using codefixes::ADD_NAME_TO_NAMELESS_PARAMETER; +namespace { +inline std::string ToString(const util::StringView &sv) +{ + auto u = sv.Utf8(); + return std::string(u.data(), u.size()); +} + +inline std::string ToString(std::string_view sv) +{ + return std::string(sv.data(), sv.size()); +} + +inline std::string_view Slice(std::string_view sv, size_t start, size_t length) +{ + return std::string_view(sv.data() + start, length); +} + +// Count commas between the opening '(' and the parameter start (0-based index). +int ComputeParamIndexByText(const std::string &fullSource, size_t paramStart) +{ + if (fullSource.empty() || paramStart == 0 || paramStart > fullSource.size()) { + return 0; + } + const size_t lparen = fullSource.rfind('(', paramStart); + if (lparen == std::string::npos) { + return 0; + } + int idx = 0; + for (size_t i = lparen + 1; i < paramStart; ++i) { + if (fullSource[i] == ',') { + ++idx; + } + } + return idx; +} + +// Return the start index of the current parameter (right after the nearest '(' or ',' before tokenStart) +size_t ParamSliceStart(const std::string &src, size_t tokenStart) +{ + const size_t lp = src.rfind('(', tokenStart); + const size_t cm = src.rfind(',', tokenStart); + size_t start = std::max(lp == std::string::npos ? 0 : lp, cm == std::string::npos ? 0 : cm); + if (start < src.size()) { + ++start; + } + return start; +} + +// true if there's a ':' between the start of *this* parameter and the token start +bool HasColonBeforeTokenInSameParam(const std::string &src, size_t tokenStart) +{ + if (tokenStart == 0 || tokenStart > src.size()) { + return false; + } + const size_t start = ParamSliceStart(src, tokenStart); + const size_t colon = src.find(':', start); + return colon != std::string::npos && colon < tokenStart; +} + +// true if there's a '=' between the start of *this* parameter and the token start +bool HasEqualsBeforeTokenInSameParam(const std::string &src, size_t tokenStart) +{ + if (tokenStart == 0 || tokenStart > src.size()) { + return false; + } + const size_t start = ParamSliceStart(src, tokenStart); + const size_t eq = src.find('=', start); + return eq != std::string::npos && eq < tokenStart; +} + +} // namespace + +AddNameToNamelessParameter::AddNameToNamelessParameter() +{ + auto errorCodes = ADD_NAME_TO_NAMELESS_PARAMETER.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({ADD_NAME_TO_NAMELESS_PARAMETER.GetFixId().data()}); +} + +bool AddNameToNamelessParameter::IsIdentifier(const ir::AstNode *node) +{ + return node != nullptr && node->IsIdentifier(); +} + +const ir::AstNode *AddNameToNamelessParameter::FindParameterNode(const ir::AstNode *start) +{ + const ir::AstNode *n = start; + while (n != nullptr) { + if (n->Type() == ir::AstNodeType::ETS_PARAMETER_EXPRESSION) { + return n; + } + n = n->Parent(); + } + return (start != nullptr) ? start->Parent() : nullptr; +} + +std::string AddNameToNamelessParameter::GetNodeText(std::string_view fullSource, const ir::AstNode *node) +{ + if (node == nullptr) { + return {}; + } + const size_t start = node->Range().start.index; + const size_t end = node->Range().end.index; + if (end < start) { + return {}; + } + return ToString(Slice(fullSource, start, end - start)); +} + +void AddNameToNamelessParameter::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr || !IsIdentifier(token)) { + return; + } + + const ir::AstNode *paramNode = FindParameterNode(token); + if (paramNode == nullptr) { + return; + } + + using ark::es2panda::public_lib::Context; + auto *pub = reinterpret_cast(context); + if (pub == nullptr || pub->parserProgram == nullptr) { + return; + } + + const std::string fullSource = ToString(pub->parserProgram->SourceCode()); + const size_t tokenStart = token->Range().start.index; + if (HasColonBeforeTokenInSameParam(fullSource, tokenStart) || + HasEqualsBeforeTokenInSameParam(fullSource, tokenStart)) { + return; + } + + const std::string typeText = GetNodeText(fullSource, token); + const int idx = ComputeParamIndexByText(fullSource, tokenStart); + const std::string nameText = "arg" + std::to_string(idx); + const size_t tokenEnd = token->Range().end.index; + if (tokenEnd < tokenStart) { + return; + } + + const TextSpan replaceSpan(tokenStart, tokenEnd - tokenStart); + const std::string replacement = nameText + ": " + typeText; + const std::string filePath = (pub->sourceFile != nullptr) ? ToString(pub->sourceFile->filePath) : std::string(); + TextChange tc(replaceSpan, replacement); + FileTextChanges fc(filePath, {tc}); + const SourceFile *owner = pub->sourceFile; + changeTracker.PushRaw(owner, fc); + fixedNodes.push_back(const_cast(paramNode)); +} + +std::vector AddNameToNamelessParameter::GetCodeActionsToFix(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, context.span.start, fixedNodes); + }); + + return fileTextChanges; +} + +std::vector AddNameToNamelessParameter::GetCodeActions(const CodeFixContext &context) +{ + std::vector actions; + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction action; + action.fixName = ADD_NAME_TO_NAMELESS_PARAMETER.GetFixId().data(); + action.description = "Add parameter name"; + action.changes = changes; + action.fixId = ADD_NAME_TO_NAMELESS_PARAMETER.GetFixId().data(); + actions.push_back(action); + } + return actions; +} + +CombinedCodeActions AddNameToNamelessParameter::GetAllCodeActions([[maybe_unused]] const CodeFixAllContext & /*unused*/) +{ + return {}; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_addNameToNamelessParameter( + ADD_NAME_TO_NAMELESS_PARAMETER.GetFixId().data()); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/constructor_for_derived_need_super_call.cpp b/ets2panda/lsp/src/register_code_fix/constructor_for_derived_need_super_call.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16af499d9d5d94d161c8e659b9c588a3e53a0a88 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/constructor_for_derived_need_super_call.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/include/internal_api.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/constructor_for_derived_need_super_call.h" + +namespace ark::es2panda::lsp { +using codefixes::CONSTRUCTOR_DERIVED_NEED_SUPER; +ConstructorDerivedNeedSuper::ConstructorDerivedNeedSuper() +{ + auto errorCodes = CONSTRUCTOR_DERIVED_NEED_SUPER.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({CONSTRUCTOR_DERIVED_NEED_SUPER.GetFixId().data()}); +} + +bool ConstructorDerivedNeedSuper::IsValidTarget(const ir::AstNode *node) +{ + return node != nullptr && (node->IsETSStructDeclaration() || node->IsClassDeclaration()); +} + +const ir::AstNode *ConstructorDerivedNeedSuper::FindEnclosingClassNode(const ir::AstNode *start) +{ + const ir::AstNode *node = start; + while (node != nullptr && !node->IsETSStructDeclaration() && !node->IsClassDeclaration()) { + node = node->Parent(); + } + return node; +} + +ir::ClassDefinition *ConstructorDerivedNeedSuper::ExtractClassDefinition(const ir::AstNode *classNode) +{ + if (classNode->IsETSStructDeclaration()) { + auto *structDecl = const_cast(classNode->AsETSStructDeclaration()); + return (structDecl != nullptr && structDecl->Definition() != nullptr) ? structDecl->Definition() : nullptr; + } + + if (classNode->IsClassDeclaration()) { + auto *classDecl = const_cast(classNode->AsClassDeclaration()); + if (classDecl == nullptr || classDecl->Definition() == nullptr || classDecl->Definition()->Super() == nullptr) { + return nullptr; + } + return classDecl->Definition(); + } + + return nullptr; +} + +ir::MethodDefinition *ConstructorDerivedNeedSuper::GetConstructorMethodFromDefinition(ir::ClassDefinition *definition) +{ + for (auto *member : definition->Body()) { + if (!member->IsMethodDefinition()) { + continue; + } + auto *method = member->AsMethodDefinition(); + if (method->Kind() == ir::MethodDefinitionKind::CONSTRUCTOR) { + return method; + } + } + return nullptr; +} + +bool ConstructorDerivedNeedSuper::NeedsSuperCall(ir::ScriptFunction *scriptFunc) +{ + if (scriptFunc == nullptr || scriptFunc->Body() == nullptr || !scriptFunc->Body()->IsBlockStatement()) { + return false; + } + + auto *block = scriptFunc->Body()->AsBlockStatement(); + for (const auto *stmt : block->Statements()) { + if (!stmt->IsExpressionStatement()) { + continue; + } + const auto *exprStmt = stmt->AsExpressionStatement(); + const auto *expr = exprStmt->GetExpression(); + if (!expr->IsCallExpression()) { + continue; + } + const auto *callExpr = expr->AsCallExpression(); + const auto *callee = callExpr->Callee(); + if (callee != nullptr && callee->IsSuperExpression()) { + return false; + } + } + return true; +} + +ir::Statement *ConstructorDerivedNeedSuper::CreateSuperStatement(es2panda_Context *context) +{ + const auto *impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + auto *superExpr = impl->CreateSuperExpression(context); + auto *superCall = impl->CreateCallExpression(context, superExpr, nullptr, 0, nullptr, false, false); + auto *superStmt = impl->CreateExpressionStatement(context, superCall); + + impl->AstNodeSetParent(context, superExpr, superCall); + impl->AstNodeSetParent(context, superCall, superStmt); + + auto *stmt = reinterpret_cast(superStmt); + return stmt != nullptr && stmt->IsStatement() ? stmt->AsStatement() : nullptr; +} + +void ConstructorDerivedNeedSuper::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + const ir::AstNode *classNode = FindEnclosingClassNode(token); + if (!IsValidTarget(classNode)) { + return; + } + + ir::ClassDefinition *definition = ExtractClassDefinition(classNode); + if (definition == nullptr) { + return; + } + + auto *ctorMethod = GetConstructorMethodFromDefinition(definition); + if (ctorMethod == nullptr || ctorMethod->Value() == nullptr || !ctorMethod->Value()->IsFunctionExpression()) { + return; + } + + auto *funcExpr = ctorMethod->Value()->AsFunctionExpression(); + auto *scriptFunc = funcExpr->Function(); + if (!NeedsSuperCall(scriptFunc)) { + return; + } + + auto *superStatement = CreateSuperStatement(context); + if (superStatement == nullptr) { + return; + } + + auto *block = scriptFunc->Body()->AsBlockStatement(); + changeTracker.InsertNodeAtConstructorStart(context, block, superStatement); + fixedNodes.push_back(ctorMethod); +} + +std::vector ConstructorDerivedNeedSuper::GetCodeActionsToFix(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, context.span.start, fixedNodes); + }); + + return fileTextChanges; +} + +std::vector ConstructorDerivedNeedSuper::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = CONSTRUCTOR_DERIVED_NEED_SUPER.GetFixId().data(); + codeAction.description = "Add missing 'super()' call to derived constructor"; + codeAction.changes = changes; + codeAction.fixId = CONSTRUCTOR_DERIVED_NEED_SUPER.GetFixId().data(); + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions ConstructorDerivedNeedSuper::GetAllCodeActions([[maybe_unused]] const CodeFixAllContext &codeFixAll) +{ + return {}; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_constructorForDerivedNeedSuperCall( + CONSTRUCTOR_DERIVED_NEED_SUPER.GetFixId().data()); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/convert_const_to_let.cpp b/ets2panda/lsp/src/register_code_fix/convert_const_to_let.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4d91d17813b7123cbe56596d304de48cffa9092c --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/convert_const_to_let.cpp @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/convert_const_to_let.h" + +#include +#include + +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_CONVERT_CONST_TO_LET; + +constexpr std::string_view KEYW_CONST_STR = "const"; +constexpr std::string_view KEYW_LET_STR = "let"; + +void FixConvertConstToLet::MakeChangeForConvertConstToLet(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + auto *scope = compiler::NearestScope(token); + auto *resolvedDecl = FindDeclInScopeWithFallback(scope, token->AsIdentifier()->Name()); + if (resolvedDecl == nullptr) { + return; + } + + TextRange constTokenRange = {0, 0}; + changeTracker.RfindNearestKeyWordTextRange(context, resolvedDecl->Node()->Start().index, KEYW_CONST_STR, + constTokenRange); + if (constTokenRange.end == 0) { + return; + } + auto astContext = reinterpret_cast(context); + const std::string replaceText(KEYW_LET_STR); + changeTracker.ReplaceRangeWithText(astContext->sourceFile, constTokenRange, replaceText); +} + +std::vector FixConvertConstToLet::GetCodeActionsToConvertConstToLet(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForConvertConstToLet(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixConvertConstToLet::FixConvertConstToLet() +{ + auto errorCodes = FIX_CONVERT_CONST_TO_LET.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_CONVERT_CONST_TO_LET.GetFixId().data()}); +} + +std::vector FixConvertConstToLet::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToConvertConstToLet(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = FIX_CONVERT_CONST_TO_LET.GetFixId().data(); + codeAction.description = "Convert const to let"; + codeAction.changes = changes; + codeAction.fixId = FIX_CONVERT_CONST_TO_LET.GetFixId().data(); + codeAction.fixAllDescription = "Convert all const to let"; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixConvertConstToLet::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForConvertConstToLet(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixConvertConstToLet(FIX_CONVERT_CONST_TO_LET.GetFixId().data()); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_add_function_return_statement.cpp b/ets2panda/lsp/src/register_code_fix/fix_add_function_return_statement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..51beebf135f06381ca8df9a5ad6711611bc1bba1 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_add_function_return_statement.cpp @@ -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. + */ + +#include "lsp/include/register_code_fix/fix_add_function_return_statement.h" +#include +#include +#include +#include +#include +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_ADD_FUNCTION_RETURN_STATEMENT; + +FixAddFunctionReturnStatement::FixAddFunctionReturnStatement() +{ + auto errorCodes = FIX_ADD_FUNCTION_RETURN_STATEMENT.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); // change this to the error code you want to handle + SetFixIds({FIX_ADD_FUNCTION_RETURN_STATEMENT.GetFixId().data()}); +} + +std::vector FixAddFunctionReturnStatement::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto info = GetInfo(context.context, context.span.start); + if (info.GetReturnTypeNode() == nullptr || info.GetBody() == nullptr) { + return returnedActions; // No valid return type or body found + } + + TextChangesContext textChangesContext {context.host, context.formatContext, context.preferences}; + auto replaceReturnTypeChanges = ChangeTracker::With( + textChangesContext, [&](ChangeTracker &tracker) { ReplaceReturnType(tracker, context.context, info); }); + auto addReturnStatementChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + AddReturnStatement(tracker, context.context, info.GetStatements(), info.GetBody()); + }); + CodeFixAction action; + action.fixName = FIX_ADD_FUNCTION_RETURN_STATEMENT.GetFixId().data(); + action.description = "Add missing return statement"; + action.fixId = FIX_ADD_FUNCTION_RETURN_STATEMENT.GetFixId().data(); + action.fixAllDescription = "Add all missing return statement"; + action.changes.insert(action.changes.end(), replaceReturnTypeChanges.begin(), replaceReturnTypeChanges.end()); + action.changes.insert(action.changes.end(), addReturnStatementChanges.begin(), addReturnStatementChanges.end()); + returnedActions.push_back(action); + + return returnedActions; +} + +CombinedCodeActions FixAddFunctionReturnStatement::GetAllCodeActions([[maybe_unused]] const CodeFixAllContext &ctx) +{ + CombinedCodeActions combinedActions; + return combinedActions; +} + +Info GetInfo(es2panda_Context *context, size_t position) +{ + const auto token = GetDefinitionAtPositionImpl(context, position); + const auto node = token.first; + const auto declaration = FindAncessor(node); + if (!declaration->IsFunctionExpression()) { + return Info(nullptr, nullptr, {}); + } + const auto returnTypeNode = declaration->AsFunctionExpression()->Function()->ReturnTypeAnnotation(); + if (returnTypeNode == nullptr || !returnTypeNode->IsETSTypeReference()) { + return Info(nullptr, nullptr, {}); + } + if (!declaration->AsFunctionExpression()->Function()->Body()->IsBlockStatement()) { + return Info(nullptr, nullptr, {}); + } + + const auto body = declaration->AsFunctionExpression()->Function()->Body(); + const auto statements = body->AsBlockStatement()->Statements(); + return Info(returnTypeNode, body, {statements.begin(), statements.end()}); +} + +void ReplaceReturnType(ChangeTracker &changes, es2panda_Context *context, Info &info) +{ + auto ctx = reinterpret_cast(context); + const auto &statements = info.GetStatements(); + bool statementFlag = false; + for (const auto &statement : statements) { + if (statement->IsReturnStatement()) { + statementFlag = true; + break; + } + } + if (statementFlag) { + return; + } + auto newNode = info.GetReturnTypeNode()->Clone(ctx->Allocator(), info.GetReturnTypeNode()->Parent()); + if (!newNode->IsETSTypeReference()) { + return; // Not a valid type reference node + } + auto typeRef = newNode->AsETSTypeReference(); + if (typeRef->Part()->IsETSTypeReferencePart()) { + auto part = typeRef->Part()->AsETSTypeReferencePart(); + part->GetIdent()->SetName("void"); // Change the type to 'void' + } + + changes.ReplaceNode(context, info.GetReturnTypeNode(), newNode, {}); +} +void AddReturnStatement(ChangeTracker &changes, es2panda_Context *context, std::vector statements, + ir::AstNode *body) +{ + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + if (!statements.empty()) { + // If the body is empty, we can add a return statement + auto *returnStmt = impl->CreateReturnStatement(context); + changes.InsertNodeAfter(context, statements[statements.size() - 1]->AsStatement(), + reinterpret_cast(returnStmt)); + } else { + size_t newSize = statements.size() + 1; + std::vector newStatementsVec(newSize, nullptr); + for (size_t i = 0; i < statements.size(); ++i) { + newStatementsVec[i] = reinterpret_cast(statements[i]->AsStatement()); + } + newStatementsVec[statements.size()] = impl->CreateReturnStatement(context); + auto newBody = impl->CreateBlockStatement(context, newStatementsVec.data(), statements.size()); + changes.ReplaceNode(context, body->AsBlockStatement(), reinterpret_cast(newBody), {}); + } +} + +ir::AstNode *FindAncessor(ir::AstNode *node) +{ + if (node->IsFunctionDeclaration() || node->IsFunctionExpression()) { + return node; + } + return FindAncessor(node->Parent()); +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixAddFunctionReturnStatement("FixAddFunctionReturnStatement"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp b/ets2panda/lsp/src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8c4fa1f056f272d26198f764c86a8a10e67b561 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.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 "code_fix_provider.h" +#include "code_fixes/code_fix_types.h" +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "internal_api.h" +#include "ir/astNode.h" +#include "ir/base/classDefinition.h" +#include "public/es2panda_lib.h" +#include "register_code_fix/fix_class_doesnt_implement_inherited_abstract_member.h" +#include "public/public.h" +#include "types.h" +#include +#include + +namespace ark::es2panda::lsp { +using codefixes::FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS; + +FixClassNotImplementingInheritedMembers::FixClassNotImplementingInheritedMembers() +{ + auto errorCodes = FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS.GetFixId().data()}); +} + +ir::AstNode *FixClassNotImplementingInheritedMembers::GetSuperClassDefinition(ir::AstNode *node) +{ + if (node == nullptr || !node->IsClassDefinition()) { + return nullptr; + } + auto superClass = node->AsClassDefinition()->Super(); + if (superClass->IsETSTypeReference()) { + auto part = superClass->AsETSTypeReference()->Part(); + if (part->IsETSTypeReferencePart()) { + auto name = part->Name(); + return compiler::DeclarationFromIdentifier(name->AsIdentifier()); + } + } + return nullptr; +} + +std::string FixClassNotImplementingInheritedMembers::MakeMethodSignature(ir::AstNode *node) +{ + if (node == nullptr || !node->IsMethodDefinition()) { + return ""; + } + auto methodName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name(); + return std::string(methodName) + node->AsMethodDefinition()->Function()->Signature()->ToString(); +} + +std::string FixClassNotImplementingInheritedMembers::MakeNewText(ir::AstNode *node) +{ + if (node == nullptr || !node->IsMethodDefinition()) { + return ""; + } + const std::string suffix = " {}"; + const std::string prefix = " "; + auto methodName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name(); + auto newText = std::string(methodName) + node->AsMethodDefinition()->Function()->DumpEtsSrc(); + newText.insert(0, prefix); + newText.insert(newText.size() - 1, suffix); + return newText; +} + +void FixClassNotImplementingInheritedMembers::MakeTextChangeForNotImplementedMembers(ChangeTracker &changeTracker, + es2panda_Context *context, + size_t pos) +{ + TextChange res {{0, 0}, ""}; + if (context == nullptr) { + return; + } + + auto targetNode = GetTouchingToken(context, pos, false); + if (targetNode == nullptr) { + return; + } + + while (targetNode->Parent() != nullptr) { + if (targetNode->IsClassDefinition()) { + targetNode = targetNode->AsClassDefinition()->Ident(); + break; + } + targetNode = targetNode->Parent(); + } + if (!targetNode->IsIdentifier()) { + return; + } + auto targetDecl = compiler::DeclarationFromIdentifier(targetNode->AsIdentifier()); + if (targetDecl == nullptr || !targetDecl->IsClassDefinition()) { + return; + } + + auto targetClassBodys = targetDecl->AsClassDefinition()->Body(); + res.span.start = targetDecl->AsClassDefinition()->Start().index + 1; + std::unordered_set methodSignature; + for (auto it : targetClassBodys) { + methodSignature.insert(MakeMethodSignature(it)); + } + + auto superClassDecl = GetSuperClassDefinition(targetDecl); + if (superClassDecl == nullptr || !superClassDecl->IsClassDefinition()) { + return; + } + auto superClassBodys = superClassDecl->AsClassDefinition()->Body(); + for (const auto &method : superClassBodys) { + if (!method->IsAbstract()) { + continue; + } + auto signature = MakeMethodSignature(method); + if (methodSignature.count(signature) == 0) { + res.newText += MakeNewText(method); + } + } + auto ctx = reinterpret_cast(context); + changeTracker.ReplaceRangeWithText(ctx->sourceFile, {res.span.start, res.span.start + res.span.length}, + res.newText); +} + +std::vector FixClassNotImplementingInheritedMembers::GetCodeActionsForAbstractMissingMembers( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeTextChangeForNotImplementedMembers(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +std::vector FixClassNotImplementingInheritedMembers::GetCodeActions(const CodeFixContext &context) +{ + std::vector actions; + auto changes = GetCodeActionsForAbstractMissingMembers(context); + if (!changes.empty()) { + CodeFixAction fix; + fix.fixName = FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS.GetFixId().data(); + fix.description = "Add missing inherited abstract members"; + fix.fixAllDescription = "Add missing all inherited abstract members"; + fix.changes = changes; + fix.fixId = FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS.GetFixId().data(); + actions.push_back(std::move(fix)); + } + + return actions; +} + +CombinedCodeActions FixClassNotImplementingInheritedMembers::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CodeFixProvider provider; + auto changes = provider.CodeFixAll( + codeFixAll, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeTextChangeForNotImplementedMembers(tracker, codeFixAll.context, diag.GetStart()); + }); + + CombinedCodeActions combined; + combined.changes = std::move(changes.changes); + combined.commands = std::move(changes.commands); + return combined; +} + +// NOLINTNEXTLINE +AutoCodeFixRegister g_fixClassNotImplementingInheritedMembers( + FIX_CLASS_NOT_IMPLEMENTING_INHERITED_MEMBERS.GetFixId().data()); + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/fix_class_incorrectly_implements_interface.cpp b/ets2panda/lsp/src/register_code_fix/fix_class_incorrectly_implements_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43d0d00c45a9e51d24aa7a19bf2403d834611a22 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_class_incorrectly_implements_interface.cpp @@ -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. + */ + +#include "lsp/include/register_code_fix/fix_class_incorrectly_implements_interface.h" + +#include "compiler/lowering/util.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" +#include "ir/astNode.h" +#include "ir/base/classDefinition.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsInterfaceBody.h" +#include "ir/ts/tsClassImplements.h" +#include "ir/base/methodDefinition.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER; +using codefixes::FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER; + +std::string FixClassIncorrectlyImplementsInterface::MakeNewTextForMember(ir::AstNode *node) +{ + if (node == nullptr || !node->IsMethodDefinition()) { + return ""; + } + + auto *methodDef = node->AsMethodDefinition(); + auto methodName = methodDef->Key()->AsIdentifier()->Name(); + std::string newText; + std::string prefix = "\n\n "; + std::string suffix; + + if (methodDef->IsGetter()) { + newText = "get " + std::string(methodName) + methodDef->Function()->DumpEtsSrc(); + suffix = " {\n return null;\n }"; + } else if (methodDef->IsSetter()) { + newText = "set " + std::string(methodName) + methodDef->Function()->DumpEtsSrc(); + suffix = " {\n }"; + } else { + newText = std::string(methodName) + methodDef->Function()->DumpEtsSrc(); + suffix = " {}"; + } + + newText.insert(0, prefix); + newText.insert(newText.size() - 1, suffix); + return newText; +} + +void FixClassIncorrectlyImplementsInterface::MakeChangeForMissingInterfaceMembers(ChangeTracker &changeTracker, + es2panda_Context *context, size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + auto *classNode = token; + while (classNode != nullptr && !classNode->IsClassDefinition()) { + classNode = classNode->Parent(); + } + + if (classNode == nullptr || !classNode->IsClassDefinition()) { + return; + } + + auto *classDef = classNode->AsClassDefinition(); + std::vector missingMembers = FindMissingInterfaceMembers(classDef); + if (missingMembers.empty()) { + return; + } + + auto classBody = classDef->Body(); + size_t insertPos = classDef->End().index; + if (!classBody.empty()) { + auto lastElement = classBody.back(); + insertPos = lastElement->End().index; + } + + std::string newText; + for (auto *missingMember : missingMembers) { + newText += MakeNewTextForMember(missingMember); + } + + if (!newText.empty()) { + TextRange insertRange = {insertPos, insertPos}; + auto astContext = reinterpret_cast(context); + changeTracker.ReplaceRangeWithText(astContext->sourceFile, insertRange, newText); + } +} + +std::vector FixClassIncorrectlyImplementsInterface::GetCodeActionsToImplementMissingMembers( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForMissingInterfaceMembers(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixClassIncorrectlyImplementsInterface::FixClassIncorrectlyImplementsInterface() +{ + auto getterErrorCodes = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER.GetSupportedCodeNumbers(); + auto setterErrorCodes = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER.GetSupportedCodeNumbers(); + + std::vector allErrorCodes; + allErrorCodes.insert(allErrorCodes.end(), getterErrorCodes.begin(), getterErrorCodes.end()); + allErrorCodes.insert(allErrorCodes.end(), setterErrorCodes.begin(), setterErrorCodes.end()); + + SetErrorCodes(allErrorCodes); + SetFixIds({FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER.GetFixId().data(), + FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER.GetFixId().data()}); +} + +void FixClassIncorrectlyImplementsInterface::GroupMissingMembers(const std::vector &missingMembers, + std::vector &missingGetters, + std::vector &missingSetters) +{ + for (auto *member : missingMembers) { + if (!member->IsMethodDefinition()) { + continue; + } + + auto *methodDef = member->AsMethodDefinition(); + if (methodDef->IsGetter()) { + missingGetters.push_back(member); + } else if (methodDef->IsSetter()) { + missingSetters.push_back(member); + } + } +} + +void FixClassIncorrectlyImplementsInterface::CreateCodeActionForType(const std::vector &members, + const CodeFixContext &context, bool isGetter, + std::vector &returnedActions) +{ + if (members.empty()) { + return; + } + + auto changes = GetCodeActionsToImplementMissingMembers(context); + if (changes.empty()) { + return; + } + + CodeFixAction codeAction; + if (isGetter) { + codeAction.fixName = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER.GetFixId().data(); + codeAction.description = "Add missing interface getter implementations"; + codeAction.fixAllDescription = "Implement all missing interface getters"; + codeAction.fixId = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER.GetFixId().data(); + } else { + codeAction.fixName = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER.GetFixId().data(); + codeAction.description = "Add missing interface setter implementations"; + codeAction.fixAllDescription = "Implement all missing interface setters"; + codeAction.fixId = FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER.GetFixId().data(); + } + + codeAction.changes = changes; + returnedActions.push_back(codeAction); +} + +std::vector FixClassIncorrectlyImplementsInterface::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + + auto *token = GetTouchingToken(context.context, context.span.start, false); + if (token == nullptr) { + return returnedActions; + } + + auto *classNode = token; + while (classNode != nullptr && !classNode->IsClassDefinition()) { + classNode = classNode->Parent(); + } + + if (classNode == nullptr || !classNode->IsClassDefinition()) { + return returnedActions; + } + + auto *classDef = classNode->AsClassDefinition(); + std::vector missingMembers = FindMissingInterfaceMembers(classDef); + if (missingMembers.empty()) { + return returnedActions; + } + + std::vector missingGetters; + std::vector missingSetters; + GroupMissingMembers(missingMembers, missingGetters, missingSetters); + + CreateCodeActionForType(missingGetters, context, true, returnedActions); + CreateCodeActionForType(missingSetters, context, false, returnedActions); + + return returnedActions; +} + +CombinedCodeActions FixClassIncorrectlyImplementsInterface::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForMissingInterfaceMembers(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} + +ir::AstNode *FixClassIncorrectlyImplementsInterface::FindInterfaceDefinition(ir::TSClassImplements *implement) +{ + if (!implement->IsTSClassImplements()) { + return nullptr; + } + + auto *tsImplements = implement->AsTSClassImplements(); + auto *expr = tsImplements->Expr(); + if (!expr->IsETSTypeReference()) { + return nullptr; + } + + auto *part = expr->AsETSTypeReference()->Part(); + if (!part->IsETSTypeReferencePart()) { + return nullptr; + } + + auto *name = part->Name(); + if (!name->IsIdentifier()) { + return nullptr; + } + + return compiler::DeclarationFromIdentifier(name->AsIdentifier()); +} + +std::vector FixClassIncorrectlyImplementsInterface::GetInterfaceDefinitions( + ir::ClassDefinition *classDef) +{ + std::vector interfaces; + if (classDef == nullptr) { + return interfaces; + } + + auto implements = classDef->Implements(); + for (auto *implement : implements) { + auto *interfaceDef = FindInterfaceDefinition(implement); + if (interfaceDef != nullptr) { + interfaces.push_back(interfaceDef); + } + } + return interfaces; +} + +std::string FixClassIncorrectlyImplementsInterface::GenerateMemberSignature(ir::MethodDefinition *methodDef, + const std::string &memberName) +{ + if (methodDef->IsGetter()) { + return "get " + memberName; + } + if (methodDef->IsSetter()) { + return "set " + memberName; + } + return ""; +} + +bool FixClassIncorrectlyImplementsInterface::IsMemberImplemented(ir::ClassDefinition *classDef, + const std::string &memberSignature) +{ + if (classDef == nullptr) { + return false; + } + + auto classBody = classDef->Body(); + for (auto *member : classBody) { + if (!member->IsMethodDefinition()) { + continue; + } + + auto *methodDef = member->AsMethodDefinition(); + auto *methodId = methodDef->Key()->AsIdentifier(); + std::string currentMemberName = std::string(methodId->Name()); + std::string currentSignature = GenerateMemberSignature(methodDef, currentMemberName); + if (currentSignature.empty()) { + continue; + } + + if (currentSignature == memberSignature) { + return true; + } + } + return false; +} + +void FixClassIncorrectlyImplementsInterface::ProcessInterfaceMembers(ir::TSInterfaceDeclaration *interface, + ir::ClassDefinition *classDef, + std::vector &missingMembers) +{ + auto *interfaceBodyNode = interface->Body(); + if (interfaceBodyNode == nullptr) { + return; + } + + auto interfaceBody = interfaceBodyNode->Body(); + for (auto *member : interfaceBody) { + if (!member->IsMethodDefinition()) { + continue; + } + + auto *methodDef = member->AsMethodDefinition(); + auto *methodId = methodDef->Key()->AsIdentifier(); + std::string memberName = std::string(methodId->Name()); + std::string memberSignature = GenerateMemberSignature(methodDef, memberName); + if (memberSignature.empty()) { + continue; + } + + if (!IsMemberImplemented(classDef, memberSignature)) { + missingMembers.push_back(member); + } + } +} + +std::vector FixClassIncorrectlyImplementsInterface::FindMissingInterfaceMembers( + ir::ClassDefinition *classDef) +{ + std::vector missingMembers; + if (classDef == nullptr) { + return missingMembers; + } + + auto interfaces = GetInterfaceDefinitions(classDef); + for (auto *interfaceDef : interfaces) { + if (interfaceDef->IsTSInterfaceDeclaration()) { + auto *interface = interfaceDef->AsTSInterfaceDeclaration(); + ProcessInterfaceMembers(interface, classDef, missingMembers); + } + } + + return missingMembers; +} + +// NOLINTNEXTLINE +AutoCodeFixRegister g_FixClassIncorrectlyImplementsInterfaceForGetter( + FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_GETTER.GetFixId().data()); + +// NOLINTNEXTLINE +AutoCodeFixRegister g_FixClassIncorrectlyImplementsInterfaceForSetter( + FIX_CLASS_INCORRECTLY_IMPLEMENTS_INTERFACE_FOR_SETTER.GetFixId().data()); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_class_super_must_precede_this_access.cpp b/ets2panda/lsp/src/register_code_fix/fix_class_super_must_precede_this_access.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0a28b0bb10dfbeca29a2b35ca3a5d96036b6dfc4 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_class_super_must_precede_this_access.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 "lsp/include/register_code_fix/fix_class_super_must_precede_this_access.h" + +#include +#include +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +using codefixes::CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS; + +ir::AstNode *FindNearestFunction(ir::AstNode *node) +{ + while (node != nullptr) { + if (node->IsConstructor()) { + return node; + } + node = node->Parent(); + } + return nullptr; +} + +void FixClassSuperMustPrecedeThisAccess::MakeChangeForClassSuperMustPrecedeThisAccess(ChangeTracker &changeTracker, + es2panda_Context *context, + size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr || !token->IsThisExpression()) { + return; + } + + ir::AstNode *ctr = FindNearestFunction(token); + if (ctr == nullptr) { + return; + } + + ir::AstNode *superCall = nullptr; + ctr->FindChild([&](ir::AstNode *n) { + if (n->IsSuperExpression()) { + superCall = n; + return true; + } + return false; + }); + + ir::AstNode *blockStatement = nullptr; + ctr->FindChild([&](ir::AstNode *n) { + if (n->IsBlockStatement()) { + blockStatement = n; + return true; + } + return false; + }); + + if (superCall == nullptr) { + return; + } + + if (token->Start().index > superCall->Start().index) { + return; + } + + auto ctx = reinterpret_cast(context); + + changeTracker.DeleteRange(ctx->sourceFile, {superCall->Start().index, superCall->End().index}); + + auto *exprStmt = ctx->allocator->New(superCall->Parent()->AsExpression()); + changeTracker.InsertNodeAtConstructorStart(context, blockStatement, exprStmt); +} + +std::vector FixClassSuperMustPrecedeThisAccess::GetCodeActionsForClassSuperMustPrecedeThisAccess( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForClassSuperMustPrecedeThisAccess(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixClassSuperMustPrecedeThisAccess::FixClassSuperMustPrecedeThisAccess() +{ + auto errorCodes = CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS.GetFixId().data()}); +} + +std::vector FixClassSuperMustPrecedeThisAccess::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsForClassSuperMustPrecedeThisAccess(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS.GetFixId().data(); + codeAction.description = "Fix 'super' access before 'this'"; + codeAction.changes = changes; + codeAction.fixId = CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS.GetFixId().data(); + codeAction.fixAllDescription = "Fix all 'super' access before 'this'"; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixClassSuperMustPrecedeThisAccess::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForClassSuperMustPrecedeThisAccess(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixClassSuperMustPrecedeThisAccess( + CLASS_SUPER_MUST_PRECEDE_THIS_ACCESS.GetFixId().data()); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_expected_comma.cpp b/ets2panda/lsp/src/register_code_fix/fix_expected_comma.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e37751fd2d974f97bc9f51a3a67aeac131e99d1f --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_expected_comma.cpp @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp/include/internal_api.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/fix_expected_comma.h" + +namespace ark::es2panda::lsp { +const int G_FIX_EXPECTED_COMMA = 1016; + +void FixExpectedComma::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, Range range, + const std::string &possibleFix) +{ + if (possibleFix.empty()) { + return; + } + + auto node = GetNodeAtLocation(context, range); + if (node == nullptr) { + return; + } + + if (node->Parent()->IsObjectExpression() && node->IsProperty()) { + changeTracker.ReplaceNodeWithText(context, node->Parent(), possibleFix); + } +} + +ir::AstNode *FixExpectedComma::GetNodeAtLocation(es2panda_Context *context, Range range) +{ + auto *ctx = reinterpret_cast(context); + auto ast = ctx->parserProgram->Ast(); + auto nodeAtLocation = + ast->FindChild([&range](ir::AstNode *node) { return node->Range().start.line == range.start.line_; }); + + return nodeAtLocation; +} + +std::vector FixExpectedComma::GetCodeActionsToFix(const CodeFixContext &context) +{ + CodeFixProvider provider; + auto diagnostics = provider.GetDiagnostics(context); + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fileTextChanges; + + for (auto &diag : diagnostics->diagnostic) { + auto code = std::get(diag.code_); + if (code != G_FIX_EXPECTED_COMMA) { + continue; + } + + auto changes = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, diag.range_, diag.source_); + }); + + fileTextChanges.insert(fileTextChanges.end(), changes.begin(), changes.end()); + } + + return fileTextChanges; +} + +FixExpectedComma::FixExpectedComma() +{ + const char *fixId = "FixExpectedComma"; + SetErrorCodes({G_FIX_EXPECTED_COMMA}); + SetFixIds({fixId}); +} + +std::vector FixExpectedComma::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = "fixExpectedComma"; + codeAction.description = "Use comma instead of semicolon at possition"; + codeAction.changes = changes; + codeAction.fixId = "FixExpectedComma"; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixExpectedComma::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + std::vector fixedNodes; + CodeFixProvider provider; + + return provider.GetAllFixes(codeFixAll); +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_extends_interface_becomes_implements.cpp b/ets2panda/lsp/src/register_code_fix/fix_extends_interface_becomes_implements.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9deb1bc3b2d1c1510b40a4f3c3229b078f75660f --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_extends_interface_becomes_implements.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 "lsp/include/register_code_fix/fix_extends_interface_becomes_implements.h" + +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +using codefixes::EXTENDS_INTERFACE_BECOMES_IMPLEMENTS; + +constexpr std::string_view KEYW_IMPLEMENTS_STR = "implements"; + +void FixExtendsInterfaceBecomesImplements::MakeChangeForExtendsInterfaceBecomesImplements(ChangeTracker &changeTracker, + es2panda_Context *context, + size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + + size_t changeEnd = 0; + size_t changeStart = 0; + size_t spaceChar = 1; + if (!token->IsClassDeclaration()) { + return; + } + token->FindChild([&](ir::AstNode *n) { + if (n->IsIdentifier()) { + changeStart = n->End().index + spaceChar; + return true; + } + return false; + }); + + token->FindChild([&](ir::AstNode *n) { + if (n->IsETSTypeReference()) { + changeEnd = n->Start().index - spaceChar; + return true; + } + return false; + }); + + TextRange extendsRange = {changeStart, changeEnd}; + const std::string replaceText(KEYW_IMPLEMENTS_STR); + auto astContext = reinterpret_cast(context); + changeTracker.ReplaceRangeWithText(astContext->sourceFile, extendsRange, replaceText); +} + +std::vector FixExtendsInterfaceBecomesImplements::GetCodeActionsToExtendsInterfaceBecomesImplements( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForExtendsInterfaceBecomesImplements(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixExtendsInterfaceBecomesImplements::FixExtendsInterfaceBecomesImplements() +{ + auto errorCodes = EXTENDS_INTERFACE_BECOMES_IMPLEMENTS.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({EXTENDS_INTERFACE_BECOMES_IMPLEMENTS.GetFixId().data()}); +} + +std::vector FixExtendsInterfaceBecomesImplements::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToExtendsInterfaceBecomesImplements(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = EXTENDS_INTERFACE_BECOMES_IMPLEMENTS.GetFixId().data(); + codeAction.description = "Change 'extends' to 'implements'"; + codeAction.changes = changes; + codeAction.fixId = EXTENDS_INTERFACE_BECOMES_IMPLEMENTS.GetFixId().data(); + codeAction.fixAllDescription = "Change all 'extends' on interfaces to 'implements'"; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixExtendsInterfaceBecomesImplements::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForExtendsInterfaceBecomesImplements(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} + +// NOLINTNEXTLINE +AutoCodeFixRegister g_FixExtendsInterfaceBecomesImplements( + EXTENDS_INTERFACE_BECOMES_IMPLEMENTS.GetFixId().data()); + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/fix_import_non_exported_member.cpp b/ets2panda/lsp/src/register_code_fix/fix_import_non_exported_member.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52691ff6d2bd8015c23a18d7403731471754e8bb --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_import_non_exported_member.cpp @@ -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. + */ +#include "lsp/include/register_code_fix/fix_import_non_exported_member.h" +#include + +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_IMPORT_NON_EXPORTED_MEMBER; + +void FixImportNonExportedMember::MakeChangeForImportNonExportedMember(ChangeTracker &changeTracker, + es2panda_Context *context, size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + auto *importDeclNode = token; + util::StringView functionName; + + if (!FindImportDeclaration(importDeclNode)) { + return; + } + + if (!FindFunctionName(importDeclNode, functionName)) { + return; + } + + size_t exportPosition = 0; + + if (importDeclNode->IsETSImportDeclaration()) { + auto funcDecl = importDeclNode->AsETSImportDeclaration(); + if (!funcDecl->Specifiers().empty()) { + ProcessExportPosition(funcDecl, functionName, exportPosition, changeTracker); + } + } +} + +bool FixImportNonExportedMember::FindImportDeclaration(ir::AstNode *&importDeclNode) +{ + while (importDeclNode != nullptr && !importDeclNode->IsETSImportDeclaration()) { + importDeclNode = importDeclNode->Parent(); + } + return (importDeclNode != nullptr); +} + +bool FixImportNonExportedMember::FindFunctionName(ir::AstNode *importDeclNode, util::StringView &functionName) +{ + importDeclNode->FindChild([&](ir::AstNode *n) { + if (n->IsIdentifier() && n->Parent()->IsImportSpecifier()) { + functionName = n->AsIdentifier()->Name(); + return true; + } + return false; + }); + return !functionName.Empty(); +} + +void FixImportNonExportedMember::ProcessExportPosition(ir::AstNode *funcDecl, const util::StringView &functionName, + size_t &exportPosition, ChangeTracker &changeTracker) +{ + Initializer initializer = Initializer(); + const auto path = funcDecl->AsETSImportDeclaration()->ResolvedSource(); + auto targetContext = initializer.CreateContext(std::string(path).c_str(), ES2PANDA_STATE_CHECKED); + auto cctx = reinterpret_cast(targetContext); + auto nodeOfAllContext = cctx->parserProgram->Ast(); + if (targetContext == nullptr || nodeOfAllContext == nullptr) { + return; + } + + nodeOfAllContext->FindChild([&](ir::AstNode *n) { + if (n->IsIdentifier() && n->AsIdentifier()->Name() == functionName) { + exportPosition = n->Parent()->Start().index; + return true; + } + return false; + }); + + const std::string replaceText("export"); + changeTracker.ReplaceRangeWithText(cctx->sourceFile, {exportPosition, exportPosition}, replaceText); +} + +std::vector FixImportNonExportedMember::GetCodeActionsToImportNonExportedMember( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForImportNonExportedMember(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixImportNonExportedMember::FixImportNonExportedMember() +{ + auto errorCodes = FIX_IMPORT_NON_EXPORTED_MEMBER.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_IMPORT_NON_EXPORTED_MEMBER.GetFixId().data()}); +} + +std::vector FixImportNonExportedMember::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToImportNonExportedMember(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = FIX_IMPORT_NON_EXPORTED_MEMBER.GetFixId().data(); + codeAction.description = "Fix Import Non Exported Member"; + codeAction.changes = changes; + codeAction.fixId = FIX_IMPORT_NON_EXPORTED_MEMBER.GetFixId().data(); + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixImportNonExportedMember::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForImportNonExportedMember(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} + +// NOLINTNEXTLINE +AutoCodeFixRegister g_fixImportNonExportedMember( + FIX_IMPORT_NON_EXPORTED_MEMBER.GetFixId().data()); +} // 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..f1040baacc001ff077433096dfc93fe8360c013a --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_nan_equality.cpp @@ -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. + */ + +#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.GetFile().source.data(), ES2PANDA_STATE_CHECKED, + diag.GetFile().source.data()); + MakeChangeForNaNEquality(tracker, ctx, diag.GetStart(), + 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/fix_remove_override_modifier.cpp b/ets2panda/lsp/src/register_code_fix/fix_remove_override_modifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f0c8b41016341a436c051700bb7edce6ecdae35 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_remove_override_modifier.cpp @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_remove_override_modifier.h" + +#include +#include + +#include "compiler/lowering/util.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +using codefixes::REMOVE_OVERRIDE_MODIFIER; + +ir::AstNode *FindNearestClass(ir::AstNode *node) +{ + while (node != nullptr) { + if (node->IsClassDefinition()) { + return node; + } + node = node->Parent(); + } + return nullptr; +} + +void FixRemoveOverrideModifier::MakeChangeForRemoveOverrideModifier(ChangeTracker &changeTracker, + es2panda_Context *context, size_t pos) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + // Remove the override modifier if found + TextRange overrideTokenRange = {0, 0}; + changeTracker.RfindNearestKeyWordTextRange(context, token->Start().index, "override", overrideTokenRange); + if (overrideTokenRange.end == 0) { + return; + } + + auto astContext = reinterpret_cast(context); + changeTracker.DeleteRange(astContext->sourceFile, overrideTokenRange); +} + +std::vector FixRemoveOverrideModifier::GetCodeActionsToRemoveOverrideModifier( + const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForRemoveOverrideModifier(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +FixRemoveOverrideModifier::FixRemoveOverrideModifier() +{ + auto errorCodes = REMOVE_OVERRIDE_MODIFIER.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({REMOVE_OVERRIDE_MODIFIER.GetFixId().data()}); +} + +std::vector FixRemoveOverrideModifier::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToRemoveOverrideModifier(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = REMOVE_OVERRIDE_MODIFIER.GetFixId().data(); + codeAction.description = "Remove override modifier"; + codeAction.changes = changes; + codeAction.fixId = REMOVE_OVERRIDE_MODIFIER.GetFixId().data(); + codeAction.fixAllDescription = "Remove all unnecessary override modifiers"; + returnedActions.push_back(codeAction); + } + + return returnedActions; +} + +CombinedCodeActions FixRemoveOverrideModifier::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForRemoveOverrideModifier(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + + return combinedCodeActions; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixRemoveOverrideModifier(REMOVE_OVERRIDE_MODIFIER.GetFixId().data()); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/fix_return_type_in_async_function.cpp b/ets2panda/lsp/src/register_code_fix/fix_return_type_in_async_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f26a16d5b7c08950277c68a4b39d8f98386721bc --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_return_type_in_async_function.cpp @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_return_type_in_async_function.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" +#include "compiler/lowering/util.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_RETURN_TYPE_IN_ASYNC_FUNCTION; +constexpr size_t K_GENERIC_BRACKETS_LENGTH = 2; // '<' and '>' +FixReturnTypeInAsyncFunction::FixReturnTypeInAsyncFunction() +{ + auto errorCodes = FIX_RETURN_TYPE_IN_ASYNC_FUNCTION.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_RETURN_TYPE_IN_ASYNC_FUNCTION.GetFixId().data()}); +} + +ir::AstNode *FixReturnTypeInAsyncFunction::GetFunctionReturnType(es2panda_Context *context, size_t position) +{ + const auto token = lsp::GetDefinitionAtPositionImpl(context, position); + const auto declaration = token.first; + + if (declaration == nullptr) { + return nullptr; + } + + auto *returnTypeNode = + declaration->FindChild([](ir::AstNode *childNode) { return childNode->IsETSTypeReference(); }); + + if (returnTypeNode == nullptr || !returnTypeNode->IsETSTypeReference()) { + return nullptr; + } + + return returnTypeNode; +} + +void FixReturnTypeInAsyncFunction::MakeChangeReturnTypeInAsyncFunction(ChangeTracker &changeTracker, + es2panda_Context *context, size_t pos) +{ + auto *returnTypeNode = GetFunctionReturnType(context, pos); + + if (returnTypeNode == nullptr || !returnTypeNode->IsETSTypeReference()) { + return; + } + + auto *ctx = reinterpret_cast(context); + auto *allocator = ctx->Allocator(); + + // Clone the original return type node + auto *originalInnerType1 = returnTypeNode->Clone(allocator, returnTypeNode->Parent()); + // Create a new Identifier for "Promise" + auto *promiseName = allocator->New(util::StringView("Promise"), allocator); + + // Wrap the original type inside Promise + ArenaVector typeParams(allocator->Adapter()); + auto *typedInner = static_cast(originalInnerType1); + typeParams.push_back(typedInner); + + auto *typeParamInstantiation = allocator->New(std::move(typeParams)); + + // Create the type reference part: Promise<...> + auto *promisePart = allocator->New(promiseName, typeParamInstantiation, + nullptr, // no previous part + allocator); + + // Create the final ETSTypeReference node + auto *newReturnType = allocator->New(promisePart, allocator); + + newReturnType->SetParent(returnTypeNode->Parent()); + originalInnerType1->SetParent(newReturnType); + newReturnType->SetStart(returnTypeNode->Start()); + auto returnTypeNodeIdent = returnTypeNode->AsETSTypeReference()->Part()->Name()->AsIdentifier(); + + lexer::SourcePosition endPos(newReturnType->Start().index + promiseName->Name().Length() + + returnTypeNodeIdent->Name().Length() + K_GENERIC_BRACKETS_LENGTH, + returnTypeNode->Start().line, ctx->parserProgram); + newReturnType->SetEnd(endPos); + // Replace the old return type with the new Promise type + changeTracker.ReplaceNode(context, returnTypeNode, newReturnType, {}); +} + +std::vector FixReturnTypeInAsyncFunction::GetChanges(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeReturnTypeInAsyncFunction(tracker, context.context, context.span.start); + }); + + return fileTextChanges; +} + +std::vector FixReturnTypeInAsyncFunction::GetCodeActions(const CodeFixContext &context) +{ + std::vector actions; + auto changes = GetChanges(context); + if (!changes.empty()) { + CodeFixAction action; + action.fixName = FIX_RETURN_TYPE_IN_ASYNC_FUNCTION.GetFixId().data(); + action.description = "Wrap return type in Promise"; + action.changes = changes; + action.fixId = FIX_RETURN_TYPE_IN_ASYNC_FUNCTION.GetFixId().data(); + action.fixAllDescription = "Wrap all incorrect async return types with Promise"; + actions.push_back(action); + } + + return actions; +} + +CombinedCodeActions FixReturnTypeInAsyncFunction::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeReturnTypeInAsyncFunction(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combined; + combined.changes = changes.changes; + combined.commands = changes.commands; + return combined; +} + +// NOLINTNEXTLINE +AutoCodeFixRegister g_fixReturnTypeInAsyncFunction( + FIX_RETURN_TYPE_IN_ASYNC_FUNCTION.GetFixId().data()); + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/fix_spelling.cpp b/ets2panda/lsp/src/register_code_fix/fix_spelling.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2586467028544f60be4b472388a993ede9ac9944 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_spelling.cpp @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_spelling.h" +#include +#include +#include +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +using codefixes::FIX_SPELLING; + +FixSpelling::FixSpelling() +{ + auto errorCodes = FIX_SPELLING.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_SPELLING.GetFixId().data()}); +} +double JaccardSimilarity(const std::string &a, const std::string &b) +{ + std::unordered_set setA; + std::unordered_set setB; + + for (char ch : a) { + if (isalpha(ch) != 0) { + setA.insert(tolower(ch)); + } + } + + for (char ch : b) { + if (isalpha(ch) != 0) { + setB.insert(tolower(ch)); + } + } + + size_t intersectionSize = 0; + for (char ch : setA) { + if (setB.find(ch) != setB.end()) { + intersectionSize++; + } + } + + size_t unionSize = setA.size() + setB.size() - intersectionSize; + if (unionSize == 0) { + return 0.0; + } + + return static_cast(intersectionSize) / unionSize; +} + +std::string FindClosestWordJaccard(const ir::AstNode *astNode, const std::string &search) +{ + if (astNode == nullptr) { + return ""; + } + double maxSimilarity = -1.0; + std::string closestWord; + astNode->FindChild([&search, &maxSimilarity, &closestWord](const ir::AstNode *node) { + if (node->IsIdentifier() && std::string(node->AsIdentifier()->Name().Utf8()) != search) { + double similarity = JaccardSimilarity(std::string(node->AsIdentifier()->Name().Utf8()), search); + if (similarity > maxSimilarity) { + maxSimilarity = similarity; + closestWord = std::string(node->AsIdentifier()->Name().Utf8()); + } + } + return false; + }); + return closestWord; +} + +void DoChanges(ChangeTracker &changes, es2panda_Context *context, ir::AstNode *node, const std::string &target) +{ + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + auto ctx = reinterpret_cast(context); + + if (node == nullptr) { + return; + } + if (!node->IsIdentifier()) { + std::vector buffer(target.begin(), target.end()); + buffer.push_back('\0'); + auto newSource = impl->CreateStringLiteral1(context, buffer.data()); + auto changedNode = reinterpret_cast(newSource); + changes.ReplaceNode(context, node, changedNode, {}); + } else if (node->IsIdentifier()) { + auto newNode = node->Clone(ctx->Allocator(), node->Parent()); + newNode->AsIdentifier()->SetName(target.c_str()); + changes.ReplaceNode(context, node, newNode, {}); + } +} + +std::vector FixSpelling::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + if (context.errorCode != 0) { + auto info = GetInfoSpelling(context.context, context.span.start); + if (info.GetFindClosestWord().empty() || info.GetNode() == nullptr) { + return returnedActions; + } + TextChangesContext textChangesContext {context.host, context.formatContext, context.preferences}; + auto changes = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + DoChanges(tracker, context.context, info.GetNode(), info.GetFindClosestWord()); + }); + CodeFixAction action; + action.fixName = FIX_SPELLING.GetFixId().data(); + action.description = "Fix spelling error"; + action.fixId = FIX_SPELLING.GetFixId().data(); + action.fixAllDescription = "Fix all spelling errors"; + action.changes.insert(action.changes.end(), changes.begin(), changes.end()); + returnedActions.push_back(action); + + return returnedActions; + } + + return returnedActions; +} + +CombinedCodeActions FixSpelling::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll( + codeFixAll, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + auto info = GetInfoSpelling(codeFixAll.context, diag.GetStart()); + DoChanges(tracker, codeFixAll.context, info.GetNode(), info.GetFindClosestWord()); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + return combinedCodeActions; +} + +Info GetInfoSpelling(es2panda_Context *context, size_t position) +{ + const auto token = GetTouchingToken(context, position, false); + if (token == nullptr) { + return {"", nullptr}; + } + const auto parent = token->Parent(); + const auto ctx = reinterpret_cast(context); + const auto astNode = ctx->parserProgram->Ast(); + + if (!parent->IsETSImportDeclaration()) { + auto findClosestWord = FindClosestWordJaccard(astNode, std::string(token->AsIdentifier()->Name().Utf8())); + if (!findClosestWord.empty()) { + return {findClosestWord, token}; + } + } + auto importDecl = parent->AsETSImportDeclaration(); + if (!importDecl->Specifiers().empty()) { + Initializer initializer = Initializer(); + const auto path = importDecl->ResolvedSource(); + auto con = initializer.CreateContext(std::string(path).c_str(), ES2PANDA_STATE_CHECKED); + auto cctx = reinterpret_cast(con); + const auto importAstNode = cctx->parserProgram->Ast(); + std::string findClosestWord; + if (token->IsIdentifier()) { + findClosestWord = FindClosestWordJaccard(importAstNode, std::string(token->AsIdentifier()->Name().Utf8())); + } else if (token->IsStringLiteral()) { + findClosestWord = + FindClosestWordJaccard(importAstNode, std::string(token->AsStringLiteral()->Str().Utf8())); + } + return {findClosestWord, token}; + } + + return {"", token}; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixSpelling("FixSpelling"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp b/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a999732235500a56a75035c697c92915726091d --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_unreachable_code.cpp @@ -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. + */ + +#include "lsp/include/register_code_fix/fix_unreachable_code.h" +#include +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +using codefixes::FIX_UNREACHABLE_CODE; + +FixUnreachableCode::FixUnreachableCode() +{ + auto errorCodes = FIX_UNREACHABLE_CODE.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); + SetFixIds({FIX_UNREACHABLE_CODE.GetFixId().data()}); +} + +static inline bool IsTerminatorStmt(const ir::AstNode *s) +{ + return (s != nullptr) && (s->IsReturnStatement() || s->IsThrowStatement()); +} + +TextRange FixUnreachableCode::HandleUnreachableAfterTerminator(ir::AstNode *stmt) +{ + ir::AstNode *parent = stmt->Parent(); + if (parent == nullptr) { + return {0, 0}; + } + + if (!parent->IsBlockStatement()) { + return {0, 0}; + } + + auto *block = parent->AsBlockStatement(); + const auto &stmts = block->Statements(); + + int idx = -1; + for (int i = 0; i < static_cast(stmts.size()); ++i) { + if (stmts[i] == stmt) { + idx = i; + break; + } + } + if (idx < 0) { + return {0, 0}; + } + + for (int j = idx - 1; j >= 0; --j) { + const ir::AstNode *prev = stmts[j]; + if (prev != nullptr && IsTerminatorStmt(prev)) { + return {stmt->Start().index, stmt->End().index}; + } + } + + return {0, 0}; +} + +TextRange FixUnreachableCode::HandleUnreachableStatement(ir::AstNode *statement) +{ + if (statement == nullptr) { + return {0, 0}; + } + + while (statement != nullptr) { + if (statement->IsWhileStatement() || statement->IsIfStatement() || statement->IsForUpdateStatement()) { + break; + } + statement = statement->Parent(); + } + + if (statement == nullptr) { + return {0, 0}; + } + + ir::Expression *expr = nullptr; + if (statement->IsWhileStatement()) { + expr = statement->AsWhileStatement()->Test(); + } else if (statement->IsIfStatement()) { + expr = statement->AsIfStatement()->Test(); + } else if (statement->IsForUpdateStatement()) { + expr = statement->AsForUpdateStatement()->Test(); + } + + if (expr == nullptr) { + return {0, 0}; + } + + if (expr->IsBooleanLiteral()) { + auto boolLiteral = expr->AsBooleanLiteral(); + if (!boolLiteral->Value()) { + return {statement->Start().index, statement->End().index}; + } + } else if (expr->IsNumberLiteral()) { + if (expr->AsNumberLiteral()->Number().IsZero()) { + return {statement->Start().index, statement->End().index}; + } + } else if (expr->IsStringLiteral()) { + if (expr->AsStringLiteral()->ToString().empty()) { + return {statement->Start().index, statement->End().index}; + } + } else if (expr->IsCharLiteral()) { + if (expr->AsCharLiteral()->ToString().empty()) { + return {statement->Start().index, statement->End().index}; + } + } else if (expr->IsNullLiteral()) { + return {statement->Start().index, statement->End().index}; + } + + return {0, 0}; +} + +void FixUnreachableCode::MakeChangeForUnreachableCode(ChangeTracker &changeTracker, es2panda_Context *context, + size_t pos) +{ + TextRange range = {0, 0}; + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + while (token != nullptr && !token->IsStatement()) { + token = token->Parent(); + } + + if (token == nullptr) { + return; + } + + range = HandleUnreachableStatement(token); + if (range.pos != range.end) { + auto ctx = reinterpret_cast(context); + changeTracker.DeleteRange(ctx->sourceFile, {range.pos, range.end}); + return; + } + + range = HandleUnreachableAfterTerminator(token); + if (range.pos != range.end) { + auto ctx = reinterpret_cast(context); + changeTracker.DeleteRange(ctx->sourceFile, {range.pos, range.end}); + return; + } +} + +std::vector FixUnreachableCode::GetCodeActionsToRemoveUnreachableCode(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + return ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForUnreachableCode(tracker, context.context, context.span.start); + }); +} + +std::vector FixUnreachableCode::GetCodeActions(const CodeFixContext &context) +{ + std::vector actions; + auto changes = GetCodeActionsToRemoveUnreachableCode(context); + if (!changes.empty()) { + CodeFixAction fix; + fix.fixName = FIX_UNREACHABLE_CODE.GetFixId().data(); + fix.description = "Remove unreachable code"; + fix.fixAllDescription = "Remove all unreachable code"; + fix.changes = changes; + fix.fixId = FIX_UNREACHABLE_CODE.GetFixId().data(); + actions.push_back(std::move(fix)); + } + + return actions; +} + +CombinedCodeActions FixUnreachableCode::GetAllCodeActions(const CodeFixAllContext &codeFixAllCtx) +{ + CodeFixProvider provider; + auto changes = provider.CodeFixAll( + codeFixAllCtx, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChangeForUnreachableCode(tracker, codeFixAllCtx.context, diag.GetStart()); + }); + + CombinedCodeActions combined; + combined.changes = std::move(changes.changes); + combined.commands = std::move(changes.commands); + return combined; +} +// NOLINTNEXTLINE +AutoCodeFixRegister g_fixUnreachableCode(FIX_UNREACHABLE_CODE.GetFixId().data()); + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp b/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abad90b34984860c76b1749dbd261a4c768727e7 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/forgotten_this_property_access.cpp @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "register_code_fix/forgotten_this_property_access.h" +#include +#include "code_fix_provider.h" +#include "generated/code_fix_register.h" + +namespace ark::es2panda::lsp { +using codefixes::FORGOTTEN_THIS_PROPERTY_ACCESS; + +ForgottenThisPropertyAccess::ForgottenThisPropertyAccess() +{ + auto errorCodes = FORGOTTEN_THIS_PROPERTY_ACCESS.GetSupportedCodeNumbers(); + SetErrorCodes({errorCodes.begin(), errorCodes.end()}); // change this to the error code you want to handle + SetFixIds({FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data()}); +} + +Info GetInfoThisProp(es2panda_Context *context, size_t offset) +{ + ir::AstNode *node = ark::es2panda::lsp::GetTouchingToken(context, offset, false); + std::string className; + if (node == nullptr) { + return {nullptr, ""}; + } + if (node->IsIdentifier()) { + className = node->AsIdentifier()->Name().Utf8(); + } + Info info(node, className); + return info; +} + +void DoChanges(es2panda_Context *context, ChangeTracker tracker) +{ + auto ctx = reinterpret_cast(context); + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + + const auto &diagnostics = + ctx->diagnosticEngine->GetDiagnosticStorage(ark::es2panda::util::DiagnosticType::SEMANTIC); + + for (const auto &diagnostic : diagnostics) { + auto index = ark::es2panda::lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto offset = index.GetOffset( + ark::es2panda::lexer::SourceLocation(diagnostic->Line(), diagnostic->Offset(), ctx->parserProgram)); + auto node = ark::es2panda::lsp::GetTouchingToken(context, offset, false); + es2panda_AstNode *thisExpr = impl->CreateThisExpression(context); + es2panda_AstNode *memberExpr = + impl->CreateMemberExpression(context, thisExpr, reinterpret_cast(node), + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); + impl->AstNodeSetParent(context, thisExpr, memberExpr); + impl->AstNodeSetParent(context, reinterpret_cast(node), memberExpr); + auto memNode = reinterpret_cast(memberExpr); + if (memNode == nullptr) { + continue; + } + tracker.ReplaceNode(context, node, memNode, {}); + } +} + +std::vector ForgottenThisPropertyAccess::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + + const auto info = GetInfoThisProp(context.context, context.span.start); + if (info.GetNode() == nullptr) { + return {}; + } + TextChangesContext textChangesContext {context.host, context.formatContext, context.preferences}; + const auto changes = + ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { DoChanges(context.context, tracker); }); + std::vector actions; + CodeFixAction action; + action.fixName = FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data(); + action.description = "Add 'this.' to property access"; + action.fixId = FORGOTTEN_THIS_PROPERTY_ACCESS.GetFixId().data(); + action.changes.insert(action.changes.end(), changes.begin(), changes.end()); + action.fixAllDescription = "Add 'this.' to all property accesses in the file"; + returnedActions.push_back(action); + return returnedActions; +} + +CombinedCodeActions ForgottenThisPropertyAccess::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CodeFixProvider provider; + const auto changes = provider.CodeFixAll(codeFixAll, GetErrorCodes(), + [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + auto info = GetInfoThisProp(codeFixAll.context, diag.GetStart()); + if (info.GetNode() != nullptr) { + DoChanges(codeFixAll.context, tracker); + } + }); + + CombinedCodeActions combined; + combined.changes = changes.changes; + combined.commands = changes.commands; + return combined; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_forgottenThisPropertyAccess("ForgottenThisPropertyAccess"); + +} // namespace ark::es2panda::lsp \ No newline at end of file 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/register_code_fix/remove_accidental_call_parentheses.cpp b/ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62b6cbed0acb5ad4127eb49417ff74bc98207977 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp/include/internal_api.h" +#include "generated/code_fix_register.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/remove_accidental_call_parentheses.h" + +namespace ark::es2panda::lsp { +using codefixes::REMOVE_ACCIDENTAL_CALL_PARENTHESES; + +bool FixRemoveAccidentalCallParentheses::IsValidCallExpression(const ir::AstNode *node) +{ + if (node == nullptr || !node->IsCallExpression()) { + return false; + } + + const auto *callExpr = node->AsCallExpression(); + const auto *callee = callExpr->Callee(); + if (callee == nullptr) { + return false; + } + + if (!callee->IsMemberExpression()) { + return false; + } + + if (!callExpr->Arguments().empty()) { + return false; + } + + return true; +} + +TextRange FixRemoveAccidentalCallParentheses::CalculateDeleteRange(const ir::AstNode *callExpr) +{ + const auto *callExpression = callExpr->AsCallExpression(); + if (callExpression == nullptr || callExpression->Callee() == nullptr) { + return TextRange {0, 0}; + } + + size_t openParenPos = static_cast(callExpression->Callee()->End().index); + size_t closeParenPos = static_cast(callExpression->End().index); + if (closeParenPos <= openParenPos) { + return TextRange {0, 0}; + } + + return TextRange {openParenPos, closeParenPos}; +} + +void FixRemoveAccidentalCallParentheses::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + const ir::AstNode *callExpr = token; + while (callExpr != nullptr && !callExpr->IsCallExpression()) { + callExpr = callExpr->Parent(); + } + + if (!IsValidCallExpression(callExpr)) { + return; + } + + TextRange deleteRange = CalculateDeleteRange(callExpr); + if (deleteRange.pos == 0 && deleteRange.end == 0) { + return; + } + + fixedNodes.push_back(const_cast(callExpr)); + auto *ctx = reinterpret_cast(context); + const auto sourceFile = ctx->sourceFile; + changeTracker.DeleteRange(sourceFile, deleteRange); +} + +std::vector FixRemoveAccidentalCallParentheses::GetCodeActionsToFix(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, context.span.start, fixedNodes); + }); + + return fileTextChanges; +} + +FixRemoveAccidentalCallParentheses::FixRemoveAccidentalCallParentheses() +{ + const auto &codes = REMOVE_ACCIDENTAL_CALL_PARENTHESES.GetSupportedCodeNumbers(); + SetErrorCodes({codes.begin(), codes.end()}); + SetFixIds({REMOVE_ACCIDENTAL_CALL_PARENTHESES.GetFixId().data()}); +} + +std::vector FixRemoveAccidentalCallParentheses::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = REMOVE_ACCIDENTAL_CALL_PARENTHESES.GetFixId().data(); + codeAction.description = "Remove parentheses from accessor call"; + codeAction.changes = changes; + codeAction.fixId = REMOVE_ACCIDENTAL_CALL_PARENTHESES.GetFixId().data(); + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions FixRemoveAccidentalCallParentheses::GetAllCodeActions([[maybe_unused]] const CodeFixAllContext &ctx) +{ + return {}; +} + +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_removeCallParens( + REMOVE_ACCIDENTAL_CALL_PARENTHESES.GetFixId().data()); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/ui_plugin_suggest.cpp b/ets2panda/lsp/src/register_code_fix/ui_plugin_suggest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8d06e5ef119dd1f8072e31f6351c93194920be70 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/ui_plugin_suggest.cpp @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/ui_plugin_suggest.h" +#include +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +const int G_UI_PLUGIN_SUGGEST_CODE = 4000; // change this to the error code you want to handle +constexpr const char *G_UI_PLUGIN_SUGGEST_ID = "UIPluginSuggest"; + +static std::vector &GetFixAll() +{ + static std::vector fixAll; + return fixAll; +} + +UIPluginSuggest::UIPluginSuggest() +{ + SetErrorCodes({G_UI_PLUGIN_SUGGEST_CODE}); + SetFixIds({G_UI_PLUGIN_SUGGEST_ID}); +} + +CodeFixAction CreateCodeFixAction(const ark::es2panda::util::Diagnostic *diag, std::vector &changes) +{ + CodeFixAction codeAction; + codeAction.fixName = "Fix"; + codeAction.description = + diag->HasSuggestions() && !diag->Suggestion().empty() + ? !diag->Suggestion().at(0)->Title().empty() ? diag->Suggestion().at(0)->Title() : "Fix Description" + : "Fix Description"; + codeAction.changes = std::move(changes); + codeAction.fixId = "UI_PLUGIN_SUGGEST"; + codeAction.fixAllDescription = "Fix All Description"; + InstallPackageAction codeActionCommand; + codeActionCommand.file = diag->File(); + codeActionCommand.packageName = ""; + codeAction.commands.push_back(codeActionCommand); + return codeAction; +} + +std::vector GetTextChangesFromSuggestions(const ark::es2panda::util::Diagnostic *diag, size_t pos, + bool isAll, es2panda_Context *context) +{ + std::vector textChanges; + if (!diag->HasSuggestions()) { + return textChanges; + } + auto ctx = reinterpret_cast(context); + auto index = lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto offset = index.GetOffset(lexer::SourceLocation(diag->Line(), diag->Offset(), ctx->parserProgram)); + auto touchingToken = GetTouchingToken(context, offset, false); + if (touchingToken == nullptr) { + return textChanges; + } + auto start = touchingToken->Start().index; + auto end = touchingToken->End().index; + for (auto suggestion : diag->Suggestion()) { + auto sourceStart = suggestion->SourceRange()->start.index; + auto sourceEnd = suggestion->SourceRange()->end.index; + auto span = TextSpan(sourceStart, sourceEnd - sourceStart); + if (isAll || (pos >= start && pos <= end)) { + // compare diag range instead of suggestion range + // to support rules of different ranges of diag and suggestion + textChanges.emplace_back(TextChange(span, suggestion->SubstitutionCode())); + } + } + return textChanges; +} + +std::vector GetUIPluginCodeFixesByDiagType(es2panda_Context *context, size_t pos, bool isAll, + std::vector &actions, + util::DiagnosticType type) +{ + auto ctx = reinterpret_cast(context); + const auto &diagnostics = ctx->diagnosticEngine->GetDiagnosticStorage(type); + std::vector changes; + for (const auto &diagnostic : diagnostics) { + std::vector fileChanges; + auto diag = reinterpret_cast(&(*diagnostic)); + auto textChanges = GetTextChangesFromSuggestions(diag, pos, isAll, context); + FileTextChanges fileTextChanges(ctx->sourceFileName, textChanges); + fileChanges.emplace_back(fileTextChanges); + changes.emplace_back(fileTextChanges); + actions.push_back(CreateCodeFixAction(diag, fileChanges)); + } + return changes; +} + +std::vector UIPluginSuggest::GetUIPluginCodeFixes(es2panda_Context *context, size_t pos, bool isAll) +{ + std::vector types = {util::DiagnosticType::PLUGIN_ERROR, + util::DiagnosticType::PLUGIN_WARNING}; + std::vector changes; + std::vector returnedActions; + for (const auto &type : types) { + auto typeChanges = GetUIPluginCodeFixesByDiagType(context, pos, isAll, returnedActions, type); + changes.insert(changes.end(), typeChanges.begin(), typeChanges.end()); + } + + auto &fixAll = GetFixAll(); + fixAll = changes; + return returnedActions; +} + +std::vector UIPluginSuggest::GetCodeActions(const CodeFixContext &context) +{ + auto returnedActions = GetUIPluginCodeFixes(context.context, context.span.start, false); + return returnedActions; +} + +CombinedCodeActions UIPluginSuggest::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CombinedCodeActions combinedCodeActions; + auto &fixAll = GetFixAll(); + if (fixAll.empty()) { + GetUIPluginCodeFixes(codeFixAll.context, 0, true); + } + combinedCodeActions.changes = fixAll; + InstallPackageAction codeActionCommand; + codeActionCommand.file = reinterpret_cast(codeFixAll.context)->sourceFileName; + codeActionCommand.packageName = ""; + combinedCodeActions.commands.push_back(codeActionCommand); + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_uiPluginSuggest(G_UI_PLUGIN_SUGGEST_ID); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/rename.cpp b/ets2panda/lsp/src/rename.cpp index 453703e9411882cc0e94d47c5bb8147147d6f4f8..6ae4022b8c14b43833d44c99a011b1b6a6eb5602 100644 --- a/ets2panda/lsp/src/rename.cpp +++ b/ets2panda/lsp/src/rename.cpp @@ -17,25 +17,27 @@ #include "get_adjusted_location.h" #include "macros.h" #include "lexer/token/letters.h" +#include "compiler/lowering/util.h" #include "public/public.h" +#include "util/path.h" #include #include namespace ark::es2panda::lsp { - constexpr size_t FIRST_CHAR_INDEX = 0; constexpr size_t QUOTE_END_OFFSET = 2; constexpr size_t MIN_QUOTED_LENGTH = 2; constexpr size_t QUOTE_START_OFFSET = 1; -RenameInfoType GetRenameInfo(es2panda_Context *context, size_t pos) +RenameInfoType GetRenameInfo(es2panda_Context *context, size_t pos, const std::string &pandaLibPath) { auto ctx = reinterpret_cast(context); - auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); - auto program = reinterpret_cast(ctx)->parserProgram; + SetPhaseManager(ctx->phaseManager); + auto checker = ctx->GetChecker()->AsETSChecker(); + auto program = ctx->parserProgram; auto node = GetAdjustedLocation(GetTouchingPropertyName(context, pos), true, ctx->allocator); if (node.has_value() && NodeIsEligibleForRename(node.value())) { - auto renameInfo = GetRenameInfoForNode(node.value(), checker, program); + auto renameInfo = GetRenameInfoForNode(node.value(), checker, program, pandaLibPath); if (renameInfo.has_value()) { return renameInfo.value(); } @@ -69,25 +71,88 @@ TextSpan CreateTriggerSpanForNode(ir::AstNode *node) return span; } -std::optional GetRenameInfoForNode(ir::AstNode *node, checker::ETSChecker *checker, - parser::Program *program) +ir::AstNode *GetDeclaration(ir::AstNode *node) { - if (node->IsStringLiteral()) { - auto type = GetContextualTypeFromParentOrAncestorTypeNode(node, checker); - if (type) { - const std::string kind = "string"; - return GetRenameInfoSuccess(node->AsStringLiteral()->ToString(), node->AsStringLiteral()->ToString(), kind, - "", node); + if (node == nullptr) { + return nullptr; + } + auto var = node->Variable(); + if (var == nullptr) { + return nullptr; + } + auto decl = var->Declaration(); + if (decl == nullptr) { + return nullptr; + } + return decl->Node(); +} + +bool IsDefinedInLibraryFile(const ir::AstNode *node, const std::string &pandaLibPath) +{ + if (node == nullptr) { + return false; + } + auto filePath = node->Range().start.Program()->SourceFile().GetAbsolutePath().Utf8(); + if (filePath.find(pandaLibPath) != std::string::npos) { + return true; + } + std::string etsPath = pandaLibPath; + size_t pos = 0; + const int threeLevelsUp = 3; + for (int i = 0; i < threeLevelsUp; ++i) { + pos = etsPath.find_last_of(util::PATH_DELIMITER); + if (pos != std::string::npos) { + etsPath = etsPath.substr(0, pos); } } - if (node->IsLabelledStatement() || - (node->IsIdentifier() && (node->Parent()->IsContinueStatement() || node->Parent()->IsBreakStatement()))) { - const std::string name = GetTextOfNode(node, program); - const std::string kind = "label"; - return GetRenameInfoSuccess(name, name, kind, "", node); + // check etsPath in openharmony sdk + if (filePath.find(etsPath) != std::string::npos) { + return true; + } + std::string oh = "openharmony"; + pos = etsPath.rfind(oh); + if (pos != std::string::npos) { + etsPath.replace(pos, oh.size(), "hms"); + // check etsPath in hms sdk + if (filePath.find(etsPath) != std::string::npos) { + return true; + } } + return false; +} - if (node->IsIdentifier()) { +bool IsDefinedInOhModules(const ir::AstNode *node) +{ + if (node == nullptr) { + return false; + } + auto filePath = node->Range().start.Program()->SourceFile().GetAbsolutePath().Utf8(); + return filePath.find("oh_modules") != std::string::npos; +} + +std::optional GetRenameInfoForNode(ir::AstNode *node, checker::ETSChecker *checker, + parser::Program *program, const std::string &pandaLibPath) +{ + auto decl = GetDeclaration(node); + if (decl == nullptr) { + if (node->IsStringLiteral()) { + auto type = GetContextualTypeFromParentOrAncestorTypeNode(node, checker); + if (type) { + const std::string kind = "string"; + return GetRenameInfoSuccess(node->AsStringLiteral()->ToString(), node->AsStringLiteral()->ToString(), + kind, "", node); + } + } + if (node->IsLabelledStatement() || + (node->IsIdentifier() && (node->Parent()->IsContinueStatement() || node->Parent()->IsBreakStatement()))) { + const std::string name = GetTextOfNode(node, program); + const std::string kind = "label"; + return GetRenameInfoSuccess(name, name, kind, "", node); + } + return std::nullopt; + } + + if (IsDefinedInLibraryFile(decl, pandaLibPath) || IsDefinedInOhModules(decl)) { return std::nullopt; } @@ -95,7 +160,7 @@ std::optional GetRenameInfoForNode(ir::AstNode *node, checker::E return GetRenameInfoForModule(node, program); } - const std::string kind = GetNodeKindForRenameInfo(node); + const std::string kind = GetNodeKindForRenameInfo(decl); std::optional specifierName; if ((IsImportOrExportSpecifierName(node) || IsStringOrNumericLiteralLike(node)) && @@ -104,8 +169,13 @@ std::optional GetRenameInfoForNode(ir::AstNode *node, checker::E } else { specifierName = std::nullopt; } - const std::string displayName = specifierName.has_value() ? specifierName.value() : ""; - const std::string fullDisplayName = specifierName.has_value() ? specifierName.value() : ""; + auto name = compiler::GetNameOfDeclaration(decl); + const std::string displayName = specifierName.has_value() ? specifierName.value() + : name.has_value() ? name.value() + : ""; + const std::string fullDisplayName = specifierName.has_value() ? specifierName.value() + : name.has_value() ? name.value() + : ""; return GetRenameInfoSuccess(displayName, fullDisplayName, kind, "", node); } @@ -254,13 +324,76 @@ std::optional GetRenameInfoForModule(ir::AstNode *node, parse "", triggerSpan); } +std::string GetKindOfMethod(ir::AstNode *node) +{ + if (!node->IsMethodDefinition()) { + return ""; + } + switch (node->AsMethodDefinition()->Kind()) { + case ir::MethodDefinitionKind::METHOD: + return "method"; + case ir::MethodDefinitionKind::GET: + return "get"; + case ir::MethodDefinitionKind::SET: + return "set"; + case ir::MethodDefinitionKind::CONSTRUCTOR: + return "constructor"; + default: + return ""; + } +} + +std::string GetKindOfClassDefinition(ir::AstNode *node) +{ + if (!node->IsClassDefinition()) { + return ""; + } + if (node->AsClassDefinition()->OrigEnumDecl() != nullptr) { + return "enum"; + } + if (node->AsClassDefinition()->IsNamespaceTransformed()) { + return "namespace"; + } + if (node->AsClassDefinition()->IsFromStruct() || node->Parent()->IsETSStructDeclaration()) { + return "struct"; + } + return "class"; +} + +std::optional GetKindOfPropertyMethodFunctionOrVar(ir::AstNode *node) +{ + switch (node->Type()) { + case ir::AstNodeType::CLASS_PROPERTY: + if (compiler::ClassDefinitionIsEnumTransformed(node->Parent())) { + return "enum member"; + } + return "property"; + case ir::AstNodeType::FUNCTION_DECLARATION: + return "function"; + case ir::AstNodeType::METHOD_DEFINITION: + return GetKindOfMethod(node); + case ir::AstNodeType::VARIABLE_DECLARATION: + return "variable"; + case ir::AstNodeType::IMPORT_DECLARATION: + return "import"; + case ir::AstNodeType::CLASS_DEFINITION: + return GetKindOfClassDefinition(node); + default: + return std::nullopt; + } +} + std::string GetNodeKindForRenameInfo(ir::AstNode *node) { + auto kind = GetKindOfPropertyMethodFunctionOrVar(node); + if (kind.has_value()) { + return kind.value(); + } switch (node->Type()) { case ir::AstNodeType::TS_ENUM_DECLARATION: return "enum"; case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: - return "type"; + return "type alias"; case ir::AstNodeType::TS_INTERFACE_DECLARATION: return "interface"; case ir::AstNodeType::TS_TYPE_PARAMETER: @@ -269,6 +402,8 @@ std::string GetNodeKindForRenameInfo(ir::AstNode *node) return "enum member"; case ir::AstNodeType::TS_MODULE_DECLARATION: return "module"; + case ir::AstNodeType::ETS_PARAMETER_EXPRESSION: + return "parameter"; default: return ""; } @@ -337,12 +472,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..f31e8d5e066b6c43362707c8481fa372a02b4f0d --- /dev/null +++ b/ets2panda/lsp/src/script_element_kind.cpp @@ -0,0 +1,347 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_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); + case ir::AstNodeType::ETS_UNION_TYPE: + return std::make_tuple(true, CompletionEntryKind::TYPE_PARAMETER); + default: + break; + } + return std::make_tuple(false, CompletionEntryKind::ALIAS_TYPE); +} + +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::ALIAS_TYPE); + 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::ALIAS_TYPE; + 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; +} + +const ir::TSTypeAliasDeclaration *GetAliasDeclFromCurrentToken(const ir::AstNode *node) +{ + if (node == nullptr) { + return nullptr; + } + const ir::TSTypeAliasDeclaration *aliasDecl = nullptr; + if (node->IsTSTypeAliasDeclaration()) { + aliasDecl = node->AsTSTypeAliasDeclaration(); + } else if (node->IsIdentifier()) { + auto decl = compiler::DeclarationFromIdentifier(node->AsIdentifier()); + if (decl == nullptr) { + return nullptr; + } + aliasDecl = decl->AsTSTypeAliasDeclaration(); + } + return aliasDecl; +} + +CompletionEntryKind GetAliasScriptElementKindImpl(es2panda_Context *context, size_t position) +{ + auto touchingToken = GetTouchingToken(context, position, false); + auto aliasDecl = GetAliasDeclFromCurrentToken(touchingToken); + if (aliasDecl == nullptr) { + return CompletionEntryKind::TEXT; + } + auto typeAnnotation = aliasDecl->TypeAnnotation(); + if (typeAnnotation == nullptr) { + return CompletionEntryKind::ALIAS_TYPE; + } + if (typeAnnotation->IsETSTypeReference()) { + auto part = typeAnnotation->AsETSTypeReference()->Part()->AsETSTypeReferencePart(); + if (part == nullptr) { + return CompletionEntryKind::ALIAS_TYPE; + } + auto targetIdent = part->GetIdent(); + auto decl = compiler::DeclarationFromIdentifier(targetIdent); + if (compiler::ClassDefinitionIsEnumTransformed(decl)) { + return CompletionEntryKind::ENUM; + } + return GetTargetTokenKind(decl); + } + return GetTargetTokenKind(typeAnnotation); +} +} // 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..d647c283357aab2a81e664fca7634a6e1b61f4cd --- /dev/null +++ b/ets2panda/lsp/src/services/text_change/change_tracker.cpp @@ -0,0 +1,836 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "get_adjusted_location.h" +#include +#include +#include +#include +#include + +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; +} + +void ChangeTracker::RfindNearestKeyWordTextRange(const es2panda_Context *context, const size_t pos, + const std::string_view &keywordStr, TextRange &range) +{ + auto ctx = reinterpret_cast(const_cast(context)); + const std::string_view &sourceCode = ctx->parserProgram->SourceCode().Utf8(); + auto start = sourceCode.rfind(keywordStr, pos); + if (start == std::string_view::npos) { + return; + } + + range.pos = start; + range.end = start + keywordStr.length(); +} + +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) ? "" : newLineCharacter_; + char currentChar = pos < sourceFile->source.size() ? sourceFile->source.at(pos) : '\0'; + std::string suffix = (IsLineBreak(currentChar) ? "" : newLineCharacter_); + if (blankLineBetween) { + suffix += newLineCharacter_; + } + 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 ? newLineCharacter_ + newLineCharacter_ : newLineCharacter_; + } 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 ? newLineCharacter_ : " "); + } + return options; +} + +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) +{ + 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 ? "," : "") + newLineCharacter_; + 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), newNode, options); + } + } + + 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 = newLineCharacter_; + options.suffix = newLineCharacter_; + 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 = "," + newLineCharacter_; + 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 = newLineCharacter_; + return options; + } +} +struct StartandEndOfNode { + size_t start; + size_t end; +}; + +StartandEndOfNode GetClassOrObjectBraceEnds(ir::AstNode *node) +{ + const auto open = node->FindChild([](ir::AstNode *) { return true; })->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) { + DeleteRange(mapElem.second.sourceFile, CreateRange(braceEnds.start, braceEnds.end - 1)); + } + if (isSingleLine) { + InsertText(mapElem.second.sourceFile, braceEnds.end - 1, newLineCharacter_); + } + } +} + +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 ? "" : ("," + newLineCharacter_); + 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 = {}; + + const auto impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + const auto newNode = impl->CreateBlockStatement(context, nullptr, 0); + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + auto **stmts = + static_cast(impl->AllocMemory(context, statements.size(), sizeof(es2panda_AstNode *))); + if (stmts == nullptr) { + return; + } + for (size_t i = 0; i < statements.size(); ++i) { + stmts[i] = reinterpret_cast(statements[i]); + } + impl->BlockStatementSetStatements(context, newNode, stmts, statements.size()); + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) + + ReplaceNode(context, ctr, reinterpret_cast(newNode), options); + } +} + +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) +{ + InsertNodeAt(context, pos, modifier, options); +} + +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 == nullptr || newStatement == nullptr) { + return; + } + if (!ctr->Parent()->IsConstructor()) { + return; + } + + std::vector statements; + ir::Statement *firstStatement = nullptr; + + ctr->FindChild([&](ir::AstNode *n) { + if (n->IsStatement()) { + if (firstStatement == nullptr) { + firstStatement = n->AsStatement(); + } + statements.push_back(n->AsStatement()); + } + return false; + }); + + if (firstStatement == nullptr && statements.empty()) { + std::vector newStatements = {newStatement}; + newStatements.insert(newStatements.end(), statements.begin(), statements.end()); + ReplaceConstructorBody(context, ctr, newStatements); + } else { + // Insert the new statement before the first statement + InsertNodeBefore(context, firstStatement, newStatement); + } +} + +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 = newLineCharacter_; + options.suffix = newLineCharacter_; + 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), newNode, insertOptions); + const int indentation = 4; + size_t insertPos = 4; + while (insertPos != end && IsLineBreak(sourceFile->source.at(insertPos - 1))) { + insertPos--; + } + insertOptions.indentation = indentation; + insertOptions.prefix = newLineCharacter_; + 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; + if (containingList.size() > 1) { + multilineList = containingList[index - 1]->Start().line != containingList[index]->Start().line; + } + 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 ChangeTracker::GetTextChangesFromChanges(std::vector &changes) +{ + std::unordered_map fileChangesMap; + auto addChange = [&](const SourceFile *sourceFile, TextRange range, const std::string &newText) { + const std::string filePath = std::string(sourceFile->filePath); + TextChange c = {{range.pos, range.end - range.pos}, newText}; + + auto &fileChange = fileChangesMap[filePath]; + if (fileChange.fileName.empty()) { + fileChange.fileName = filePath; + } + fileChange.textChanges.push_back(c); + }; + + for (const auto &change : changes) { + if (const auto *textChange = std::get_if(&change)) { + addChange(textChange->sourceFile, textChange->range, textChange->text); + } else if (const auto *remove = std::get_if(&change)) { + addChange(remove->sourceFile, remove->range, ""); + } else if (const auto *replace = std::get_if(&change)) { + addChange(replace->sourceFile, replace->range, replace->node->DumpEtsSrc()); + } + } + + 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 +{ + FinishClassesWithNodesInsertedAtStart(); + auto textChangesList = GetTextChangesFromChanges(changes_); + 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..03cb954749b56aa8cc5f880ba8158193e95f8f38 --- /dev/null +++ b/ets2panda/lsp/src/signature_help.cpp @@ -0,0 +1,384 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + } + auto parent = node->Parent(); + if (parent->Type() == ir::AstNodeType::CALL_EXPRESSION || parent->Type() == ir::AstNodeType::NEW_EXPRESSION || + parent->Type() == ir::AstNodeType::MEMBER_EXPRESSION) { + if (parent->IsMemberExpression() && parent->Parent() != nullptr && parent->Parent()->IsCallExpression()) { + parent = parent->Parent(); + } + auto const invocation = parent; + + auto const argument = GetArgumentOrParameterListInfo(parent); + const auto &list = argument.GetList(); + if (!list.empty()) { + auto const argumentIndex = argument.GetArgumentIndex(); + auto const argumentCount = GetArgumentCount(parent, false); + auto const span = CreateTextSpanForNode(parent); + ArgumentListInfo argumentList; + argumentList.SetInvocation(Invocation(CallInvocation {InvocationKind::CALL, invocation})); + argumentList.SetApplicableSpan(span); + argumentList.SetArgumentIndex(argumentIndex); + argumentList.SetArgumentCount(argumentCount); + return argumentList; + } + } else if (parent->Type() == ir::AstNodeType::METHOD_DEFINITION) { + auto const info = GetContextualSignatureLocationInfo(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, parent->AsMethodDefinition()->Function()->Signature(), 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..69bc6f2950b31adeef105267a95227428679efdd --- /dev/null +++ b/ets2panda/lsp/src/signature_help_items.cpp @@ -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. + */ + +#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)); + + 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/suggestion_diagnostics.cpp b/ets2panda/lsp/src/suggestion_diagnostics.cpp index ae94deae2ec25755f8b6ded790026c46a1549fa3..9b7d54c8e69b554b92ca54dab4c026a3f404bdba 100644 --- a/ets2panda/lsp/src/suggestion_diagnostics.cpp +++ b/ets2panda/lsp/src/suggestion_diagnostics.cpp @@ -22,13 +22,13 @@ namespace ark::es2panda::lsp { -std::vector GetSuggestionDiagnosticsImpl(ir::AstNode *astNode) +std::vector GetSuggestionDiagnosticsImpl(ir::AstNode *astNode, es2panda_Context *context) { std::unordered_map visitedNestedConvertibleFunctions; std::vector diags; if (astNode != nullptr) { - Check(astNode, diags, visitedNestedConvertibleFunctions); + Check(astNode, diags, visitedNestedConvertibleFunctions, context); if (!diags.empty()) { std::sort(diags.begin(), diags.end(), [](const FileDiagnostic &d1, const FileDiagnostic &d2) { return d1.diagnostic.range_.start.line_ < d2.diagnostic.range_.start.line_; @@ -38,14 +38,18 @@ std::vector GetSuggestionDiagnosticsImpl(ir::AstNode *astNode) return diags; } -void Check(ir::AstNode *node, std::vector &diag, std::unordered_map &visitedFunc) +void Check(ir::AstNode *node, std::vector &diag, std::unordered_map &visitedFunc, + es2panda_Context *context) { if (CanBeConvertedToAsync(node)) { - AddConvertToAsyncFunctionDiagnostics(node, diag, visitedFunc); + AddConvertToAsyncFunctionDiagnostics(node, diag, visitedFunc, context); } - node->FindChild([&diag, &visitedFunc](ir::AstNode *childNode) { - Check(childNode, diag, visitedFunc); + node->FindChild([&diag, &visitedFunc, &node, &context](ir::AstNode *childNode) { + // It should only Check direct child node istead of all child and grandchild node, according to tsc + if (childNode->Parent() == node) { + Check(childNode, diag, visitedFunc, context); + } return false; }); } @@ -60,16 +64,21 @@ bool CheckGivenTypeExistInChilds(ir::AstNode *node, ir::AstNodeType type) } void AddConvertToAsyncFunctionDiagnostics(ir::AstNode *node, std::vector &diag, - std::unordered_map &visitedFunc) + std::unordered_map &visitedFunc, es2panda_Context *context) { if (IsConvertibleFunction(node, visitedFunc) && (visitedFunc.count(GetKeyFromNode(node)) == 0)) { - Position posStart(node->Range().start.line, node->Range().start.index); - Position posEnd(node->Range().end.line, node->Range().end.index); + auto ctx = reinterpret_cast(context); + // The line and col should start from 1 istead of 0 + auto index = lexer::LineIndex(ctx->parserProgram->SourceCode()); + auto sourceStartLocation = index.GetLocation(node->Range().start); + auto sourceEndLocation = index.GetLocation(node->Range().end); + Position posStart(sourceStartLocation.line, sourceStartLocation.col); + Position posEnd(sourceEndLocation.line, sourceEndLocation.col); Range range(posStart, posEnd); const std::string message = "This_may_be_converted_to_an_async_function"; Diagnostic diagnostic(range, {}, {}, DiagnosticSeverity::Hint, 0, message, {}, {}, {}); - diag.push_back(lsp::CreateDiagnosticForNode(reinterpret_cast(node), diagnostic)); + diag.push_back(lsp::CreateDiagnosticForNode(reinterpret_cast(node), diagnostic, context)); } } 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/ASparser.cpp b/ets2panda/parser/ASparser.cpp index b7dbd5b0f1e16b003c6b7fb9e8d1a80cb53ac7c9..2e0e102951fd5e5354e778737b6ed345fbad31bc 100644 --- a/ets2panda/parser/ASparser.cpp +++ b/ets2panda/parser/ASparser.cpp @@ -95,6 +95,7 @@ ir::Decorator *ASParser::ParseDecorator() auto *expr = ParseLeftHandSideExpression(); auto *decorator = AllocNode(expr); + ES2PANDA_ASSERT(decorator != nullptr); decorator->SetRange({start, expr->End()}); return decorator; } @@ -124,6 +125,7 @@ ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration() const util::StringView &ident = Lexer()->GetToken().Ident(); auto *id = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -343,6 +345,7 @@ std::tuple ASParser::ParsePatternElementToken(E } case lexer::TokenType::LITERAL_IDENT: { returnNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(returnNode != nullptr); returnNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -430,6 +433,7 @@ ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionPar key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -446,6 +450,7 @@ ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionPar } auto *property = AllocNode(key, value); + ES2PANDA_ASSERT(property != nullptr); property->SetRange({key->Start(), value->End()}); return property; } @@ -570,8 +575,10 @@ ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError) ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options) { auto *typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); + ES2PANDA_ASSERT(type != nullptr); type->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -584,6 +591,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type } typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); auto *next = AllocNode(typeName, Allocator()); current->SetRange(Lexer()->GetToken().Loc()); @@ -646,8 +654,10 @@ ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throw } auto *typeName = AllocNode(name, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); + ES2PANDA_ASSERT(type != nullptr); type->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return type; @@ -717,6 +727,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode * util::StringView name = "Array"; auto *typeName = AllocNode(name, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); ArenaVector params(Allocator()->Adapter()); @@ -768,6 +779,8 @@ bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression } *returnExpression = AllocNode(*returnExpression); + ES2PANDA_ASSERT(*returnExpression != nullptr); + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); Lexer()->NextToken(); return false; @@ -814,6 +827,7 @@ bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir lexer::SourcePosition endLoc = propertyNode->End(); *returnExpression = AllocNode(*returnExpression, propertyNode, typeParams); + ES2PANDA_ASSERT(returnExpression != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, endLoc}); return false; @@ -845,6 +859,7 @@ ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpr ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -865,6 +880,7 @@ bool ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadEle return true; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ArenaVector ASParser::ParseInterfaceExtendsClause() { Lexer()->NextToken(); // eat extends keyword @@ -876,8 +892,10 @@ ArenaVector ASParser::ParseInterfaceExtendsClause() const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start(); lexer::SourcePosition heritageEnd = Lexer()->GetToken().End(); auto *extendsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(extendsName != nullptr); extendsName->SetRange(Lexer()->GetToken().Loc()); auto *extendsClause = AllocNode(extendsName, Allocator()); + ES2PANDA_ASSERT(extendsClause != nullptr); extendsClause->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -942,6 +960,7 @@ ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition } auto *key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat key @@ -991,12 +1010,14 @@ std::tuple ASParser::ParseInterfacePropertyKey() case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = Lexer()->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = Lexer()->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1007,6 +1028,7 @@ std::tuple ASParser::ParseInterfacePropertyKey() key = AllocNode(Lexer()->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1100,8 +1122,10 @@ ArenaVector ASParser::ParseClassImplementClause() const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start(); auto *implementsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(implementsName != nullptr); implementsName->SetRange(Lexer()->GetToken().Loc()); auto *implementsClause = AllocNode(implementsName, Allocator()); + ES2PANDA_ASSERT(implementsClause != nullptr); implementsClause->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1114,6 +1138,7 @@ ArenaVector ASParser::ParseClassImplementClause() } implementsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(implementsName != nullptr); implementsName->SetRange(Lexer()->GetToken().Loc()); auto *next = AllocNode(implementsName, Allocator()); current->SetRange(Lexer()->GetToken().Loc()); @@ -1134,6 +1159,7 @@ ArenaVector ASParser::ParseClassImplementClause() } auto *impl = AllocNode(current, implTypeParams); + ES2PANDA_ASSERT(impl != nullptr); impl->SetRange({implementStart, Lexer()->GetToken().End()}); implements.push_back(impl); @@ -1280,6 +1306,7 @@ std::tuple ASParser::ParseComputedClassFieldOrIndexSignature(i } auto id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat param @@ -1345,6 +1372,7 @@ std::tuple ASParser::Pa ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); } else { body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); endLoc = body->End(); } @@ -1357,6 +1385,7 @@ ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector *s Lexer()->NextToken(); // eat local name auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); @@ -1502,6 +1531,7 @@ ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl != nullptr); variableDecl->SetStart(constVarStar); ConsumeSemicolon(variableDecl); @@ -1518,6 +1548,7 @@ ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFla const util::StringView &identStr = Lexer()->GetToken().Ident(); auto init = AllocNode(identStr, Allocator()); + ES2PANDA_ASSERT(init != nullptr); init->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1591,6 +1622,7 @@ ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexe lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -1665,6 +1697,7 @@ ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, decl->End()}); return exportDeclaration; @@ -1709,8 +1742,10 @@ ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsin source = ParseFromClause(false); } + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); diff --git a/ets2panda/parser/ETSFormattedParser.cpp b/ets2panda/parser/ETSFormattedParser.cpp index 24cfaaa2374dda211674b810f7ffa9f432863a21..b999b9a7bf24de8f8993f6da689f07514d89d84a 100644 --- a/ets2panda/parser/ETSFormattedParser.cpp +++ b/ets2panda/parser/ETSFormattedParser.cpp @@ -106,14 +106,13 @@ ir::TypeNode *ETSParser::ParseTypeFormatPlaceholder(std::optionalGetToken().Start()); - ES2PANDA_UNREACHABLE(); + LogUnexpectedToken(lexer::TokenType::PUNCTUATOR_FORMAT); + return AllocBrokenType(Lexer()->GetToken().Loc()); } nodeFormat = GetFormatPlaceholderType(); if (std::get<0>(*nodeFormat) || std::get<1>(*nodeFormat) != TYPE_FORMAT_NODE) { - LogError(diagnostic::INVALID_NODE_TYPE, {}, Lexer()->GetToken().Start()); - ES2PANDA_UNREACHABLE(); + return nullptr; } } @@ -135,7 +134,7 @@ ir::Identifier *ETSParser::ParseIdentifierFormatPlaceholder(std::optionalGetToken().Start()); - return nullptr; + return AllocBrokenExpression(Lexer()->GetToken().Loc()); } nodeFormat = GetFormatPlaceholderType(); @@ -162,7 +161,7 @@ ir::Statement *ETSParser::ParseStatementFormatPlaceholder() { if (insertingNodes_.empty()) { LogError(diagnostic::INSERT_NODE_ABSENT, {}, Lexer()->GetToken().Start()); - ES2PANDA_UNREACHABLE(); + return AllocBrokenStatement(Lexer()->GetToken().Start()); } ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); @@ -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(); @@ -303,6 +301,7 @@ ir::Statement *ETSParser::CreateStatement(std::string_view const sourceCode) } auto *const blockStmt = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockStmt != nullptr); blockStmt->SetRange({startLoc, lexer->GetToken().End()}); for (auto *statement : blockStmt->Statements()) { @@ -333,6 +332,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,10 +375,11 @@ 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); + ES2PANDA_ASSERT(property != nullptr); if (!property->IsTSInterfaceBody() || property->AsTSInterfaceBody()->Body().empty()) { LogError(diagnostic::INVALID_CLASS_FIELD, {}, Lexer()->GetToken().Start()); ES2PANDA_UNREACHABLE(); @@ -373,10 +392,11 @@ 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); + ES2PANDA_ASSERT(property != nullptr); if (!property->IsMethodDefinition()) { LogError(diagnostic::INVALID_CLASS_METHOD, {}, Lexer()->GetToken().Start()); ES2PANDA_UNREACHABLE(); @@ -462,7 +482,7 @@ ir::Statement *ETSParser::CreateClassDeclaration(std::string_view sourceCode, bo } default: { LogUnexpectedToken(Lexer()->GetToken()); - return nullptr; + return AllocBrokenStatement(lexer->GetToken().Start()); } } } @@ -495,6 +515,7 @@ ir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags m Lexer()->NextToken(); auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers, true); + ES2PANDA_ASSERT(methodDefinition != nullptr); methodDefinition->SetStart(startLoc); return methodDefinition; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 5364fc13dae34abefd15139dc79a7d0cab7751bd..e4b25915ea843bfd0b9febf3a5945ebebd39ad08 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" @@ -97,6 +99,11 @@ bool ETSParser::IsETSParser() const noexcept return true; } +bool ETSParser::IsValidIdentifierName(const lexer::Token &token) const noexcept +{ + return !token.IsPredefinedType() || util::Helpers::IsStdLib(GetProgram()); +} + std::unique_ptr ETSParser::InitLexer(const SourceFile &sourceFile) { GetProgram()->SetSource(sourceFile); @@ -117,24 +124,48 @@ void ETSParser::ParseProgram(ScriptKind kind) } ArenaVector statements(Allocator()->Adapter()); + ParseFileHeaderFlag(startLoc, &statements); auto decl = ParsePackageDeclaration(); if (decl != nullptr) { 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; + } +#ifndef ENABLE_ISOLATED_DECLGEN AddExternalSource(ParseSources(true)); +#endif GetProgram()->SetAst(script); } +void ETSParser::ParseFileHeaderFlag(lexer::SourcePosition startLoc, ArenaVector *statements) +{ + if (Lexer()->GetToken().KeywordType() != lexer::TokenType::LITERAL_STRING || + Lexer()->GetToken().String() != compiler::Signatures::STATIC_PROGRAM_FLAG) { + return; + } + + ir::Expression *fileHeaderFlag = ParseStringLiteral(); + auto *exprStatementNode = AllocNode(fileHeaderFlag); + ES2PANDA_ASSERT(exprStatementNode != nullptr); + exprStatementNode->SetRange({startLoc, fileHeaderFlag->End()}); + ConsumeSemicolon(exprStatementNode); + if (statements != nullptr) { + statements->push_back(exprStatementNode); + } +} + ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, ArenaVector &statements) { ETSNolintParser etsnolintParser(this); @@ -143,19 +174,24 @@ ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A auto imports = ParseImportDeclarations(); statements.insert(statements.end(), imports.begin(), imports.end()); + auto initModules = ParseETSInitModuleStatements(); + statements.insert(statements.end(), initModules.begin(), initModules.end()); + auto topLevelStatements = ParseTopLevelDeclaration(); statements.insert(statements.end(), topLevelStatements.begin(), topLevelStatements.end()); etsnolintParser.ApplyETSNolintsToStatements(statements); auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); - auto *etsModule = - AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, + GetContext().GetLanguage(), GetProgram()); + ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; } -ir::ETSModule *ETSParser::ParseImportsOnly(lexer::SourcePosition startLoc, ArenaVector &statements) +ir::ETSModule *ETSParser::ParseImportsAndReExportOnly(lexer::SourcePosition startLoc, + ArenaVector &statements) { ETSNolintParser etsnolintParser(this); etsnolintParser.CollectETSNolints(); @@ -165,12 +201,29 @@ ir::ETSModule *ETSParser::ParseImportsOnly(lexer::SourcePosition startLoc, Arena etsnolintParser.ApplyETSNolintsToStatements(statements); auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); - auto *etsModule = - AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, + GetContext().GetLanguage(), GetProgram()); + ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; } +bool ETSParser::CheckDupAndReplace(Program *&oldProg, Program *newProg) const +{ + if (oldProg->FileName() == newProg->FileName() && + oldProg->FileNameWithExtension() != newProg->FileNameWithExtension()) { + bool oldIsDeclare = oldProg->FileNameWithExtension().Length() > newProg->FileNameWithExtension().Length(); + if (oldIsDeclare) { + Context()->dupPrograms.emplace(oldProg->AbsoluteName(), newProg); + oldProg = newProg; + } else { + Context()->dupPrograms.emplace(newProg->AbsoluteName(), oldProg); + } + return true; + } + return false; +} + void ETSParser::AddExternalSource(const std::vector &programs) { auto &extSources = globalProgram_->ExternalSources(); @@ -180,8 +233,21 @@ 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; + auto &extProgs = extSources.at(name); + for (auto &prog : extProgs) { + if (prog->SourceFilePath() == newProg->SourceFilePath()) { + found = true; + break; + } + if (CheckDupAndReplace(prog, newProg)) { + found = true; + break; + } + } + if (!found) { + extSources.at(name).emplace_back(newProg); + } } } @@ -198,7 +264,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; } @@ -211,11 +292,17 @@ void ETSParser::AddDirectImportsToDirectExternalSources( return; } - const util::StringView name = newProg->Ast()->Statements().empty() ? newProg->FileName() : newProg->ModuleName(); + auto name = newProg->ModuleName(); if (GetProgram()->DirectExternalSources().count(name) == 0) { GetProgram()->DirectExternalSources().try_emplace(name, Allocator()->Adapter()); } - GetProgram()->DirectExternalSources().at(name).emplace_back(newProg); + auto &dirExternal = GetProgram()->DirectExternalSources().at(name); + for (auto &prog : dirExternal) { + if (CheckDupAndReplace(prog, newProg)) { + return; + } + } + dirExternal.emplace_back(newProg); } void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo &parseListElem, util::UString *extSrc, @@ -224,8 +311,10 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & { const auto &importData = parseListElem.importData; auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; + ES2PANDA_ASSERT(extSrc != nullptr); SourceFile sf {src, extSrc->View().Utf8(), importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; parser::Program *newProg = ParseSource(sf); + ES2PANDA_ASSERT(newProg != nullptr); if (!importData.IsImplicitPackageImported() || newProg->IsPackage()) { AddDirectImportsToDirectExternalSources(directImportsFromMainSource, newProg); // don't insert the separate modules into the programs, when we collect implicit package imports @@ -233,34 +322,75 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & } } -std::vector ETSParser::ParseSources(bool firstSource) +void ETSParser::AddGenExtenralSourceToParseList(public_lib::Context *ctx) { - std::vector programs; + auto allocator = ctx->allocator; + auto ident = allocator->New(compiler::Signatures::ETS_GLOBAL, allocator); + ArenaVector stmts(allocator->Adapter()); - auto &parseList = importPathManager_->ParseList(); - - ArenaVector directImportsFromMainSource(Allocator()->Adapter()); + auto etsModule = + allocator->New(allocator, std::move(stmts), ident, ir::ModuleFlag::ETSSCRIPT, + ctx->parser->AsETSParser()->GetContext().GetLanguage(), ctx->parserProgram); + ctx->parserProgram->SetAst(etsModule); + for (auto &sourceName : ctx->sourceFileNames) { + util::ImportPathManager::ImportMetadata importData {util::ImportFlags::NONE}; + importData.resolvedSource = sourceName; + 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)); +} - if (firstSource) { - for (auto pl : parseList) { - if (pl.isParsed) { - // Handle excluded files, which are already set to be parsed before parsing them - continue; +static bool SearchImportedExternalSources(ETSParser *parser, const std::string_view &path) +{ + 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; } - directImportsFromMainSource.emplace_back(pl.importData.resolvedSource); } } + return false; +} + +bool ETSParser::TryMergeFromCache(size_t idx, ArenaVector &parseList) +{ + if (Context()->globalContext == nullptr) { + return false; + } + + 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 +399,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); @@ -281,37 +416,60 @@ std::vector ETSParser::ParseSources(bool firstSource) return programs; } - util::DiagnosticMessageParams diagParams = {std::string(parseCandidate)}; - std::ifstream inputStream {std::string(parseCandidate)}; + std::string parseCandidateStr {parseCandidate}; + util::DiagnosticMessageParams diagParams = {parseCandidateStr}; + std::ifstream inputStream {parseCandidateStr}; if (!inputStream) { DiagnosticEngine().LogDiagnostic(diagnostic::OPEN_FAILED, diagParams); return programs; // Error processing. } - std::stringstream ss; ss << inputStream.rdbuf(); - std::string externalSource = ss.str(); + std::string externalSource; + if (data.IsExternalBinaryImport()) { + externalSource = data.declText; + } else { + 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); auto *program = Allocator()->New(Allocator(), GetProgram()->VarBinder()); + ES2PANDA_ASSERT(program != nullptr); auto esp = ExternalSourceParser(this, program); auto lexer = InitLexer(sourceFile); @@ -319,11 +477,22 @@ parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) Lexer()->NextToken(); ArenaVector statements(Allocator()->Adapter()); + ParseFileHeaderFlag(startLoc, nullptr); auto decl = ParsePackageDeclaration(); + ir::ETSModule *script = nullptr; if (decl != nullptr) { statements.emplace_back(decl); + if (Context()->config->options->GetCompilationMode() == CompilationMode::GEN_ABC_FOR_EXTERNAL_SOURCE) { + importPathManager_->AddImplicitPackageImportToParseList(program->SourceFile().GetAbsoluteParentFolder(), + Lexer()->GetToken().Start()); + importPathManager_->MarkAsParsed(program->AbsoluteName()); + } + 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; } @@ -394,6 +563,11 @@ ir::ScriptFunction *ETSParser::ParseFunction(ParserStatus newStatus) LogError(diagnostic::ASYNC_IN_AMBIENT_CONTEXT); } + if (isDeclare && signature.ReturnType() != nullptr) { + // Note: if the return type annotation is null, the error handler will set later. + endLoc = signature.ReturnType()->Range().end; + } + // clang-format off ir::ModifierFlags mFlags = isDeclare ? ir::ModifierFlags::DECLARE : ir::ModifierFlags::NONE; ir::ScriptFunctionFlags funcFlags = @@ -401,6 +575,7 @@ ir::ScriptFunction *ETSParser::ParseFunction(ParserStatus newStatus) auto *funcNode = AllocNode( Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(signature), funcFlags, mFlags, GetContext().GetLanguage()}); + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({startLoc, endLoc}); // clang-format on @@ -418,29 +593,11 @@ std::tuple ETSParser::P } ir::BlockStatement *body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); return {true, body, body->End(), false}; } -ir::ScriptFunctionFlags ETSParser::ParseFunctionThrowMarker(bool isRethrowsAllowed) -{ - ir::ScriptFunctionFlags throwMarker = ir::ScriptFunctionFlags::NONE; - - if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { - if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_THROWS)) { - throwMarker = ir::ScriptFunctionFlags::THROWS; - } else if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_RETHROWS)) { - if (isRethrowsAllowed) { - throwMarker = ir::ScriptFunctionFlags::RETHROWS; - } else { - LogError(diagnostic::ONLY_THROWS_IN_FUN_TYPE); - } - } - } - - return throwMarker; -} - ir::AstNode *ETSParser::ParseInnerTypeDeclaration(ir::ModifierFlags memberModifiers, lexer::LexerPosition savedPos, bool isStepToken, bool seenStatic) { @@ -456,6 +613,9 @@ ir::AstNode *ETSParser::ParseInnerTypeDeclaration(ir::ModifierFlags memberModifi Lexer()->GetToken().SetTokenType(Lexer()->GetToken().KeywordType()); ir::AstNode *typeDecl = ParseTypeDeclaration(true); + if (typeDecl == nullptr) { + return nullptr; + } memberModifiers &= (ir::ModifierFlags::PUBLIC | ir::ModifierFlags::PROTECTED | ir::ModifierFlags::PRIVATE | ir::ModifierFlags::INTERNAL); typeDecl->AddModifier(memberModifiers); @@ -478,10 +638,17 @@ ir::AstNode *ETSParser::ParseInnerConstructorDeclaration(ir::ModifierFlags membe 0) { LogError(diagnostic::INVALID_DECORATOR_CONSTRUCTOR); } - auto *memberName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + + lexer::Token constructorToken = Lexer()->GetToken(); + Lexer()->TryEatTokenType(lexer::TokenType::KEYW_CONSTRUCTOR); memberModifiers |= ir::ModifierFlags::CONSTRUCTOR; - Lexer()->NextToken(); + + ir::Identifier *memberName = Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT + ? ExpectIdentifier(false, true) + : AllocNode(constructorToken.Ident(), Allocator()); + auto *classMethod = ParseClassMethodDefinition(memberName, memberModifiers, isDefault); + ES2PANDA_ASSERT(classMethod != nullptr); classMethod->SetStart(startLoc); return classMethod; @@ -491,6 +658,7 @@ ir::Identifier *ETSParser::CreateInvokeIdentifier() { util::StringView tokenName = util::StringView {compiler::Signatures::STATIC_INVOKE_METHOD}; auto ident = AllocNode(tokenName, Allocator()); + ES2PANDA_ASSERT(ident != nullptr); ident->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); return ident; } @@ -501,14 +669,22 @@ 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, @@ -519,34 +695,45 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert 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, isDefault, this](ir::Identifier *methodName) { + auto parseClassMethod = [&memberModifiers, isDefault, this](ir::Identifier *methodName) { auto *classMethod = ParseClassMethodDefinition(methodName, memberModifiers, isDefault); - classMethod->SetStart(startLoc); + ES2PANDA_ASSERT(classMethod != nullptr); + classMethod->SetStart(methodName->Start()); return classMethod; }; if (InAmbientContext()) { - auto *property = HandleAmbientDeclaration(memberModifiers, parseClassMethod); - if (property != nullptr) { + if (auto *property = HandleAmbientDeclaration(memberModifiers, parseClassMethod); property != nullptr) { return property; } } + if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_OVERLOAD)) { + auto *classOverload = ParseClassOverloadDeclaration(memberModifiers); + classOverload->SetStart(startLoc); + return classOverload; + } + auto *memberName = ExpectIdentifier(false, false, TypeAnnotationParsingOptions::NO_OPTS); // don't report error - if (memberName == nullptr) { // log error here + if (memberName == nullptr) { + auto tokenType = Lexer()->GetToken().Type(); + if (Lexer()->TryEatTokenType(lexer::TokenType::KEYW_NEW) || + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + LogError(diagnostic::CALL_SIG_IN_OBJECT, + {tokenType == lexer::TokenType::KEYW_NEW ? "Constructor" : "Call"}); + auto *ident = AllocNode("dummy", Allocator()); + parseClassMethod(ident); + return AllocBrokenStatement(Lexer()->GetToken().Loc()); + } // log error here LogUnexpectedToken(Lexer()->GetToken()); const auto &rangeToken = Lexer()->GetToken().Loc(); Lexer()->NextToken(); return AllocBrokenStatement(rangeToken); } + if (memberName->IsErrorPlaceHolder()) { + return AllocBrokenStatement(startLoc); + } + ThrowOptionalMethodErrorIfNeeded(); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { @@ -555,6 +742,7 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert ArenaVector fieldDeclarations(Allocator()->Adapter()); auto *placeholder = AllocNode(std::move(fieldDeclarations)); + ES2PANDA_ASSERT(placeholder != nullptr); ParseClassFieldDefinition(memberName, memberModifiers, placeholder->BodyPtr(), isDefault); return placeholder; } @@ -575,7 +763,7 @@ ir::Statement *ETSParser::ParseTypeDeclarationAbstractFinal(bool allowStatic, ir } LogUnexpectedToken(Lexer()->GetToken()); - return nullptr; + return AllocBrokenStatement(Lexer()->GetToken().Loc()); } ir::Statement *ETSParser::ParseTypeDeclaration(bool allowStatic) @@ -631,9 +819,15 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() { ES2PANDA_ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE); + const auto start = Lexer()->Save(); lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat type keyword + 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())}); } @@ -641,6 +835,7 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() ir::Identifier *id = ExpectIdentifier(); auto *typeAliasDecl = AllocNode(Allocator(), id); + ES2PANDA_ASSERT(typeAliasDecl != nullptr); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { auto options = @@ -652,54 +847,25 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() ExpectToken(lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; + if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_NEW)) { + LogError(diagnostic::CONSTRUCTOR_FUNC_TYPE_NOT_SUPPORTED, {}, typeStart); + typeAliasDecl->SetTsTypeAnnotation(AllocBrokenType(typeStart)); + } + + TypeAnnotationParsingOptions options = + TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::TYPE_ALIAS_CONTEXT; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); if (typeAnnotation == nullptr) { return nullptr; } - typeAliasDecl->SetTsTypeAnnotation(typeAnnotation); + if (typeAliasDecl->TypeAnnotation() == nullptr) { + typeAliasDecl->SetTsTypeAnnotation(typeAnnotation); + } typeAnnotation->SetParent(typeAliasDecl); typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()}); return typeAliasDecl; } -std::pair ETSParser::CheckDefaultParameters(const ir::ScriptFunction *const function) -{ - bool hasOptionalParameters = false; - bool hasRestParameter = false; - std::size_t requiredParametersNumber = 0U; - - for (auto *const it : function->Params()) { - auto const *const param = it->AsETSParameterExpression(); - - if (param->IsRestParameter()) { - hasRestParameter = true; - continue; - } - - if (hasRestParameter) { - LogError(diagnostic::REST_PARAM_LAST, {}, param->Start()); - } - - if (param->IsOptional()) { - hasOptionalParameters = true; - continue; - } - - if (hasOptionalParameters) { - LogError(diagnostic::REQUIRED_PARAM_AFTER_DEFAULT, {}, param->Start()); - } - - ++requiredParametersNumber; - } - - if (hasOptionalParameters && hasRestParameter) { - LogError(diagnostic::REST_AND_DEFAULT_SAME_TIME, {}, function->Start()); - } - - return std::make_pair(hasOptionalParameters, requiredParametersNumber); -} - std::string ETSParser::PrimitiveTypeToName(ir::PrimitiveType type) const { switch (type) { @@ -859,10 +1025,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}; @@ -880,10 +1045,23 @@ ir::TypeNode *ETSParser::ParseTypeReference(TypeAnnotationParsingOptions *option while (true) { auto partPos = Lexer()->GetToken().Start(); auto [typeName, typeParams] = ParseTypeReferencePart(options); + if (typeName == nullptr) { + typeName = AllocBrokenExpression(partPos); + } + typeRefPart = AllocNode(typeName, typeParams, typeRefPart, Allocator()); - typeRefPart->SetRange({partPos, Lexer()->GetToken().End()}); + ES2PANDA_ASSERT(typeRefPart != nullptr); + auto endPos = typeParams == nullptr ? typeName->End() : typeParams->End(); + typeRefPart->SetRange({partPos, endPos}); if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_PERIOD)) { + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IS) { + auto isPos = Lexer()->GetToken().Start(); + Lexer()->NextToken(); // eat 'is' + Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT); + LogError(diagnostic::ERROR_ARKTS_NO_IS_OPERATOR, {}, isPos); + return AllocBrokenType({partPos, Lexer()->GetToken().End()}); + } break; } @@ -894,7 +1072,8 @@ ir::TypeNode *ETSParser::ParseTypeReference(TypeAnnotationParsingOptions *option } auto *typeReference = AllocNode(typeRefPart, Allocator()); - typeReference->SetRange({startPos, Lexer()->GetToken().End()}); + ES2PANDA_ASSERT(typeReference != nullptr); + typeReference->SetRange({startPos, typeRefPart->End()}); return typeReference; } @@ -924,12 +1103,14 @@ ir::TypeNode *ETSParser::ParseBaseTypeReference(TypeAnnotationParsingOptions *op ir::TypeNode *ETSParser::ParseLiteralIdent(TypeAnnotationParsingOptions *options) { - if (Lexer()->GetToken().IsDefinableTypeName()) { + if (Lexer()->GetToken().IsPredefinedType()) { return GetTypeAnnotationOfPrimitiveType(Lexer()->GetToken().KeywordType(), options); } if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_KEYOF)) { - auto *typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + auto keyofOptions = *options | TypeAnnotationParsingOptions::REPORT_ERROR; + auto *typeAnnotation = ParseTypeAnnotationNoPreferParam(&keyofOptions); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation = AllocNode(typeAnnotation, Allocator()); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); return typeAnnotation; @@ -956,35 +1137,90 @@ 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::CreateReExportDeclarationNode(ir::ETSImportDeclaration *reExportDeclaration, + const lexer::SourcePosition &startLoc, + const ir::ModifierFlags &modifiers) +{ + if (GetProgram()->AbsoluteName().Is(reExportDeclaration->ResolvedSource())) { + LogError(diagnostic::RE_EXPORTING_LOCAL_BINDINGS_IS_NOT_ALLOWED, {}, startLoc); + return AllocBrokenStatement(startLoc); + } + auto reExport = AllocNode(reExportDeclaration, std::vector(), + GetProgram()->AbsoluteName(), Allocator()); + ES2PANDA_ASSERT(reExport != nullptr); + reExport->AddModifier(modifiers); + reExport->SetRange(reExportDeclaration->Range()); + return reExport; +} + +ir::Statement *ETSParser::ParseDefaultIfSingleExport(ir::ModifierFlags modifiers) +{ + auto tokenType = Lexer()->GetToken().Type(); + if (tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + return ParseSingleExport(modifiers); } + auto savePos = Lexer()->Save(); + Lexer()->NextToken(); + auto isSelectiveExport = Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT) && + (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || + Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS || + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); + Lexer()->Rewind(savePos); + return !isSelectiveExport ? ParseSingleExport(modifiers) : nullptr; } 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); + // export a constant variable anonymously, as export default new A() + if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MULTIPLY && + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + auto exportedExpression = ParseDefaultIfSingleExport(modifiers); + if (exportedExpression != nullptr) { + return exportedExpression; + } + } + 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) { + auto endLoc = startLoc; + for (auto spec : specs.result) { exports.emplace_back(AllocNode(spec->Local(), spec->Imported())); + endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; + } + + if (specs.resultExportDefault.size() > exportDefaultMaxSize) { + LogError(diagnostic::EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER); } + for (auto spec : specs.resultExportDefault) { + exports.emplace_back(spec); + endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; + } + auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); + ES2PANDA_ASSERT(result != nullptr); result->AddModifier(modifiers); + result->SetRange({startLoc, endLoc}); return result; } } else { @@ -995,10 +1231,7 @@ ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::Modifi } // re-export directive auto *reExportDeclaration = ParseImportPathBuildImport(std::move(specifiers), true, startLoc, ir::ImportKinds::ALL); - auto reExport = AllocNode(reExportDeclaration, std::vector(), - GetProgram()->AbsoluteName(), Allocator()); - reExport->AddModifier(modifiers); - return reExport; + return CreateReExportDeclarationNode(reExportDeclaration, startLoc, modifiers); } ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() @@ -1016,6 +1249,7 @@ ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() ir::Expression *name = ParseQualifiedName(); auto *packageDeclaration = AllocNode(name); + ES2PANDA_ASSERT(packageDeclaration != nullptr); packageDeclaration->SetRange({startLoc, Lexer()->GetToken().End()}); ConsumeSemicolon(packageDeclaration); @@ -1040,9 +1274,11 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVector(ERROR_LITERAL); + ES2PANDA_ASSERT(errorLiteral != nullptr); errorLiteral->SetRange(Lexer()->GetToken().Loc()); auto *const importDeclaration = AllocNode( errorLiteral, util::ImportPathManager::ImportMetadata {}, std::move(specifiers), importKind); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, errorLiteral->End()}); return importDeclaration; } @@ -1050,22 +1286,43 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVectorGetToken().Type() == lexer::TokenType::LITERAL_STRING); auto pathToResolve = Lexer()->GetToken().Ident(); auto *importPathStringLiteral = AllocNode(pathToResolve); + ES2PANDA_ASSERT(importPathStringLiteral != nullptr); importPathStringLiteral->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); - auto *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); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, importPathStringLiteral->End()}); + if (Lexer()->GetToken().Ident().Is("assert")) { + LogError(diagnostic::ERROR_ARKTS_NO_IMPORT_ASSERTIONS); + return importDeclaration; + } ConsumeSemicolon(importDeclaration); return importDeclaration; } ir::ETSImportDeclaration *ETSParser::BuildImportDeclaration(ir::ImportKinds importKind, ArenaVector &&specifiers, - ir::StringLiteral *pathToResolve) + ir::StringLiteral *pathToResolve, parser::Program *program, + util::ImportFlags importFlag) { - ES2PANDA_ASSERT(GetProgram() == GetContext().GetProgram()); - return AllocNode(pathToResolve, - importPathManager_->GatherImportMetadata(GetContext(), pathToResolve), - std::move(specifiers), importKind); + return AllocNode( + pathToResolve, importPathManager_->GatherImportMetadata(program, importFlag, pathToResolve), + std::move(specifiers), importKind); +} + +ArenaVector ETSParser::ParseETSInitModuleStatements() +{ + std::vector userPaths; + ArenaVector statements(Allocator()->Adapter()); + while (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INIT_MODULE) { + statements.push_back(ParseInitModuleStatement(StatementParsingFlags::INIT_MODULE)); + } + return statements; } ArenaVector ETSParser::ParseImportDeclarations() @@ -1084,20 +1341,18 @@ ArenaVector ETSParser::ParseImportDeclarations() ArenaVector defaultSpecifiers(Allocator()->Adapter()); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { - if (importKind == ir::ImportKinds::TYPES) { - LogError(diagnostic::TYPE_IMPORT_MISSING_SELECTIVE_BINDING); - } 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); } auto pos = Lexer()->Save(); if (!specifiers.empty()) { auto *const importDecl = ParseImportPathBuildImport(std::move(specifiers), true, startLoc, importKind); + ES2PANDA_ASSERT(importDecl != nullptr); statements.push_back(importDecl->AsETSImportDeclaration()); } @@ -1105,6 +1360,7 @@ ArenaVector ETSParser::ParseImportDeclarations() Lexer()->Rewind(pos); auto *const importDeclDefault = ParseImportPathBuildImport(std::move(defaultSpecifiers), true, startLoc, importKind); + ES2PANDA_ASSERT(importDeclDefault != nullptr); if (!importDeclDefault->IsBrokenStatement()) { util::Helpers::CheckDefaultImport(statements); statements.push_back(importDeclDefault->AsETSImportDeclaration()); @@ -1118,10 +1374,46 @@ ArenaVector ETSParser::ParseImportDeclarations() return statements; } +ir::ExportNamedDeclaration *ETSParser::ParseSingleExportForAnonymousConst(ir::ModifierFlags modifiers) +{ + ir::Expression *constantExpression = ParseExpression(); + + auto *exported = AllocNode(compiler::Signatures::EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY, Allocator()); + ES2PANDA_ASSERT(exported != nullptr); + exported->SetRange(Lexer()->GetToken().Loc()); + + ArenaVector exports(Allocator()->Adapter()); + 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)); + ES2PANDA_ASSERT(result != nullptr); + 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.KeywordType() == lexer::TokenType::KEYW_AS) { + LogError(diagnostic::ERROR_ARKTS_NO_UMD, {}, token.Start()); + return nullptr; + } + if (token.Type() != lexer::TokenType::LITERAL_IDENT) { + LogError(diagnostic::EXPORT_NON_DECLARATION, {}, token.Start()); + return nullptr; + } auto *exported = AllocNode(token.Ident(), Allocator()); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat exported variable name @@ -1129,8 +1421,11 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExport(ir::ModifierFlags modif ArenaVector exports(Allocator()->Adapter()); exports.emplace_back(AllocNode(exported, ParseNamedExport(&token))); + exports.back()->SetRange(exported->Range()); auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); + result->SetRange(exported->Range()); + ES2PANDA_ASSERT(result != nullptr); result->AddModifier(modifiers); ConsumeSemicolon(result); @@ -1161,6 +1456,7 @@ bool TypedParser::IsPrimitiveType(const lexer::TokenType &tokenType) case lexer::TokenType::KEYW_LONG: case lexer::TokenType::KEYW_SHORT: case lexer::TokenType::KEYW_VOID: + case lexer::TokenType::KEYW_ANY: return true; default: return false; @@ -1171,9 +1467,11 @@ void ETSParser::ParseNamedSpecifiesDefaultImport(ArenaVector(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(imported != nullptr); imported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); auto *specifier = AllocNode(imported); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({imported->Start(), imported->End()}); util::Helpers::CheckDefaultImportedName(*resultDefault, specifier, fileName); @@ -1181,9 +1479,54 @@ 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()); + ES2PANDA_ASSERT(exported != nullptr); + exported->SetRange(Lexer()->GetToken().Loc()); + auto *exportedAnonyConst = AllocNode(exported, exported->Clone(Allocator(), nullptr)); + ES2PANDA_ASSERT(exportedAnonyConst != nullptr); + exportedAnonyConst->SetConstantExpression(constantExpression); + exportedAnonyConst->SetDefault(); + resultExportDefault->emplace_back(exportedAnonyConst); + 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; + CheckModuleAsModifier(); + if (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); + ES2PANDA_ASSERT(specifier != nullptr); + 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)) { @@ -1198,44 +1541,29 @@ std::pair ETSParser::ParseN ArenaVector result(Allocator()->Adapter()); ArenaVector resultDefault(Allocator()->Adapter()); + ArenaVector resultExportDefault(Allocator()->Adapter()); + + auto token = Lexer()->GetToken(); + if (token.Ident() == (lexer::TokenToString(lexer::TokenType::KEYW_IMPORT)) && + token.Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { + LogError(diagnostic::ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT); + } 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) @@ -1243,21 +1571,20 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, lexer::SourcePosition namespaceStart = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat `*` character - if (!CheckModuleAsModifier()) { - LogError(diagnostic::UNEXPECTED_TOKEN); - } + CheckModuleAsModifier(); // Note (oeotvos) As a temporary solution we allow the stdlib to use namespace import without an alias, but this // 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); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, Lexer()->GetToken().End()}); specifiers->push_back(specifier); return; @@ -1267,6 +1594,7 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, local = ParseNamedImport(&Lexer()->GetToken()); auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, Lexer()->GetToken().End()}); specifiers->push_back(specifier); @@ -1275,33 +1603,54 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector *specifiers) { + if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { + LogError(diagnostic::ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT); + return nullptr; + } if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { LogExpectedToken(lexer::TokenType::LITERAL_IDENT); } auto *imported = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(imported != nullptr); 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().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { + LogError(diagnostic::ERROR_ARKTS_NO_REQUIRE); + return nullptr; + } if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) { LogExpectedToken(lexer::TokenType::KEYW_FROM); Lexer()->NextToken(); // eat 'from' } auto *specifier = AllocNode(imported); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({imported->Start(), imported->End()}); specifiers->push_back(specifier); return nullptr; } -bool ETSParser::CheckModuleAsModifier() +void ETSParser::CheckModuleAsModifier() { if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0U) { LogError(diagnostic::ESCAPE_SEQUENCES_IN_AS); } - - return true; } ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() @@ -1311,12 +1660,10 @@ ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() switch (Lexer()->GetToken().Type()) { case lexer::TokenType::LITERAL_IDENT: { parameter = AllocNode(Lexer()->GetToken().Ident(), Allocator()); - if (parameter->AsIdentifier()->Decorators().empty()) { - parameter->SetRange(Lexer()->GetToken().Loc()); - } else { - parameter->SetRange( - {parameter->AsIdentifier()->Decorators().front()->Start(), Lexer()->GetToken().End()}); - } + ES2PANDA_ASSERT(parameter != nullptr); + + parameter->SetRange(Lexer()->GetToken().Loc()); + break; } @@ -1329,9 +1676,11 @@ ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() } auto *const restIdent = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(restIdent != nullptr); restIdent->SetRange(Lexer()->GetToken().Loc()); parameter = AllocNode(ir::AstNodeType::REST_ELEMENT, Allocator(), restIdent); + ES2PANDA_ASSERT(parameter != nullptr); parameter->SetRange({startLoc, Lexer()->GetToken().End()}); break; } @@ -1353,7 +1702,7 @@ ir::Expression *ETSParser::ParseFunctionParameterAnnotations() auto annotations = ParseAnnotations(false); auto savePos = Lexer()->GetToken().Start(); ir::Expression *result = ParseFunctionParameter(); - if (result != nullptr) { + if (result != nullptr && !result->IsBrokenExpression()) { ApplyAnnotationsToNode(result, std::move(annotations), savePos); } return result; @@ -1377,6 +1726,10 @@ ir::Expression *ETSParser::ParseFunctionReceiver() return AllocBrokenExpression(thisLoc); } + if (typeAnnotation->IsBrokenTypeNode()) { + return AllocBrokenExpression(thisLoc); + } + return CreateParameterThis(typeAnnotation); } @@ -1413,6 +1766,17 @@ bool ETSParser::IsFixedArrayTypeNode(ir::AstNode *node) ir::Expression *ETSParser::ParseFunctionParameter() { + switch (Lexer()->GetToken().Type()) { + case lexer::TokenType::KEYW_PRIVATE: + case lexer::TokenType::KEYW_PUBLIC: + case lexer::TokenType::KEYW_PROTECTED: + LogError(diagnostic::FIELD_IN_PARAM); + Lexer()->NextToken(); + [[fallthrough]]; + default: + break; + } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { return ParseFunctionParameterAnnotations(); } @@ -1437,19 +1801,20 @@ ir::Expression *ETSParser::ParseFunctionParameter() if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); + ES2PANDA_ASSERT(typeAnnotation != nullptr); if (typeAnnotation->IsBrokenTypeNode()) { // the compiler can't process "declare class A { static foo(x: {key: string}[]):void; }" correctly // and resolve "{key: string}" as function body, so skip invalid types SkipInvalidType(); - } else if (paramIdent->IsRestElement() && !typeAnnotation->IsTSArrayType() && - !IsFixedArrayTypeNode(typeAnnotation) && !typeAnnotation->IsETSTuple()) { - LogError(diagnostic::ONLY_ARRAY_OR_TUPLE_FOR_REST); } typeAnnotation->SetParent(paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); paramIdent->SetEnd(typeAnnotation->End()); - } else if (!isArrow && !isOptional) { + } + + if ((!isArrow || isOptional) && paramIdent->TypeAnnotation() == nullptr) { LogError(diagnostic::EXPLICIT_PARAM_TYPE); + paramIdent->SetTsTypeAnnotation(AllocBrokenType(Lexer()->GetToken().Loc())); } return ParseFunctionParameterExpression(paramIdent, isOptional); @@ -1458,12 +1823,14 @@ ir::Expression *ETSParser::ParseFunctionParameter() ir::Expression *ETSParser::CreateParameterThis(ir::TypeNode *typeAnnotation) { auto *paramIdent = AllocNode(varbinder::TypedBinder::MANDATORY_PARAM_THIS, Allocator()); + ES2PANDA_ASSERT(paramIdent != nullptr); paramIdent->SetRange(Lexer()->GetToken().Loc()); typeAnnotation->SetParent(paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); auto *paramExpression = AllocNode(paramIdent, false, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); return paramExpression; @@ -1472,6 +1839,7 @@ ir::Expression *ETSParser::CreateParameterThis(ir::TypeNode *typeAnnotation) ir::AnnotatedExpression *ETSParser::ParseVariableDeclaratorKey([[maybe_unused]] VariableParsingFlags flags) { ir::Identifier *init = ExpectIdentifier(); + ES2PANDA_ASSERT(init != nullptr); ir::TypeNode *typeAnnotation = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { if ((flags & VariableParsingFlags::FOR_OF) != 0U) { @@ -1479,6 +1847,9 @@ ir::AnnotatedExpression *ETSParser::ParseVariableDeclaratorKey([[maybe_unused]] } Lexer()->NextToken(); // eat '?' init->AddModifier(ir::ModifierFlags::OPTIONAL); + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { + LogError(diagnostic::OPTIONAL_VARIABLE); + } } if (auto const tokenType = Lexer()->GetToken().Type(); tokenType == lexer::TokenType::PUNCTUATOR_COLON) { @@ -1564,8 +1935,10 @@ ir::Expression *ETSParser::ParseCatchParam() void ETSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpression *param) { if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { + LogError(diagnostic::MULTI_CATCH_DEPRECATED); TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; if (auto *typeAnnotation = ParseTypeAnnotation(&options); typeAnnotation != nullptr) { + ES2PANDA_ASSERT(param != nullptr); typeAnnotation->SetParent(param); param->SetTsTypeAnnotation(typeAnnotation); } @@ -1578,8 +1951,10 @@ void ETSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpr ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsingFlags flags) { + bool isError = false; if ((flags & StatementParsingFlags::GLOBAL) == 0) { LogError(diagnostic::IMPORT_TOP_LEVEL); + isError = true; } char32_t nextChar = Lexer()->Lookahead(); @@ -1606,24 +1981,26 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi importDeclaration = ParseImportPathBuildImport(std::move(specifiers), false, startLoc, ir::ImportKinds::ALL); } - return importDeclaration; + return isError ? AllocBrokenStatement(startLoc) : importDeclaration; } ir::Statement *ETSParser::ParseExportDeclaration([[maybe_unused]] StatementParsingFlags flags) { LogUnexpectedToken(lexer::TokenType::KEYW_EXPORT); - return AllocBrokenStatement(Lexer()->GetToken().Start()); + return AllocBrokenStatement(Lexer()->GetToken().Loc()); } ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type, [[maybe_unused]] ExpressionParseFlags flags) { if (type == lexer::TokenType::KEYW_INSTANCEOF) { - TypeAnnotationParsingOptions options = - TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | + TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW | + TypeAnnotationParsingOptions::INSTANCEOF; if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_NULL) { auto *typeAnnotation = AllocNode(); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1660,15 +2037,20 @@ bool ETSParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, i return true; } - // unexpected_token_49,ets, 50, 51 - if (!Lexer()->GetToken().NewLine() && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { - LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { + Lexer()->NextToken(); + return true; } - if (Lexer()->GetToken().NewLine()) { + if (Lexer()->GetToken().Type() == lexer::TokenType::EOS || Lexer()->GetToken().NewLine()) { return true; } + // unexpected_token_49,ets, 50, 51 + if (!Lexer()->GetToken().NewLine() && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { if (!ignoreCallExpression) { *returnExpression = ParseCallExpression(*returnExpression, false, false); @@ -1735,15 +2117,19 @@ ir::AstNode *ETSParser::ParseAmbientSignature(const lexer::SourcePosition &start } // eat ":" - if (Lexer()->NextToken(); Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_NUMBER) { + if (Lexer()->NextToken(); Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_NUMBER && + Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_INT) { // ambient_indexer_3.ets LogError(diagnostic::INDEX_TYPE_NOT_NUMBER); Lexer()->GetToken().SetTokenType(lexer::TokenType::KEYW_NUMBER); } + TypeAnnotationParsingOptions typAnotationOptions = TypeAnnotationParsingOptions::NO_OPTS; + auto typeAnno = ParseTypeAnnotation(&typAnotationOptions); + // eat indexType - if (Lexer()->NextToken(); Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { // ambient_indexer_7.ets LogError(diagnostic::EXPECTED_BRACKETS_IN_INDEX); @@ -1754,25 +2140,24 @@ ir::AstNode *ETSParser::ParseAmbientSignature(const lexer::SourcePosition &start if (Lexer()->NextToken(); Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { // ambient_indexer_4.ets LogError(diagnostic::INDEX_MISSING_TYPE); + } - Lexer()->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_COLON); + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { + LogError(diagnostic::EXPECTED_PARAM_GOT_PARAM, {":", TokenToString(Lexer()->GetToken().Type())}); } - // eat ":" - if (Lexer()->NextToken(); Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { - // ambient_indexer_5.ets + TypeAnnotationParsingOptions options = + TypeAnnotationParsingOptions::RETURN_TYPE | TypeAnnotationParsingOptions::REPORT_ERROR; + auto *returnType = ParseTypeAnnotation(&options); + if (returnType->IsBrokenTypeNode()) { LogError(diagnostic::INDEX_MISSING_IDENTIFIER); - - Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); - Lexer()->GetToken().SetTokenStr(ERROR_LITERAL); + return AllocBrokenStatement({startPos, Lexer()->GetToken().End()}); } - auto const returnType = AllocNode( - AllocNode(Lexer()->GetToken().Ident(), Allocator()), Allocator()); auto dummyNode = AllocNode(compiler::Signatures::AMBIENT_INDEXER, indexName, returnType, - ir::DummyNodeFlag::INDEXER); + ir::DummyNodeFlag::INDEXER, typeAnno); + ES2PANDA_ASSERT(dummyNode != nullptr); dummyNode->SetRange({startPos, Lexer()->GetToken().End()}); - Lexer()->NextToken(); // eat return type return dummyNode; } @@ -1801,13 +2186,12 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati } } auto saveLoc = Lexer()->GetToken().Start(); - auto *paramIdent = ExpectIdentifier(false, false, *options); + auto *paramIdent = ExpectIdentifier(false, false, *options | TypeAnnotationParsingOptions::REPORT_ERROR); ir::TypeNode *constraint = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { Lexer()->NextToken(); - TypeAnnotationParsingOptions newOptions = - TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE; + TypeAnnotationParsingOptions newOptions = TypeAnnotationParsingOptions::REPORT_ERROR; constraint = ParseTypeAnnotation(&newOptions); } @@ -1821,6 +2205,7 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati auto *typeParam = AllocNode(paramIdent, constraint, defaultType, varianceModifier, Allocator()); + ES2PANDA_ASSERT(typeParam != nullptr); ApplyAnnotationsToNode(typeParam, std::move(annotations), saveLoc); typeParam->SetRange({startLoc, Lexer()->GetToken().End()}); return typeParam; @@ -1858,6 +2243,11 @@ void ETSParser::CheckDeclare() Lexer()->NextToken(); // eat 'declare' + if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->GetToken().Ident().Is("module")) { + LogError(diagnostic::ERROR_ARKTS_NO_AMBIENT_DECLS); + return; + } + switch (Lexer()->GetToken().KeywordType()) { case lexer::TokenType::KEYW_LET: case lexer::TokenType::KEYW_CONST: @@ -1882,6 +2272,83 @@ void ETSParser::CheckDeclare() } } +void ETSParser::ValidateOverloadDeclarationModifiers(ir::ModifierFlags modifiers) +{ + ir::ModifierFlags allowModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::ASYNC | + ir::ModifierFlags::ACCESS | ir::ModifierFlags::EXPORTED | + ir::ModifierFlags::DECLARE; + if ((modifiers & ~allowModifiers) != 0) { + LogError(diagnostic::OVERLOAD_MODIFIERS); + } +} + +bool ETSParser::ParseOverloadListElement(ArenaVector &overloads, + ir::OverloadDeclaration *overloadDecl) +{ + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + LogExpectedToken(lexer::TokenType::LITERAL_IDENT); + } + ir::Expression *qualifiedName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + qualifiedName->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + while (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_PERIOD)) { + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + LogExpectedToken(lexer::TokenType::LITERAL_IDENT); + return false; + } + auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + identNode->SetRange(Lexer()->GetToken().Loc()); + auto start = qualifiedName->Start(); + qualifiedName = AllocNode(qualifiedName, identNode, + ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + qualifiedName->SetRange({start, identNode->End()}); + Lexer()->NextToken(); + } + + qualifiedName->SetParent(overloadDecl); + overloads.push_back(qualifiedName); + return true; +} + +ir::OverloadDeclaration *ETSParser::ParseOverloadDeclaration(ir::ModifierFlags modifiers) +{ + ValidateOverloadDeclarationModifiers(modifiers); + Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_OVERLOAD); + auto *overloadName = ExpectIdentifier(false, false, TypeAnnotationParsingOptions::REPORT_ERROR); + auto *overloadDef = AllocNode(overloadName->Clone(Allocator(), nullptr)->AsExpression(), + modifiers, Allocator()); + overloadDef->AddOverloadDeclFlag(ir::OverloadDeclFlags::FUNCTION); + + auto startLoc = overloadName->Start(); + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); + } + ArenaVector overloads(Allocator()->Adapter()); + lexer::SourcePosition endLoc; + + ParseList( + lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, + [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + overloadDef->SetOverloadedList(std::move(overloads)); + overloadDef->SetRange({startLoc, endLoc}); + for (ir::Expression *overloadedName : overloadDef->OverloadedList()) { + std::function checkQualifiedName = [&checkQualifiedName](ir::Expression *expr) -> bool { + if (expr->IsIdentifier()) { + return true; + } + if (expr->IsMemberExpression()) { + return expr->AsMemberExpression()->Property()->IsIdentifier() && + checkQualifiedName(expr->AsMemberExpression()->Object()); + } + return false; + }; + if (!checkQualifiedName(overloadedName)) { + LogError(diagnostic::FUNCTION_OVERLOADED_NAME_MUST_QUALIFIED_NAME, {}, overloadedName->Start()); + } + } + return overloadDef; +} + ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous, ir::ModifierFlags modifiers) { lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); @@ -1895,6 +2362,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous } if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_MULTIPLY)) { + LogError(diagnostic::GENERATOR_FUNCTION); newStatus |= ParserStatus::GENERATOR_FUNCTION; } @@ -1914,6 +2382,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::FUNCTION_DECLARATION | ParserStatus::ALLOW_RECEIVER); + ES2PANDA_ASSERT(func != nullptr); if (funcIdentNode != nullptr) { // Error processing. func->SetIdent(funcIdentNode); } @@ -1923,6 +2392,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous Lexer()->NextToken(); } + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); func->AddModifier(modifiers); func->SetStart(startLoc); @@ -1942,10 +2412,12 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags ParserStatus::EXTENSION_ACCESSOR; ir::Identifier *funcIdentNode = ExpectIdentifier(); + ES2PANDA_ASSERT(funcIdentNode != nullptr); CheckRestrictedBinding(funcIdentNode->Name(), funcIdentNode->Start()); ir::ScriptFunction *func = isGetter ? ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE) : ParseFunction(newStatus); + ES2PANDA_ASSERT(func != nullptr); size_t paramCount = func->Params().size(); size_t getterValidParamCount = 1; size_t setterValidParamCount = 2; @@ -1967,6 +2439,7 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags func->SetIdent(funcIdentNode); auto *funcDecl = AllocNode(Allocator(), func); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); func->AddModifier(modifiers); func->SetStart(startLoc); @@ -1979,7 +2452,7 @@ void ETSParser::AddPackageSourcesToParseList() 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_->SourceFile().GetAbsolutePath()); + importPathManager_->MarkAsParsed(globalProgram_->AbsoluteName()); } //================================================================================================// diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index a288b7150ecd3ca663c361bc5da832a80ddbf52a..66ddcc044e8e2c478bf790a9923d043e37cef6ec 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -18,7 +18,6 @@ #include "util/arktsconfig.h" #include "util/importPathManager.h" -#include "util/recursiveGuard.h" #include "innerSourceParser.h" #include "TypedParser.h" #include "ir/base/classDefinition.h" @@ -33,6 +32,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, @@ -55,10 +60,18 @@ public: return globalProgram_->AbsoluteName(); } + Program *GetGlobalProgram() + { + return globalProgram_; + } + [[nodiscard]] bool IsETSParser() const noexcept override; + [[nodiscard]] bool IsValidIdentifierName(const lexer::Token &token) const noexcept override; + void AddDirectImportsToDirectExternalSources(const ArenaVector &directImportsFromMainSource, parser::Program *newProg) const; + bool CheckDupAndReplace(Program *&oldProg, Program *newProg) const; ArenaVector ParseDefaultSources(std::string_view srcFile, std::string_view importSrc); public: @@ -75,156 +88,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); @@ -245,16 +136,18 @@ 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); + static void AddGenExtenralSourceToParseList(public_lib::Context *ctx); private: + void ParseAndSetStdlib(); NodeFormatType GetFormatPlaceholderType(); - ir::Statement *ParseStatementFormatPlaceholder() override; ir::Expression *ParseExpressionFormatPlaceholder(); ir::Identifier *ParseIdentifierFormatPlaceholder(std::optional nodeFormat) override; @@ -267,15 +160,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); @@ -289,7 +178,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; @@ -299,6 +187,9 @@ private: #endif ir::ETSImportDeclaration *ParseImportPathBuildImport(ArenaVector &&specifiers, bool requireFrom, lexer::SourcePosition startLoc, ir::ImportKinds importKind); + ir::Statement *CreateReExportDeclarationNode(ir::ETSImportDeclaration *reExportDeclaration, + const lexer::SourcePosition &startLoc, + const ir::ModifierFlags &modifiers); void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool defaultExport); void ParseUserSources(std::vector userParths); ArenaVector ParseTopLevelDeclaration(); @@ -308,16 +199,25 @@ 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(); + ArenaVector ParseETSInitModuleStatements(); 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); + void ParseFileHeaderFlag(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); ir::MethodDefinition *ParseClassGetterSetterMethod(const ArenaVector &properties, @@ -330,12 +230,21 @@ private: ir::ModifierFlags ParseClassModifiers(); ir::ModifierFlags ParseInterfaceMethodModifiers(); ir::AstNode *ParseInterfaceField(); + void ParseIndexedSignature(); + ir::TypeNode *ParseInterfaceTypeAnnotation(ir::Identifier *name); + void ParseInterfaceModifiers(ir::ModifierFlags &fieldModifiers, bool &optionalField); + ir::OverloadDeclaration *ParseInterfaceOverload(ir::ModifierFlags modifiers); + void ThrowOptionalMethodErrorIfNeeded(); ir::MethodDefinition *ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind); void ReportAccessModifierError(const lexer::Token &token); std::tuple ParseClassMemberAccessModifiers(); ir::ModifierFlags ParseClassFieldModifiers(bool seenStatic); ir::ModifierFlags ParseClassMethodModifierFlag(); ir::ModifierFlags ParseClassMethodModifiers(bool seenStatic); + void ValidateOverloadDeclarationModifiers(ir::ModifierFlags modifiers); + bool ParseOverloadListElement(ArenaVector &overloads, ir::OverloadDeclaration *overloadDecl); + void ValidateOverloadList(ArenaVector const &overloadList); + ir::OverloadDeclaration *ParseClassOverloadDeclaration(ir::ModifierFlags modifiers); ir::MethodDefinition *ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers, bool isDefault); ir::ScriptFunction *ParseFunction(ParserStatus newStatus); @@ -344,9 +253,10 @@ private: std::tuple ParseFunctionBody( const ArenaVector ¶ms, ParserStatus newStatus, ParserStatus contextStatus) override; ir::TypeNode *ParseFunctionReturnType(ParserStatus status) override; - 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, bool isDefault); @@ -360,19 +270,19 @@ private: ir::TypeNode *ParseWildcardType(TypeAnnotationParsingOptions *options); ir::TypeNode *ParseFunctionType(TypeAnnotationParsingOptions *options); ir::TypeNode *ParseETSTupleType(TypeAnnotationParsingOptions *options); + ir::TypeNode *CreateErrorForWrongArrayType(lexer::SourcePosition &startPos); ir::TypeNode *ParseTsArrayType(ir::TypeNode *typeNode, TypeAnnotationParsingOptions *options); bool ParseTriplePeriod(bool spreadTypePresent); - std::pair CheckDefaultParameters(const ir::ScriptFunction *function); std::string PrimitiveTypeToName(ir::PrimitiveType type) const; std::string GetNameForTypeNode(const ir::TypeNode *typeAnnotation) const; std::string GetNameForETSUnionType(const ir::TypeNode *typeAnnotation) const; 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 ParseNonNullableType(TypeAnnotationParsingOptions *options); + void CheckForConditionalTypeError(TypeAnnotationParsingOptions options, lexer::TokenType tokenType); std::pair GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options); std::pair GetTypeAnnotationFromParentheses(TypeAnnotationParsingOptions *options); ir::TypeNode *ParseLiteralIdent(TypeAnnotationParsingOptions *options); @@ -383,29 +293,30 @@ 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; ir::Statement *ParseTryStatement() override; ir::Statement *ParseDebuggerStatement() override; + ir::Statement *ParseDefaultIfSingleExport(ir::ModifierFlags modifiers); ir::Statement *ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers); ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags) override; ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags) override; + ir::Statement *ParseInitModuleStatement(StatementParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, const lexer::SourcePosition &startLoc) override; bool IsFieldStartToken(lexer::TokenType t); + void LookForOptionalMethod(char32_t &nextCp); ir::AstNode *ParseTypeLiteralOrInterfaceMember() override; ir::AstNode *ParseAnnotationsInInterfaceBody(); void ParseNameSpaceSpecifier(ArenaVector *specifiers, bool isReExport = false); - bool CheckModuleAsModifier(); + void CheckModuleAsModifier(); bool IsFixedArrayTypeNode(ir::AstNode *node); ir::Expression *ParseFunctionParameterExpression(ir::AnnotatedExpression *paramIdent, bool isOptional); std::pair TypeAnnotationValue(ir::TypeNode *typeAnnotation); @@ -417,11 +328,14 @@ private: ir::Expression *ResolveArgumentUnaryExpr(ExpressionParseFlags flags); ir::Expression *CreateUnaryExpressionFromArgument(ir::Expression *argument, lexer::TokenType operatorType, char32_t beginningChar); + + ir::Expression *HandleDeepNesting(); // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseUnaryOrPrefixUpdateExpression( ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParsePropertyDefinition(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; + ir::Expression *ParsePropertyKey(ExpressionParseFlags flags) override; // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseDefaultPrimaryExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); // NOLINTNEXTLINE(google-default-arguments) @@ -441,6 +355,9 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParseStructStatement(StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags = ir::ModifierFlags::NONE) override; + ir::Statement *ParseInterfaceStatement(StatementParsingFlags flags) override; + ir::Statement *ParseEnumStatement(StatementParsingFlags flags) override; + ir::Statement *ParseTypeAliasStatement() override; ir::AstNode *ParseClassElement(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags) override; std::tuple HandleClassElementModifiers(ir::ModifierFlags &memberModifiers); @@ -466,29 +383,24 @@ private: 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; + ir::OverloadDeclaration *ParseOverloadDeclaration(ir::ModifierFlags modifiers); ir::FunctionDeclaration *ParseFunctionDeclaration(bool canBeAnonymous, ir::ModifierFlags modifiers); ir::FunctionDeclaration *ParseAccessorWithReceiver(ir::ModifierFlags modifiers); ir::TypeNode *ParseExtensionFunctionsTypeAnnotation(); @@ -506,13 +418,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, @@ -521,11 +431,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 @@ -535,24 +442,19 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; - ir::Expression *ParseExpressionOrTypeAnnotation(lexer::TokenType type, ExpressionParseFlags flags) override; - + void ValidateKeywordIn(); ir::Expression *ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags) override; - + ir::Expression *ParseGenericLambdaOrTypeAssertion(); 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(); friend class ExternalSourceParser; friend class InnerSourceParser; - friend ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags); private: uint32_t namespaceNestedRank_; @@ -562,7 +464,6 @@ private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; std::unique_ptr importPathManager_ {nullptr}; - RecursiveContext recursiveCtx_; }; class ExternalSourceParser { @@ -603,6 +504,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 f09bc2591f7a76a992c73a027ab8fb83fa5e9a20..e294a8573baf600112275eb0ac90ec63b0e3fa81 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -19,6 +19,7 @@ #include "ir/ets/etsTuple.h" #include "ir/ets/etsUnionType.h" #include "ir/statements/annotationDeclaration.h" +#include "ir/brokenTypeNode.h" namespace ark::es2panda::parser { @@ -56,23 +57,32 @@ ir::Expression *ETSParser::ParseAnnotationName() } }; auto save = Lexer()->Save(); + ir::Identifier *ident = nullptr; Lexer()->NextToken(); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { Lexer()->Rewind(save); expr = ExpectIdentifier(); - setAnnotation(expr->AsIdentifier()); - return expr; - } - Lexer()->Rewind(save); - if (Lexer()->Lookahead() == '.') { - auto opt = TypeAnnotationParsingOptions::NO_OPTS; - expr = ParseTypeReference(&opt); - setAnnotation(expr->AsETSTypeReference()->Part()->GetIdent()); + ES2PANDA_ASSERT(expr != nullptr); + ident = expr->AsIdentifier(); } else { - expr = ExpectIdentifier(); - setAnnotation(expr->AsIdentifier()); + Lexer()->Rewind(save); + if (Lexer()->Lookahead() == '.') { + auto opt = TypeAnnotationParsingOptions::NO_OPTS; + expr = ParseTypeReference(&opt); + ES2PANDA_ASSERT(expr != nullptr); + ident = expr->AsETSTypeReference()->Part()->GetIdent(); + } else { + expr = ExpectIdentifier(); + ES2PANDA_ASSERT(expr != nullptr); + ident = expr->AsIdentifier(); + } } + if (ident->IsBrokenExpression()) { + LogError(diagnostic::INVALID_ANNOTATION_NAME, {}, expr->Start()); + } + + setAnnotation(ident); return expr; } @@ -94,6 +104,7 @@ ir::AnnotationDeclaration *ETSParser::ParseAnnotationDeclaration(ir::ModifierFla lexer::SourcePosition endLoc = Lexer()->GetToken().End(); auto *annotationDecl = AllocNode(expr, std::move(properties), Allocator()); + ES2PANDA_ASSERT(annotationDecl != nullptr); annotationDecl->SetRange({startLoc, endLoc}); annotationDecl->AddModifier(flags); return annotationDecl; @@ -128,12 +139,15 @@ ArenaVector ETSParser::ParseAnnotationProperties(ir::ModifierFlag } auto *fieldName = ExpectIdentifier(); + ES2PANDA_ASSERT(fieldName != nullptr); if (fieldName->IsErrorPlaceHolder()) { // Try to recover from error: simplest strategy: only one step ahead. // Probably we can seek for identifier till the enclosing right brace (staring after the next comma?) // if the simplest case failed. auto const pos = Lexer()->Save(); - if (auto *fieldName1 = ExpectIdentifier(); fieldName1->IsErrorPlaceHolder()) { + auto *fieldName1 = ExpectIdentifier(); + ES2PANDA_ASSERT(fieldName1 != nullptr); + if (fieldName1->IsErrorPlaceHolder()) { Lexer()->Rewind(pos); } else { fieldName = fieldName1; @@ -188,6 +202,8 @@ ir::AstNode *ETSParser::ParseAnnotationProperty(ir::Identifier *fieldName, ir::M if (typeAnnotation == nullptr && (memberModifiers & ir::ModifierFlags::ANNOTATION_DECLARATION) != 0 && !fieldName->IsErrorPlaceHolder()) { LogError(diagnostic::MISSING_TYPE_ANNOTATION, {fieldName->Name().Mutf8()}, Lexer()->GetToken().Start()); + typeAnnotation = AllocNode(Allocator()); + typeAnnotation->SetRange({endLoc, endLoc}); } if (typeAnnotation != nullptr) { @@ -210,12 +226,14 @@ ir::AstNode *ETSParser::ParseAnnotationProperty(ir::Identifier *fieldName, ir::M if (initializer != nullptr && !ValidAnnotationValue(initializer)) { LogError(diagnostic::INVALID_VAL_ANNOTATION_FIELD, {}, savePos); + initializer = AllocBrokenExpression(savePos); } memberModifiers |= ir::ModifierFlags::PUBLIC; memberModifiers |= ir::ModifierFlags::ABSTRACT; auto *field = AllocNode(fieldName, initializer, typeAnnotation, memberModifiers, Allocator(), false); + ES2PANDA_ASSERT(field != nullptr); field->SetRange({fieldName->Start(), initializer != nullptr ? initializer->End() : endLoc}); return field; } @@ -282,24 +300,17 @@ 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) { switch (node->Type()) { - case ir::AstNodeType::METHOD_DEFINITION: - node->AsMethodDefinition()->Function()->SetAnnotations(std::move(annotations)); + case ir::AstNodeType::METHOD_DEFINITION: { + auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->SetAnnotations(std::move(annotations)); break; + } case ir::AstNodeType::CLASS_DECLARATION: node->AsClassDeclaration()->Definition()->SetAnnotations(std::move(annotations)); break; @@ -334,7 +345,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)); @@ -365,13 +376,14 @@ void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVecto } } -static lexer::SourcePosition GetExpressionEndLoc(ir::Expression *expr) +static lexer::SourcePosition GetAnnotationExpressionEndLoc(ir::Expression *expr) { + ES2PANDA_ASSERT(expr != nullptr); if (expr->IsIdentifier()) { return expr->AsIdentifier()->End(); } - auto *part = expr->AsETSTypeReference()->Part(); - return part->Name()->AsTSQualifiedName()->Right()->End(); + + return expr->AsETSTypeReference()->Part()->GetIdent()->End(); } ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() @@ -383,13 +395,14 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() ArenaVector properties(Allocator()->Adapter()); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS && - !IsArrowFunctionExpressionStart() && IsAnnotationUsageStart(GetExpressionEndLoc(expr))) { + !IsArrowFunctionExpressionStart() && IsAnnotationUsageStart(GetAnnotationExpressionEndLoc(expr))) { Lexer()->NextToken(); // eat '(' if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { properties = ParseAnnotationProperties(flags); } else if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { // handle single field annotation auto *singleParamName = AllocNode(compiler::Signatures::ANNOTATION_KEY_VALUE, Allocator()); + ES2PANDA_ASSERT(singleParamName != nullptr); singleParamName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); const auto savePos = Lexer()->GetToken().Start(); @@ -400,16 +413,26 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() auto *singleParam = AllocNode(singleParamName, initializer, nullptr, ir::ModifierFlags::ANNOTATION_USAGE, Allocator(), false); + ES2PANDA_ASSERT(singleParam != nullptr); singleParam->SetRange( {singleParamName->Start(), initializer != nullptr ? initializer->End() : singleParamName->End()}); properties.push_back(singleParam); } + + auto *annotationUsage = AllocNode(expr, std::move(properties)); + annotationUsage->AddModifier(flags); + annotationUsage->SetRange({startLoc, Lexer()->GetToken().End()}); + ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, true); // eat ')' + + return annotationUsage; } auto *annotationUsage = AllocNode(expr, std::move(properties)); + ES2PANDA_ASSERT(annotationUsage != nullptr); annotationUsage->AddModifier(flags); - annotationUsage->SetRange({startLoc, Lexer()->GetToken().End()}); + annotationUsage->SetRange({startLoc, GetAnnotationExpressionEndLoc(expr)}); + return annotationUsage; } diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 70df4332515ab87584e17eeaa601abc9f9ca688c..f9d858dbc79b249ffe63e527ea2fae7a0c9e30e8 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -28,6 +28,7 @@ #include "lexer/lexer.h" #include "lexer/ETSLexer.h" #include "ir/astNode.h" +#include "ir/brokenTypeNode.h" #include "ir/base/classDefinition.h" #include "ir/base/decorator.h" #include "ir/base/catchClause.h" @@ -55,7 +56,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" @@ -114,11 +114,6 @@ ir::ModifierFlags ETSParser::ParseClassModifiers() while (IsClassModifier(Lexer()->GetToken().KeywordType())) { ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; - lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); - if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); // Lexer will do it. - } - switch (Lexer()->GetToken().KeywordType()) { case lexer::TokenType::KEYW_STATIC: { currentFlag = ir::ModifierFlags::STATIC; @@ -202,11 +197,6 @@ std::tuple ETSParser::ParseClassMemberAccessModif return {ir::ModifierFlags::NONE, false, false}; } - lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); - if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); // Lexer will do it. - } - ir::ModifierFlags accessFlag = ir::ModifierFlags::NONE; const auto token = Lexer()->GetToken(); @@ -233,6 +223,9 @@ std::tuple ETSParser::ParseClassMemberAccessModif accessFlag = ir::ModifierFlags::INTERNAL_PROTECTED; break; } + case lexer::TokenType::EOS: { // process invalid tokenType + return {ir::ModifierFlags::NONE, false, false}; + } default: { ES2PANDA_UNREACHABLE(); } @@ -267,11 +260,6 @@ ir::ModifierFlags ETSParser::ParseClassFieldModifiers(bool seenStatic) ir::ModifierFlags currentFlag; - lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); - if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); // Lexer will do it. - } - switch (Lexer()->GetToken().KeywordType()) { case lexer::TokenType::KEYW_STATIC: { currentFlag = ir::ModifierFlags::STATIC; @@ -404,11 +392,6 @@ ir::ModifierFlags ETSParser::ParseClassMethodModifiers(bool seenStatic) ir::ModifierFlags currentFlag = ir::ModifierFlags::NONE; - lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); - if ((tokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); // Lexer will do it. - } - currentFlag = ParseClassMethodModifierFlag(); if ((flags & currentFlag) != 0) { LogError(diagnostic::DUPLICATED_MODIFIER); @@ -441,6 +424,7 @@ ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) types.push_back(AllocNode(Allocator())); types.back()->SetRange(typeAnno->Range()); auto *newTypeAnno = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(newTypeAnno != nullptr); newTypeAnno->SetRange(typeAnno->Range()); return newTypeAnno; } @@ -456,10 +440,36 @@ ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) types.push_back(AllocNode(Allocator())); types.back()->SetRange(typeAnno->Range()); auto *newTypeAnno = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(newTypeAnno != nullptr); newTypeAnno->SetRange(typeAnno->Range()); return newTypeAnno; } +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, bool isDefault) @@ -469,8 +479,21 @@ void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::Modifie TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; bool optionalField = false; - if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { + auto start = Lexer()->GetToken().Start(); + if (Lexer()->GetToken().Type() == (lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK)) { + endLoc = Lexer()->GetToken().End(); + modifiers |= ir::ModifierFlags::DEFINITE; + Lexer()->NextToken(); + } + if (Lexer()->GetToken().Type() == (lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { + endLoc = Lexer()->GetToken().End(); optionalField = true; + Lexer()->NextToken(); + } + if (Lexer()->GetToken().Type() == (lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK)) { + endLoc = Lexer()->GetToken().End(); + modifiers |= ir::ModifierFlags::DEFINITE; + Lexer()->NextToken(); } if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { typeAnnotation = ParseTypeAnnotation(&options); @@ -488,22 +511,67 @@ void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::Modifie if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_SUBSTITUTION)) { initializer = ParseExpression(); } else if (typeAnnotation == nullptr) { - LogError(diagnostic::FIELD_TPYE_ANNOTATION_MISSING); + typeAnnotation = AllocNode(Allocator()); + typeAnnotation->SetRange({endLoc, endLoc}); + LogError(diagnostic::FIELD_TYPE_ANNOTATION_MISSING, {}, endLoc); } - 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); + ES2PANDA_ASSERT(field != nullptr); field->SetDefaultAccessModifier(isDefault); + if (optionalField) { + field->AddModifier(ir::ModifierFlags::OPTIONAL); + } field->SetRange({fieldName->Start(), initializer != nullptr ? initializer->End() : endLoc}); declarations->push_back(field); } +void ETSParser::ValidateOverloadList(ArenaVector const &overloadList) +{ + for (ir::Expression *overloadedName : overloadList) { + if (!overloadedName->IsIdentifier()) { + LogError(diagnostic::CLASS_INTERFACE_METHOD_OVERLOADED_NAME_MUST_IDENT, {}, overloadedName->Start()); + } + } +} + +ir::OverloadDeclaration *ETSParser::ParseClassOverloadDeclaration(ir::ModifierFlags modifiers) +{ + ValidateOverloadDeclarationModifiers(modifiers); + ir::Identifier *overloadName = nullptr; + // To avoid duplicate names with anonymous constructors, overload constructor name is + // "constructorOverloadDeclaration", instead of "constructor" + if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CONSTRUCTOR) { + overloadName = AllocNode(compiler::Signatures::CONSTRUCTOR_NAME, Allocator()); + modifiers |= ir::ModifierFlags::CONSTRUCTOR; + Lexer()->NextToken(); + } else { + overloadName = ExpectIdentifier(false, false, TypeAnnotationParsingOptions::REPORT_ERROR); + } + + auto *overloadDef = AllocNode(overloadName->Clone(Allocator(), nullptr)->AsExpression(), + modifiers, Allocator()); + overloadDef->AddOverloadDeclFlag(ir::OverloadDeclFlags::CLASS_METHOD); + + auto startLoc = Lexer()->GetToken().Start(); + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); + } + ArenaVector overloads(Allocator()->Adapter()); + lexer::SourcePosition endLoc; + + ParseList( + lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, + [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + overloadDef->SetOverloadedList(std::move(overloads)); + overloadDef->SetRange({startLoc, endLoc}); + ValidateOverloadList(overloadDef->OverloadedList()); + return overloadDef; +} + ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers, bool isDefault) { @@ -524,13 +592,17 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth } ir::ScriptFunction *func = ParseFunction(newStatus); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(methodName); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); func->AddModifier(modifiers); + ES2PANDA_ASSERT(methodName->Clone(Allocator(), nullptr) != nullptr); auto *method = AllocNode(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, modifiers, Allocator(), false); + ES2PANDA_ASSERT(method != nullptr); method->SetDefaultAccessModifier(isDefault); method->SetRange(funcExpr->Range()); return method; @@ -546,11 +618,13 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, } ir::ScriptFunction *func = ParseFunction(desc->newStatus); + ES2PANDA_ASSERT(func != nullptr); if (propName->IsIdentifier()) { func->SetIdent(propName->AsIdentifier()->Clone(Allocator(), nullptr)); } auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -564,6 +638,7 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, auto *method = AllocNode(desc->methodKind, propName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; @@ -677,7 +752,9 @@ void *ETSParser::ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVect for (auto *node : property->AsTSInterfaceBody()->Body()) { ArenaVector cloneAnnotations(Allocator()->Adapter()); for (auto *annotationUsage : annotations) { - cloneAnnotations.push_back(annotationUsage->Clone(Allocator(), node)->AsAnnotationUsage()); + auto cloneAnnotationUsage = annotationUsage->Clone(Allocator(), node); + ES2PANDA_ASSERT(cloneAnnotationUsage != nullptr); + cloneAnnotations.push_back(cloneAnnotationUsage->AsAnnotationUsage()); } ApplyAnnotationsToNode(node, std::move(cloneAnnotations), pos); } @@ -695,8 +772,10 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< ClassElementDescriptor desc(Allocator()); desc.methodKind = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET ? ir::MethodDefinitionKind::GET : ir::MethodDefinitionKind::SET; + desc.propStart = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat get/set auto *methodName = ExpectIdentifier(); + ES2PANDA_ASSERT(methodName != nullptr); if (desc.methodKind == ir::MethodDefinitionKind::GET) { methodName->SetAccessor(); } else { @@ -705,18 +784,20 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< desc.newStatus = ParserStatus::ALLOW_SUPER; desc.hasSuperClass = (modifiers & ir::ClassDefinitionModifiers::HAS_SUPER) != 0U; - desc.propStart = Lexer()->GetToken().Start(); desc.modifiers = memberModifiers; lexer::SourcePosition propEnd = methodName->End(); ir::MethodDefinition *method = ParseClassMethod(&desc, properties, methodName, &propEnd); + ES2PANDA_ASSERT(method != nullptr); method->SetDefaultAccessModifier(isDefault); - method->Function()->AddModifier(desc.modifiers); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->AddModifier(desc.modifiers); method->SetRange({desc.propStart, propEnd}); if (desc.methodKind == ir::MethodDefinitionKind::GET) { - method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); + func->AddFlag(ir::ScriptFunctionFlags::GETTER); } else { - method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); + func->AddFlag(ir::ScriptFunctionFlags::SETTER); } return method; @@ -733,18 +814,26 @@ ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::Modi return nullptr; } method->AddModifier(ir::ModifierFlags::PUBLIC); - method->SetRange({Lexer()->GetToken().Start(), method->Id()->End()}); + auto *id = method->Id(); + auto *func = method->Function(); + ES2PANDA_ASSERT(id != nullptr); + ES2PANDA_ASSERT(func != nullptr); if (methodKind == ir::MethodDefinitionKind::GET) { - method->Id()->SetAccessor(); - method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); + id->SetAccessor(); + func->AddFlag(ir::ScriptFunctionFlags::GETTER); } else { - method->Id()->SetMutator(); - method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); + id->SetMutator(); + func->AddFlag(ir::ScriptFunctionFlags::SETTER); } method->AddModifier(ir::ModifierFlags::PUBLIC); - method->Function()->SetIdent(method->Id()->Clone(Allocator(), nullptr)); - method->Function()->AddModifier(method->Modifiers()); + func->SetIdent(id->Clone(Allocator(), nullptr)); + func->AddModifier(method->Modifiers()); + + bool hasReturn = func->ReturnTypeAnnotation() != nullptr; + if (hasReturn && methodKind == ir::MethodDefinitionKind::SET) { + LogError(diagnostic::SETTER_NO_RETURN_TYPE, {}, func->Range().start); + } return method; } @@ -767,17 +856,8 @@ ir::TSInterfaceDeclaration *ETSParser::ParseInterfaceBody(ir::Identifier *name, lexer::SourcePosition bodyStart = Lexer()->GetToken().Start(); auto members = ParseTypeLiteralOrInterface(); - - for (auto &member : members) { - if (member->Type() == ir::AstNodeType::CLASS_DECLARATION || - member->Type() == ir::AstNodeType::STRUCT_DECLARATION || - member->Type() == ir::AstNodeType::TS_ENUM_DECLARATION || - member->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) { - LogError(diagnostic::IMPROPER_NESTING_INTERFACE); - } - } - auto *body = AllocNode(std::move(members)); + ES2PANDA_ASSERT(body != nullptr); body->SetRange({bodyStart, Lexer()->GetToken().End()}); const auto isExternal = IsExternal(); @@ -800,8 +880,9 @@ ir::Statement *ETSParser::ParseInterfaceDeclaration(bool isStatic) auto *id = ExpectIdentifier(false, true); auto *declNode = ParseInterfaceBody(id, isStatic); + ES2PANDA_ASSERT(declNode != nullptr); - declNode->SetRange({interfaceStart, Lexer()->GetToken().End()}); + declNode->SetRange({interfaceStart, declNode->Body()->Range().end}); return declNode; } @@ -853,9 +934,10 @@ ir::ClassDefinition *ETSParser::ParseClassDefinition(ir::ClassDefinitionModifier std::tie(ctor, properties, bodyRange) = ParseClassBody(modifiers, flags); } - auto *classDefinition = - AllocNode(identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, - superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + auto *classDefinition = AllocNode( + Allocator(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, + std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetRange(bodyRange); @@ -868,7 +950,8 @@ ir::ModifierFlags ETSParser::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) { + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || + Lexer()->GetToken().Type() == lexer::TokenType::KEYW_OVERLOAD) { return ir::ModifierFlags::PUBLIC; } @@ -877,12 +960,79 @@ ir::ModifierFlags ETSParser::ParseInterfaceMethodModifiers() LogError(diagnostic::LOCAL_CLASS_ACCESS_MOD, {}, Lexer()->GetToken().Start()); } } - if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_PRIVATE) { - LogError(diagnostic::UNEXPECTED_TOKEN_PRIVATE_ID); + const auto keywordType = Lexer()->GetToken().KeywordType(); + const bool isPrivate = (keywordType == lexer::TokenType::KEYW_PRIVATE); + const bool isDefaultInAmbient = (keywordType == lexer::TokenType::KEYW_DEFAULT) && InAmbientContext(); + if (!isPrivate) { + if (!isDefaultInAmbient) { + LogError(diagnostic::UNEXPECTED_TOKEN_PRIVATE_ID); + } + if (keywordType == lexer::TokenType::KEYW_NEW) { + LogError(diagnostic::ERROR_ARKTS_NO_INTERFACE_CONSTRUCTOR_SIGNATURES); + } + } + Lexer()->NextToken(); + return isDefaultInAmbient ? ir::ModifierFlags::DEFAULT : ir::ModifierFlags::PRIVATE; +} + +ir::TypeNode *ETSParser::ParseInterfaceTypeAnnotation(ir::Identifier *name) +{ + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON) && + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { + 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); + } +} + +void ETSParser::ParseIndexedSignature() +{ + ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); Lexer()->NextToken(); - return ir::ModifierFlags::PRIVATE; + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + return; + } + auto *name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + Lexer()->NextToken(); + ParseInterfaceTypeAnnotation(name); + + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET)) { + return; + } + Lexer()->NextToken(); + ParseInterfaceTypeAnnotation(name); } ir::AstNode *ETSParser::ParseInterfaceField() @@ -890,13 +1040,20 @@ ir::AstNode *ETSParser::ParseInterfaceField() ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + ir::ModifierFlags fieldModifiers = ir::ModifierFlags::PUBLIC; auto startLoc = Lexer()->GetToken().Start(); auto *name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + if (name->IsErrorPlaceHolder()) { + Lexer()->NextToken(); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); + } + auto parseClassMethod = [&fieldModifiers, &startLoc, this](ir::Identifier *methodName) { auto *classMethod = ParseClassMethodDefinition(methodName, fieldModifiers, false); + ES2PANDA_ASSERT(classMethod != nullptr); classMethod->SetStart(startLoc); return classMethod; }; @@ -907,40 +1064,26 @@ ir::AstNode *ETSParser::ParseInterfaceField() return property; } } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { + ParseIndexedSignature(); + LogError(diagnostic::ERROR_ARKTS_NO_PROPERTIES_BY_INDEX, {}, startLoc); + return AllocBrokenExpression(Lexer()->GetToken().Start()); + } + ES2PANDA_ASSERT(name != nullptr); name->SetRange(Lexer()->GetToken().Loc()); 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); - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL && - Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { - LogError(diagnostic::INITIALIZERS_INTERFACE_PROPS); - Lexer()->NextToken(); // Error processing: eat '='. - } + ParseInterfaceModifiers(fieldModifiers, optionalField); + auto *typeAnnotation = ParseInterfaceTypeAnnotation(name); auto *field = AllocNode(name, nullptr, typeAnnotation->Clone(Allocator(), nullptr), fieldModifiers, Allocator(), false); + ES2PANDA_ASSERT(field != nullptr); if (optionalField) { field->AddModifier(ir::ModifierFlags::OPTIONAL); } - field->SetEnd(Lexer()->GetToken().End()); + field->SetEnd(typeAnnotation->End()); return field; } @@ -962,6 +1105,39 @@ static lexer::SourcePosition GetEndLoc(ir::BlockStatement *body, ir::ScriptFunct return lexer->GetToken().End(); } +ir::OverloadDeclaration *ETSParser::ParseInterfaceOverload(ir::ModifierFlags modifiers) +{ + ValidateOverloadDeclarationModifiers(modifiers); + auto *overloadName = ExpectIdentifier(false, false, TypeAnnotationParsingOptions::REPORT_ERROR); + auto *overloadDef = AllocNode(overloadName->Clone(Allocator(), nullptr)->AsExpression(), + modifiers, Allocator()); + overloadDef->AddOverloadDeclFlag(ir::OverloadDeclFlags::INTERFACE_METHOD); + + auto startLoc = Lexer()->GetToken().Start(); + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); + } + ArenaVector overloads(Allocator()->Adapter()); + lexer::SourcePosition endLoc; + + ParseList( + lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, + [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + + overloadDef->SetOverloadedList(std::move(overloads)); + overloadDef->SetRange({startLoc, endLoc}); + ValidateOverloadList(overloadDef->OverloadedList()); + return overloadDef; +} +void ETSParser::ThrowOptionalMethodErrorIfNeeded() +{ + if ((Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN || Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) && + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { + LogError(diagnostic::OPTIONAL_METHOD, {}); + } +} + +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind) { ir::Identifier *name = nullptr; @@ -971,11 +1147,14 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i name = AllocBrokenExpression(Lexer()->GetToken().Loc()); } else { name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(name != nullptr); name->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); } FunctionContext functionContext(this, ParserStatus::FUNCTION); + ThrowOptionalMethodErrorIfNeeded(); + lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); auto [signature, throwMarker] = ParseFunctionSignature(ParserStatus::NEED_RETURN_TYPE); @@ -1006,20 +1185,23 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i auto *func = AllocNode( Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(signature), functionContext.Flags(), flags, GetContext().GetLanguage()}); - + ES2PANDA_ASSERT(func != nullptr); if ((flags & ir::ModifierFlags::STATIC) == 0 && body == nullptr) { func->AddModifier(ir::ModifierFlags::ABSTRACT); } ValidateGetterSetter(methodKind, func->Params().size()); - func->SetRange({startLoc, GetEndLoc(body, func, Lexer())}); + func->SetRange({name->Start(), GetEndLoc(body, func, Lexer())}); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); func->SetIdent(name); + ES2PANDA_ASSERT(name->Clone(Allocator(), nullptr) != nullptr); auto *method = AllocNode(methodKind, name->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, flags, Allocator(), false); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); ConsumeSemicolon(method); @@ -1047,6 +1229,18 @@ bool ETSParser::IsFieldStartToken(lexer::TokenType tokenType) tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS; } +void ETSParser::LookForOptionalMethod(char32_t &nextCp) +{ + if (nextCp == lexer::LEX_CHAR_QUESTION) { + const auto startPos = Lexer()->Save(); + Lexer()->NextToken(); + if (Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN || Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { + nextCp = Lexer()->Lookahead(); + } + Lexer()->Rewind(startPos); + } +} + ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() { if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { @@ -1065,11 +1259,19 @@ ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() auto readonlyTok = Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY); bool isReadonly = readonlyTok.has_value(); + if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_OVERLOAD)) { + auto *overloadDeclaration = ParseInterfaceOverload(modifiers); + overloadDeclaration->SetStart(startLoc); + return overloadDeclaration; + } + LookForOptionalMethod(nextCp); + if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { if (isReadonly) { LogError(diagnostic::READONLY_INTERFACE_METHOD, {}, startLoc); } auto *method = ParseInterfaceMethod(modifiers, ir::MethodDefinitionKind::METHOD); + ES2PANDA_ASSERT(method != nullptr); method->SetStart(startLoc); return method; } @@ -1126,6 +1328,7 @@ bool ETSParser::CheckClassElement(ir::AstNode *property, [[maybe_unused]] ir::Me void ETSParser::CheckPredefinedMethods(ir::ScriptFunction const *function, const lexer::SourcePosition &position) { + ES2PANDA_ASSERT(function != nullptr); auto const name = function->Id()->Name(); auto const checkAsynchronous = [this, function, &name, &position]() -> void { @@ -1139,6 +1342,9 @@ void ETSParser::CheckPredefinedMethods(ir::ScriptFunction const *function, const bool isValid = function->Params().size() == 1U; if (isValid) { + if (function->Params()[0]->IsBrokenExpression()) { + return; + } auto const *const param = function->Params()[0]->AsETSParameterExpression(); isValid = !param->IsOptional() && !param->IsRestParameter(); } @@ -1151,6 +1357,9 @@ void ETSParser::CheckPredefinedMethods(ir::ScriptFunction const *function, const bool isValid = function->Params().size() == 2U; if (isValid) { + if (function->Params()[0]->IsBrokenExpression() || function->Params()[1]->IsBrokenExpression()) { + return; + } auto const *const param1 = function->Params()[0]->AsETSParameterExpression(); auto const *const param2 = function->Params()[1]->AsETSParameterExpression(); isValid = !param1->IsOptional() && !param1->IsRestParameter() && !param2->IsOptional() && @@ -1185,12 +1394,54 @@ void ETSParser::CreateImplicitConstructor([[maybe_unused]] ir::MethodDefinition } auto *methodDef = BuildImplicitConstructor(ir::ClassDefinitionModifiers::SET_CTOR_ID, startLoc); + ES2PANDA_ASSERT(methodDef != nullptr); if ((flags & ir::ModifierFlags::DECLARE) != 0) { - methodDef->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + auto func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } properties.push_back(methodDef); } +static bool DeclareIsModifier(lexer::Lexer *lexer) +{ + bool result = false; + auto currentPos = lexer->Save(); + if (lexer->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { + lexer->NextToken(); // eat 'declare' + switch (lexer->GetToken().KeywordType()) { + case lexer::TokenType::KEYW_LET: + case lexer::TokenType::KEYW_CONST: + case lexer::TokenType::KEYW_FUNCTION: + case lexer::TokenType::KEYW_CLASS: + case lexer::TokenType::KEYW_NAMESPACE: + case lexer::TokenType::KEYW_ENUM: + 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: + case lexer::TokenType::KEYW_STRUCT: { + result = true; + break; + } + default: { + if (lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { + result = true; + break; + } + if (lexer->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && + lexer->GetToken().Ident().Is("module")) { + result = true; + break; + } + } + } + } + lexer->Rewind(currentPos); + return result; +} + std::pair ETSParser::ParseMemberModifiers() { auto memberModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC; @@ -1203,7 +1454,10 @@ std::pair ETSParser::ParseMemberModifi if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { Lexer()->Rewind(savedPos); } + memberModifiers |= ir::ModifierFlags::EXPORT; memberModifiers |= ir::ModifierFlags::EXPORT_TYPE; + } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { + LogError(diagnostic::ERROR_ARKTS_NO_EXPORT_ASSIGNMENT); } else { memberModifiers |= ir::ModifierFlags::EXPORT; } @@ -1211,7 +1465,7 @@ std::pair ETSParser::ParseMemberModifi lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); - if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_DECLARE) { + if (DeclareIsModifier(Lexer())) { CheckDeclare(); memberModifiers |= ir::ModifierFlags::DECLARE; } @@ -1226,7 +1480,8 @@ std::pair ETSParser::ParseMemberModifi } Lexer()->NextToken(); - if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_FUNCTION) { + if (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_FUNCTION && + Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_OVERLOAD) { // async_function_bas.ets if (isAsync) { LogError(diagnostic::ASYNC_FLAG_ONLY_FOR_TOP_FUN); diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index 28614b5066fafad380f62c9c5dbac67a52fd94df..44434862cb24624894067944521b420157710561 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" @@ -149,30 +148,58 @@ ir::Statement *ETSParser::ParsePotentialConstEnum(VariableParsingFlags flags) return ParseEnumDeclaration(false); } -// NOLINTBEGIN(cert-err58-cpp) -// NOLINTEND(cert-err58-cpp) - ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, const lexer::SourcePosition &enumStart, const bool isConst, const bool isStatic) { - if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); } + ir::TypeNode *typeAnnotation = nullptr; + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { + Lexer()->NextToken(); // eat ':' + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; + typeAnnotation = ParseTypeAnnotation(&options); + + // According to a comment on ETSparser.cpp:1598, compiler can't process ": string" correctly. + // ParseTypeAnnotation reads ": string" as literal so it's not supported here for now. + auto startPos = Lexer()->GetToken().Start(); + if (!typeAnnotation->IsETSPrimitiveType()) { + LogError(diagnostic::UNSUPPORTED_ENUM_TYPE, {}, startPos); + typeAnnotation = nullptr; + } else { + ir::PrimitiveType primitiveType = typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType(); + if (primitiveType != ir::PrimitiveType::INT && primitiveType != ir::PrimitiveType::LONG && + primitiveType != ir::PrimitiveType::DOUBLE) { + // Issue: #26024 Numeric support for enum + LogError(diagnostic::UNSUPPORTED_ENUM_TYPE, {}, startPos); + typeAnnotation = nullptr; + } + } + } Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat '{' - 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); - auto *const enumDeclaration = AllocNode( - Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}); + ir::TSEnumDeclaration *enumDeclaration; + + if (typeAnnotation == nullptr) { + enumDeclaration = AllocNode( + Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, + GetContext().GetLanguage()); + } else { + enumDeclaration = AllocNode( + Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, typeAnnotation, + GetContext().GetLanguage()); + } + + ES2PANDA_ASSERT(enumDeclaration != nullptr); + if (InAmbientContext()) { enumDeclaration->AddModifier(ir::ModifierFlags::DECLARE); } diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 594c038963bd7c8ec51e48b6b83b5705e937aff9..f1cd269a67a4657c5c4fdef72b7a06fd81b8256c 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -15,40 +15,15 @@ #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(); @@ -66,6 +41,7 @@ static std::string GetArgumentsSourceView(lexer::Lexer *lexer, const util::Strin ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent, bool isOptional) { ir::ETSParameterExpression *paramExpression; + ES2PANDA_ASSERT(paramIdent != nullptr); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { auto const lexerPos = Lexer()->Save().Iterator(); Lexer()->NextToken(); // eat '=' @@ -89,19 +65,22 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress auto defaultValue = ParseExpression(); if (!paramIdent->IsIdentifier()) { LogError(diagnostic::IDENTIFIER_EXPECTED); - return nullptr; + return AllocBrokenExpression(Lexer()->GetToken().Loc()); } paramExpression = AllocNode(paramIdent->AsIdentifier(), defaultValue, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); std::string value = GetArgumentsSourceView(Lexer(), lexerPos); paramExpression->SetLexerSaved(util::UString(value, Allocator()).View()); paramExpression->SetRange({paramIdent->Start(), paramExpression->Initializer()->End()}); } else if (paramIdent->IsIdentifier()) { paramExpression = AllocNode(paramIdent->AsIdentifier(), isOptional, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } else { paramExpression = AllocNode(paramIdent->AsRestElement(), false, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } return paramExpression; @@ -128,14 +107,24 @@ ir::Expression *ETSParser::ResolveArgumentUnaryExpr(ExpressionParseFlags flags) ir::Expression *ETSParser::CreateUnaryExpressionFromArgument(ir::Expression *argument, lexer::TokenType operatorType, char32_t beginningChar) { + auto checkLiteral = [argument, beginningChar]() -> bool { + ir::NumberLiteral *literal = nullptr; + if (argument->IsNumberLiteral()) { + literal = argument->AsNumberLiteral(); + } else if (argument->IsCallExpression() && argument->AsCallExpression()->Callee()->IsMemberExpression() && + argument->AsCallExpression()->Callee()->AsMemberExpression()->Object()->IsNumberLiteral()) { + literal = argument->AsCallExpression()->Callee()->AsMemberExpression()->Object()->AsNumberLiteral(); + } + return literal != nullptr && ((beginningChar >= '0' && beginningChar <= '9') || (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 if (operatorType == lexer::TokenType::PUNCTUATOR_MINUS && checkLiteral()) { + returnExpr = argument; } else { returnExpr = AllocNode(argument, operatorType); } @@ -143,16 +132,8 @@ ir::Expression *ETSParser::CreateUnaryExpressionFromArgument(ir::Expression *arg return returnExpr; } -// NOLINTNEXTLINE(google-default-arguments) -ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags) +static bool IsLeftHandSideExpression(lexer::TokenType &operatorType, lexer::NextTokenFlags &tokenFlags) { - 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: tokenFlags = lexer::NextTokenFlags::UNARY_MINUS; @@ -162,15 +143,34 @@ 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: { - break; - } - case lexer::TokenType::KEYW_LAUNCH: { - return ParseLaunchExpression(flags); - } - default: { - return ParseLeftHandSideExpression(flags); - } + case lexer::TokenType::KEYW_TYPEOF: + case lexer::TokenType::KEYW_AWAIT: + return false; + default: + return true; + } +} + +ir::Expression *ETSParser::HandleDeepNesting() +{ + LogError(diagnostic::DEEP_NESTING); + while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + Lexer()->NextToken(); + } + return AllocBrokenExpression(Lexer()->GetToken().Start()); +} + +// NOLINTNEXTLINE(google-default-arguments) +ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags) +{ + TrackRecursive trackRecursive(RecursiveCtx()); + if (!trackRecursive) { + return HandleDeepNesting(); + } + auto tokenFlags = lexer::NextTokenFlags::NONE; + lexer::TokenType operatorType = Lexer()->GetToken().Type(); + if (IsLeftHandSideExpression(operatorType, tokenFlags)) { + return ParseLeftHandSideExpression(flags); } char32_t beginningChar = Lexer()->Lookahead(); @@ -178,6 +178,13 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla Lexer()->NextToken(tokenFlags); ir::Expression *argument = ResolveArgumentUnaryExpr(flags); + if (operatorType == lexer::TokenType::KEYW_AWAIT) { + auto *awaitExpr = AllocNode(argument); + ES2PANDA_ASSERT(awaitExpr != nullptr); + awaitExpr->SetRange({start, argument->End()}); + return awaitExpr; + } + if (argument == nullptr) { return nullptr; } @@ -189,6 +196,7 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla } ir::Expression *returnExpr = CreateUnaryExpressionFromArgument(argument, operatorType, beginningChar); + ES2PANDA_ASSERT(returnExpr != nullptr); returnExpr->SetRange({start, argument->End()}); return returnExpr; } @@ -219,12 +227,14 @@ ir::Expression *ETSParser::ParsePropertyDefinition(ExpressionParseFlags flags) ir::Expression *key = ParsePropertyKey(flags); ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); + ES2PANDA_ASSERT(value != nullptr); lexer::SourcePosition end = value->End(); ir::Expression *returnProperty = nullptr; if (propertyKind == ir::PropertyKind::INIT) { returnProperty = AllocNode(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); } else { returnProperty = AllocBrokenExpression(key->Start()); @@ -234,6 +244,57 @@ 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); +} + +ir::Expression *ETSParser::ParsePropertyKey([[maybe_unused]] ExpressionParseFlags flags) +{ + ir::Expression *key = nullptr; + + switch (Lexer()->GetToken().Type()) { + case lexer::TokenType::LITERAL_IDENT: { + const util::StringView &ident = Lexer()->GetToken().Ident(); + key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + case lexer::TokenType::LITERAL_STRING: { + const util::StringView &string = Lexer()->GetToken().String(); + key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + case lexer::TokenType::LITERAL_NUMBER: { + if ((Lexer()->GetToken().Flags() & lexer::TokenFlags::NUMBER_BIGINT) != 0) { + key = AllocNode(Lexer()->GetToken().BigInt()); + } else { + key = AllocNode(Lexer()->GetToken().GetNumber()); + } + ES2PANDA_ASSERT(key != nullptr); + key->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return key; + } + default: { + const auto &rangeToken = Lexer()->GetToken().Loc(); + LogError(diagnostic::UNEXPECTED_TOKEN); + Lexer()->NextToken(); + return AllocBrokenExpression(rangeToken); + } + } +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags) { @@ -253,9 +314,11 @@ ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags fl Lexer()->NextToken(); // eat '.' } - if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) { + if ((Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) && + potentialType->IsBrokenTypeNode()) { Lexer()->NextToken(); // eat 'class' and 'struct' auto *classLiteral = AllocNode(potentialType); + ES2PANDA_ASSERT(classLiteral != nullptr); classLiteral->SetRange({startLoc, Lexer()->GetToken().End()}); return classLiteral; } @@ -265,8 +328,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(); @@ -274,8 +342,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()); } @@ -307,26 +376,12 @@ 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 HandleLeftParanthesis(this, flags); + return ParseCoverParenthesizedExpressionAndArrowParameterList(flags); } case lexer::TokenType::KEYW_THIS: { return ParseThisExpression(); @@ -354,9 +409,13 @@ ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) } case lexer::TokenType::KEYW_TYPE: { LogError(diagnostic::TYPE_ALIAS_ONLY_TOP_LEVEL); - const auto &rangeToken = Lexer()->GetToken().Loc(); ParseTypeAliasDeclaration(); // Try to parse type alias and drop the result. - return AllocBrokenExpression(rangeToken); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); + } + case lexer::TokenType::KEYW_FUNCTION: { + LogError(diagnostic::FUNC_EXPR); + ParseFunctionDeclaration(true, ir::ModifierFlags::NONE); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); } case lexer::TokenType::PUNCTUATOR_FORMAT: { return ParseExpressionFormatPlaceholder(); @@ -468,6 +527,7 @@ ir::ArrowFunctionExpression *ETSParser::ParseArrowFunctionExpression() auto newStatus = ParserStatus::ARROW_FUNCTION | ParserStatus::ALLOW_RECEIVER; auto *func = ParseFunction(newStatus); auto *arrowFuncNode = AllocNode(func, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(func->Range()); return arrowFuncNode; } @@ -490,6 +550,12 @@ ir::Expression *ETSParser::ParseCoverParenthesizedExpressionAndArrowParameterLis ir::Expression *expr = ParseExpression(newFlags); + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { + LogError(diagnostic::ERROR_ARKTS_NO_COMMA_OUTSIDE_LOOPS); + auto sequenceExpression = ParseSequenceExpression(expr); + Lexer()->NextToken(); + return AllocBrokenExpression(sequenceExpression->Range()); + } if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); } @@ -564,8 +630,9 @@ ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExp [[maybe_unused]] bool *isChainExpression) { ir::Expression *returnExpression = primaryExpr; + WhileLoopGuard guard; - while (true) { + while (guard.ShouldContinue()) { auto expr = GetPostPrimaryExpression(returnExpression, startLoc, ignoreCallExpression, isChainExpression); if (expr.has_value()) { returnExpression = expr.value(); @@ -575,6 +642,10 @@ ir::Expression *ETSParser::ParsePostPrimaryExpression(ir::Expression *primaryExp break; } + if (guard.IsLimitReached()) { + return HandleDeepNesting(); + } + return returnExpression; } @@ -582,7 +653,10 @@ ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExp { ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS); Lexer()->NextToken(); - + if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CONST) { + LogError(diagnostic::AS_CONST_USAGE); + return nullptr; + } TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; ir::TypeNode *type = ParseTypeAnnotation(&options); @@ -593,7 +667,9 @@ ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExp } auto *asExpression = AllocNode(primaryExpr, type, false); - asExpression->SetRange(primaryExpr->Range()); + ES2PANDA_ASSERT(asExpression != nullptr); + asExpression->SetStart(primaryExpr->Start()); + asExpression->SetEnd(type->End()); return asExpression; } @@ -660,6 +736,7 @@ ir::Expression *ETSParser::ParseNewExpression() } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); auto *multiArray = AllocNode(typeReference, std::move(dimensions)); + ES2PANDA_ASSERT(multiArray != nullptr); multiArray->SetRange({start, endLoc}); return multiArray; } @@ -668,6 +745,7 @@ ir::Expression *ETSParser::ParseNewExpression() ParseArgumentsNewExpression(arguments, typeReference); auto *newExprNode = AllocNode(typeReference, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, Lexer()->GetToken().End()}); return newExprNode; @@ -676,6 +754,11 @@ ir::Expression *ETSParser::ParseNewExpression() ir::Expression *ETSParser::ParseAsyncExpression() { Lexer()->NextToken(); // eat 'async' + if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION) { + LogError(diagnostic::FUNC_EXPR); + ParseFunctionDeclaration(true, ir::ModifierFlags::NONE); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); + } if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || !IsArrowFunctionExpressionStart()) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); @@ -687,6 +770,7 @@ ir::Expression *ETSParser::ParseAsyncExpression() return nullptr; } auto *arrowFuncNode = AllocNode(func, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(func->Range()); return arrowFuncNode; } @@ -697,6 +781,7 @@ ir::Expression *ETSParser::ParseAwaitExpression() Lexer()->NextToken(); ir::Expression *argument = ParseExpression(); auto *awaitExpression = AllocNode(argument); + ES2PANDA_ASSERT(awaitExpression != nullptr); awaitExpression->SetRange({start, Lexer()->GetToken().End()}); return awaitExpression; } @@ -723,6 +808,7 @@ bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, con } const auto nonNullExpr = AllocNode(*expression); + ES2PANDA_ASSERT(nonNullExpr != nullptr); nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()}); *expression = nonNullExpr; @@ -750,35 +836,78 @@ void ETSParser::ValidateInstanceOfExpression(ir::Expression *expr) } } +ir::Expression *ETSParser::ParseGenericLambdaOrTypeAssertion() +{ + ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN); + const auto savedPosition = Lexer()->Save(); + const auto start = Lexer()->GetToken().Start(); + const auto arrowStart = DiagnosticEngine().Save(); + if (ir::Expression *expr = ParseGenericArrowFunction(); expr != nullptr) { + LogError(diagnostic::GENERIC_LAMBDA_NOT_SUPPORTED, util::DiagnosticMessageParams {}, start); + return AllocBrokenExpression(expr->Range()); + } + const auto afterArrow = DiagnosticEngine().Save(); + Lexer()->Rewind(savedPosition); + if (const ir::Expression *typeAssertion = ParseTypeAssertion(); typeAssertion != nullptr) { + DiagnosticEngine().UndoRange(arrowStart, afterArrow); + LogError(diagnostic::TS_TYPE_ASSERTION, util::DiagnosticMessageParams {}, start); + ES2PANDA_ASSERT(DiagnosticEngine().IsAnyError()); + return AllocBrokenExpression(typeAssertion->Range()); + } + DiagnosticEngine().Rollback(afterArrow); + ES2PANDA_ASSERT(DiagnosticEngine().IsAnyError()); + return AllocBrokenExpression(lexer::SourceRange {start, Lexer()->GetToken().End()}); +} + +void ETSParser::ValidateKeywordIn() +{ + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_IN) { + LogError(diagnostic::ERROR_ARKTS_NO_IN_OPERATOR); + Lexer()->NextToken(); // eat 'in' + if (auto const tokenType = Lexer()->GetToken().Type(); tokenType == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + ParseObjectExpression(); + } else if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { + ParseArrayExpression(ExpressionParseFlags::NO_OPTS); + } else { + Lexer()->NextToken(); + } + } +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags) { + TrackRecursive trackRecursive(RecursiveCtx()); + if (!trackRecursive) { + return HandleDeepNesting(); + } ArenaVector annotations {Allocator()->Adapter()}; if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { annotations = ParseAnnotations(false); } - auto savedPos = Lexer()->GetToken().Start(); + const auto start = Lexer()->GetToken().Start(); if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD && (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) { ir::YieldExpression *yieldExpr = ParseYieldExpression(); return ParsePotentialExpressionSequence(yieldExpr, flags); } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { + return ParseGenericLambdaOrTypeAssertion(); + } ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags); + ValidateKeywordIn(); if ((flags & ExpressionParseFlags::INSTANCEOF) != 0) { ValidateInstanceOfExpression(unaryExpressionNode); } ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags); - ApplyAnnotationsToNode(assignmentExpression, std::move(annotations), savedPos); + ApplyAnnotationsToNode(assignmentExpression, std::move(annotations), start); - if (Lexer()->GetToken().NewLine()) { - return assignmentExpression; - } - - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && - (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U) { + if (!Lexer()->GetToken().NewLine() && + (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA && + (flags & ExpressionParseFlags::ACCEPT_COMMA) != 0U && (flags & ExpressionParseFlags::IN_FOR) != 0U)) { return ParseSequenceExpression(assignmentExpression, (flags & ExpressionParseFlags::ACCEPT_REST) != 0U); } diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index 47f37b6f42910e4ef842685cd582e22d5e20a549..6909d6890faadefead0e136a000b713eff1530d7 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -58,31 +58,33 @@ ir::Statement *ETSParser::ParseNamespace(ir::ModifierFlags flags) if ((GetContext().Status() & ParserStatus::IN_NAMESPACE) == 0) { LogError(diagnostic::NAMESPACE_ONLY_TOP_OR_IN_NAMESPACE); } - auto start = Lexer()->GetToken().Start(); ir::ETSModule *ns = ParseNamespaceImp(flags); - ns->SetRange({start, Lexer()->GetToken().Start()}); + ES2PANDA_ASSERT(ns != nullptr); return ns; } ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) { + auto nsStart = Lexer()->GetToken().Start(); Lexer()->NextToken(); - auto *result = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), - ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, globalProgram_); + auto *result = + AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), ExpectIdentifier(), + ir::ModuleFlag::NAMESPACE, GetContext().GetLanguage(), globalProgram_); ir::ETSModule *parent = result; ir::ETSModule *child = nullptr; while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { Lexer()->NextToken(); auto start = Lexer()->GetToken().Start(); child = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), - ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, globalProgram_); + ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, GetContext().GetLanguage(), + globalProgram_); child->SetParent(parent); child->SetRange({start, Lexer()->GetToken().Start()}); child->AddModifier(ir::ModifierFlags::EXPORT); 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); @@ -99,6 +101,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) auto st = ParseTopLevelStatement(); statements.emplace_back(st); } + auto nsEnd = Lexer()->GetToken().End(); Lexer()->NextToken(); if (child != nullptr) { child->SetNamespaceChainLastNode(); @@ -108,6 +111,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) result->SetStatements(std::move(statements)); } result->AddModifier(flags); + result->SetRange({nsStart, nsEnd}); return result; } diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index e50e64f2c5bbe2db44035a075eaa239f1df5fb01..bb7d3f6db0e6f009aa5414a9d115b164e3732e4d 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -20,6 +20,7 @@ #include "parser/parserFlags.h" #include "util/errorRecovery.h" #include "util/helpers.h" +#include "util/importPathManager.h" #include "utils/arena_containers.h" #include "varbinder/varbinder.h" #include "varbinder/ETSBinder.h" @@ -72,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" @@ -145,10 +145,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 +152,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 +161,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,20 +173,18 @@ 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; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP, G.FUD.05) solid logic, big switch case 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); } @@ -202,6 +193,7 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags switch (token.Type()) { case lexer::TokenType::KEYW_FUNCTION: { result = ParseFunctionDeclaration(false, memberModifiers); + ES2PANDA_ASSERT(result != nullptr); result->SetStart(startLoc); break; } @@ -219,6 +211,9 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags case lexer::TokenType::KEYW_CLASS: result = ParseTypeDeclaration(IsInitializerBlockStart()); break; + case lexer::TokenType::KEYW_OVERLOAD: + result = ParseOverloadDeclaration(memberModifiers); + break; case lexer::TokenType::PUNCTUATOR_AT: result = ParseTopLevelAnnotation(memberModifiers); break; @@ -236,6 +231,10 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags } } + if (result == nullptr && IsExportedDeclaration(memberModifiers)) { + return ParseExport(startLoc, memberModifiers); + } + return ValidateExportableStatement(this, result, memberModifiers, startLoc); } @@ -250,6 +249,34 @@ ir::Statement *ETSParser::ParseTopLevelStatement() return result; } +ir::Statement *ETSParser::ParseInitModuleStatement(StatementParsingFlags flags) +{ + auto startLoc = Lexer()->GetToken().Start(); + if ((flags & StatementParsingFlags::INIT_MODULE) == 0) { + LogError(diagnostic::INIT_MODULE_DECLARATION_POSITION); + return AllocBrokenStatement(startLoc); + } + + auto *callee = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + Lexer()->NextToken(); // eat initModule + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + return AllocBrokenStatement(startLoc); + } + ir::CallExpression *expr = ParseCallExpression(callee, false, false); + expr->SetRange({startLoc, Lexer()->GetToken().End()}); + if (expr->Arguments().size() != 1 || !expr->Arguments().front()->IsStringLiteral()) { + LogError(diagnostic::ONLY_STRING_LITERAL_IN_INIT_MODULE, {}, expr->Start()); + return AllocBrokenStatement(startLoc); + } + // In order to build relationship between the current program and initModule program. + importPathManager_->GatherImportMetadata(const_cast(GetContext().GetProgram()), + util::ImportFlags::NONE, expr->Arguments().front()->AsStringLiteral()); + auto initModuleStatement = AllocNode(expr); + ConsumeSemicolon(initModuleStatement); + return initModuleStatement; +} + ir::Statement *ETSParser::ParseAnnotationsInStatement(StatementParsingFlags flags) { Lexer()->NextToken(); // eat '@' @@ -283,13 +310,13 @@ bool ETSParser::ValidateLabeledStatement(lexer::TokenType type) bool ETSParser::ValidateForInStatement() { - LogUnexpectedToken(lexer::TokenType::KEYW_IN); + LogError(diagnostic::ERROR_ARKTS_NO_FOR_IN_LOOP); return false; } ir::Statement *ETSParser::ParseDebuggerStatement() { - LogUnexpectedToken(lexer::TokenType::KEYW_DEBUGGER); + LogError(diagnostic::ERROR_ARKTS_NO_DEBUGGER_STATEMENT); return AllocBrokenStatement(Lexer()->GetToken().Loc()); } @@ -323,7 +350,7 @@ ir::Statement *ETSParser::ParseTryStatement() if (catchClauses.empty() && finalizer == nullptr) { LogError(diagnostic::MISSING_CATCH_OR_FINALLY_AFTER_TRY, {}, startLoc); - return nullptr; + return AllocBrokenStatement(startLoc); } lexer::SourcePosition endLoc = finalizer != nullptr ? finalizer->End() : catchClauses.back()->End(); @@ -331,6 +358,7 @@ ir::Statement *ETSParser::ParseTryStatement() ArenaVector> finalizerInsertions(Allocator()->Adapter()); auto *tryStatement = AllocNode(body, std::move(catchClauses), finalizer, finalizerInsertions); + ES2PANDA_ASSERT(tryStatement != nullptr); tryStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(tryStatement); @@ -342,9 +370,13 @@ ir::Statement *ETSParser::ParseClassStatement([[maybe_unused]] StatementParsingF ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { modFlags |= ParseClassModifiers(); - return ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | - ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, - modFlags); + const auto &rangeClass = Lexer()->GetToken().Loc(); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"CLASS"}, rangeClass.start); + // Try to parse class and drop the result. + ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | + ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, + modFlags); + return AllocBrokenStatement(rangeClass); } // NOLINTNEXTLINE(google-default-arguments) @@ -352,11 +384,39 @@ ir::Statement *ETSParser::ParseStructStatement([[maybe_unused]] StatementParsing ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { const auto &rangeStruct = Lexer()->GetToken().Loc(); - LogError(diagnostic::ILLEGAL_START_STRUCT, {}, rangeStruct.start); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"STRUCT"}, rangeStruct.start); + // Try to parse struct and drop the result. ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, - modFlags); // Try to parse struct and drop the result. + modFlags); return AllocBrokenStatement(rangeStruct); } +ir::Statement *ETSParser::ParseInterfaceStatement([[maybe_unused]] StatementParsingFlags flags) +{ + auto &rangeClass = Lexer()->GetToken().Loc(); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"INTERFACE"}, Lexer()->GetToken().Start()); + ParseInterfaceDeclaration(false); + return AllocBrokenStatement(rangeClass); +} + +ir::Statement *ETSParser::ParseEnumStatement([[maybe_unused]] StatementParsingFlags flags) +{ + auto &rangeClass = Lexer()->GetToken().Loc(); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"ENUM"}, Lexer()->GetToken().Start()); + ParseEnumDeclaration(); + return AllocBrokenStatement(rangeClass); +} + +ir::Statement *ETSParser::ParseTypeAliasStatement() +{ + auto &rangeClass = Lexer()->GetToken().Loc(); + lexer::SourcePosition start = rangeClass.start; + if (ParseTypeAliasDeclaration() == nullptr) { + return nullptr; + } + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"Type Alias"}, start); + return AllocBrokenStatement(rangeClass); +} + } // namespace ark::es2panda::parser 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 7c247dcb73f4ec2783f47f50decaf280bcb13168..b2da373d7fed73c1471bb15fa7fcc69bf92e8057 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" @@ -100,6 +99,7 @@ ir::TypeNode *ETSParser::ParsePrimitiveType(TypeAnnotationParsingOptions *option } auto *const typeAnnotation = AllocNode(type, Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return typeAnnotation; @@ -122,6 +122,7 @@ ir::TypeNode *ETSParser::ParseUnionType(ir::TypeNode *const firstType) auto const endLoc = types.back()->End(); auto *const unionType = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(unionType != nullptr); unionType->SetRange({firstType->Start(), endLoc}); return unionType; } @@ -177,10 +178,12 @@ ir::TypeNode *ETSParser::ParseWildcardType(TypeAnnotationParsingOptions *options ir::ETSTypeReference *typeReference = nullptr; if (!isUnboundOut) { auto reference = ParseTypeReference(options); + ES2PANDA_ASSERT(reference != nullptr); typeReference = reference->AsETSTypeReference(); } auto *wildcardType = AllocNode(typeReference, varianceModifier, Allocator()); + ES2PANDA_ASSERT(wildcardType != nullptr); wildcardType->SetRange({varianceStartLoc, typeReference == nullptr ? varianceEndLoc : typeReference->End()}); return wildcardType; @@ -195,6 +198,7 @@ ir::TypeNode *ETSParser::ParseFunctionType(TypeAnnotationParsingOptions *options if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_ARROW)) { if (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW); + return AllocBrokenType(Lexer()->GetToken().Loc()); } return nullptr; } @@ -209,9 +213,9 @@ ir::TypeNode *ETSParser::ParseFunctionType(TypeAnnotationParsingOptions *options return nullptr; } - ir::ScriptFunctionFlags throwMarker = ParseFunctionThrowMarker(false); auto *funcType = AllocNode( - ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation, hasReceiver), throwMarker, Allocator()); + ir::FunctionSignature(nullptr, std::move(params), returnTypeAnnotation, hasReceiver), + ir::ScriptFunctionFlags::NONE, Allocator()); funcType->SetRange({startLoc, returnTypeAnnotation->End()}); return funcType; @@ -262,6 +266,7 @@ ir::TypeNode *ETSParser::ParseETSTupleType(TypeAnnotationParsingOptions *const o lexer::SourcePosition endLoc; ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE, parseElem, &endLoc, true); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->SetTypeAnnotationsList(std::move(tupleTypeList)); tupleType->SetRange({startLoc, endLoc}); @@ -307,12 +312,38 @@ ir::TypeNode *ETSParser::ParsePotentialFunctionalType(TypeAnnotationParsingOptio return nullptr; } +std::pair ETSParser::ParseNonNullableType(TypeAnnotationParsingOptions *options) +{ + ES2PANDA_ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NON_NULLABLE); + Lexer()->NextToken(); // eat NonNullable + + ExpectToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, true); + auto *const typeAnnotation = ParseTypeAnnotation(options); + ParsePunctuatorGreaterThan(); + return std::make_pair(AllocNode(typeAnnotation, Allocator()), true); +} + +// Helper function to reduce line count of GetTypeAnnotationFromToken(...) +void ETSParser::CheckForConditionalTypeError(TypeAnnotationParsingOptions options, lexer::TokenType tokenType) +{ + if ((options & TypeAnnotationParsingOptions::TYPE_ALIAS_CONTEXT) != 0 && + (tokenType == lexer::TokenType::KEYW_EXTENDS || tokenType == lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { + LogError(diagnostic::ERROR_ARKTS_NO_CONDITIONAL_TYPES); + } +} + +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic // Just to reduce the size of ParseTypeAnnotation(...) method std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options) { - auto tokenType = Lexer()->GetToken().Type(); - if (IsPrimitiveType(Lexer()->GetToken().KeywordType()) || tokenType == lexer::TokenType::LITERAL_IDENT) { + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_NON_NULLABLE) { + return ParseNonNullableType(options); + } + + if (IsPrimitiveType(Lexer()->GetToken().KeywordType()) || + Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { auto typeAnnotation = ParseLiteralIdent(options); + CheckForConditionalTypeError(*options, Lexer()->GetToken().Type()); if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { return std::make_pair(typeAnnotation, false); @@ -320,24 +351,19 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota return std::make_pair(typeAnnotation, true); } - switch (tokenType) { + ir::TypeNode *typeAnnotation; + switch (Lexer()->GetToken().Type()) { case lexer::TokenType::LITERAL_NULL: { - auto typeAnnotation = AllocNode(Allocator()); - typeAnnotation->SetRange(Lexer()->GetToken().Loc()); - Lexer()->NextToken(); - return std::make_pair(typeAnnotation, true); + typeAnnotation = AllocNode(Allocator()); + break; } case lexer::TokenType::KEYW_UNDEFINED: { - auto typeAnnotation = AllocNode(Allocator()); - typeAnnotation->SetRange(Lexer()->GetToken().Loc()); - Lexer()->NextToken(); - return std::make_pair(typeAnnotation, true); + typeAnnotation = AllocNode(Allocator()); + break; } case lexer::TokenType::LITERAL_STRING: { - auto typeAnnotation = AllocNode(Lexer()->GetToken().String(), Allocator()); - typeAnnotation->SetRange(Lexer()->GetToken().Loc()); - Lexer()->NextToken(); - return std::make_pair(typeAnnotation, true); + typeAnnotation = AllocNode(Lexer()->GetToken().String(), Allocator()); + break; } case lexer::TokenType::PUNCTUATOR_BACK_TICK: { return std::make_pair(ParseMultilineString(), true); @@ -351,10 +377,25 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota return std::make_pair(ParseETSTupleType(options), true); case lexer::TokenType::KEYW_THIS: return std::make_pair(ParseThisType(options), true); + case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: + if (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { + auto startPos = Lexer()->GetToken().Start(); + auto modifiers = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL | + ir::ClassDefinitionModifiers::DECLARATION; + auto flags = ir::ModifierFlags::NONE; + ParseClassBody(modifiers, flags); + LogError(diagnostic::ERROR_ARKTS_NO_OBJ_LITERAL_TO_DECL_TYPE, {}, startPos); + return {AllocBrokenType({startPos, Lexer()->GetToken().End()}), false}; + } + [[fallthrough]]; default: { return {nullptr, true}; } } + ES2PANDA_ASSERT(typeAnnotation != nullptr); + typeAnnotation->SetRange(Lexer()->GetToken().Loc()); + Lexer()->NextToken(); + return std::make_pair(typeAnnotation, true); } std::pair ETSParser::GetTypeAnnotationFromParentheses(TypeAnnotationParsingOptions *options) @@ -371,6 +412,7 @@ std::pair ETSParser::GetTypeAnnotationFromParentheses(Type if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS)) { if (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + return {AllocBrokenType(Lexer()->GetToken().Loc()), false}; } return {nullptr, false}; } @@ -391,7 +433,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) || @@ -420,20 +462,36 @@ ir::TypeNode *ETSParser::ParseThisType(TypeAnnotationParsingOptions *options) bool parseReturnType = (*options & TypeAnnotationParsingOptions::RETURN_TYPE) != 0; bool isExtensionFunction = (GetContext().Status() & ParserStatus::HAS_RECEIVER) != 0; bool isInUnion = (*options & TypeAnnotationParsingOptions::DISALLOW_UNION) != 0; + bool isInstance = (*options & TypeAnnotationParsingOptions::INSTANCEOF) != 0; if (isExtensionFunction) { if (reportErr && (!IsSimpleReturnThis(Lexer()->GetToken()) || isInUnion)) { LogError(diagnostic::THIS_IN_NON_STATIC_METHOD, {}, startPos); } + } else if (reportErr && (isInstance)) { + LogError(diagnostic::INVALID_RIGHT_INSTANCEOF, {}, startPos); } else if (reportErr && (!allowThisType || !parseReturnType || isArrowFunc)) { LogError(diagnostic::THIS_IN_NON_STATIC_METHOD, {}, startPos); } auto *const thisType = AllocNode(Allocator()); + ES2PANDA_ASSERT(thisType != nullptr); thisType->SetRange(tokenLoc); return thisType; } +ir::TypeNode *ETSParser::CreateErrorForWrongArrayType(lexer::SourcePosition &startPos) +{ + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_STRING) { + LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); + } else { + Lexer()->NextToken(); // eat string lteral + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); + LogError(diagnostic::INDEXED_ACCESS_TYPE, {}, startPos); + } + return AllocBrokenType({startPos, Lexer()->GetToken().End()}); +} + ir::TypeNode *ETSParser::ParseTsArrayType(ir::TypeNode *typeNode, TypeAnnotationParsingOptions *options) { while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { @@ -447,9 +505,9 @@ 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 CreateErrorForWrongArrayType(startPos); } - return nullptr; + return AllocBrokenType(startPos); } typeNode = AllocNode(typeNode, Allocator()); @@ -466,29 +524,30 @@ ir::TypeNode *ETSParser::ParseTypeAnnotationNoPreferParam(TypeAnnotationParsingO if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { annotations = ParseAnnotations(false); } + auto startPos = Lexer()->GetToken().Start(); auto [typeAnnotation, needFurtherProcessing] = GetTypeAnnotationFromToken(options); if (typeAnnotation == nullptr) { if (reportError) { LogError(diagnostic::INVALID_TYPE); - auto typeNode = AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); - return typeNode; } - return nullptr; + return AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); } - if (!needFurtherProcessing) { + if (((*options) & TypeAnnotationParsingOptions::DISALLOW_UNION) == 0 && + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_BITWISE_AND)) { + LogError(diagnostic::INTERSECTION_TYPES); + Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT); + return AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); + } + + if (!needFurtherProcessing || typeAnnotation->IsBrokenTypeNode()) { return typeAnnotation; } typeAnnotation = ParseTsArrayType(typeAnnotation, options); - if (((*options) & TypeAnnotationParsingOptions::DISALLOW_UNION) == 0 && - Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) { - ApplyAnnotationsToNode(typeAnnotation, std::move(annotations), startPos); - return ParseUnionType(typeAnnotation); - } ApplyAnnotationsToNode(typeAnnotation, std::move(annotations), startPos, *options); return typeAnnotation; } @@ -507,20 +566,32 @@ bool ETSParser::ParseReadonlyInTypeAnnotation() return false; } +static bool IsReadonlyApplicableType(ir::TypeNode *typeNode) +{ + return typeNode->IsTSArrayType() || typeNode->IsETSTuple() || + (typeNode->IsETSTypeReference() && + typeNode->AsETSTypeReference()->BaseName()->Name() == compiler::Signatures::ARRAY); +} + ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) { 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)) { - 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 ((*options & + (TypeAnnotationParsingOptions::DISALLOW_UNION | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW)) == 0 && + Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_TYPEOF)) { + LogError(diagnostic::TYPEOF_IN_ANNOTATION); + return AllocBrokenType(Lexer()->GetToken().Loc()); + } + + bool hasReadonly = Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_READONLY); + + auto typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + if (typeAnnotation->IsBrokenTypeNode()) { + return typeAnnotation; + } + + if (hasReadonly) { + if (!IsReadonlyApplicableType(typeAnnotation)) { if (!ParseReadonlyInTypeAnnotation()) { LogError(diagnostic::READONLY_ONLY_ON_ARRAY_OR_TUPLE); } else { @@ -529,9 +600,14 @@ ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *optio } typeAnnotation->SetStart(startPos); typeAnnotation->AddModifier(ir::ModifierFlags::READONLY_PARAMETER); - return typeAnnotation; } - return ParseTypeAnnotationNoPreferParam(options); + + if (((*options) & TypeAnnotationParsingOptions::DISALLOW_UNION) == 0 && + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) { + return ParseUnionType(typeAnnotation); + } + + return typeAnnotation; } ir::TypeNode *ETSParser::ParseMultilineString() @@ -541,6 +617,7 @@ ir::TypeNode *ETSParser::ParseMultilineString() Lexer()->ScanTemplateStringEnd(); auto typeAnnotation = AllocNode(multilineStr, Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange({startPos, Lexer()->GetToken().End()}); Lexer()->NextToken(); diff --git a/ets2panda/parser/JsdocHelper.cpp b/ets2panda/parser/JsdocHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3e75ea9a63636b99be1890c64367b0846e9a36b --- /dev/null +++ b/ets2panda/parser/JsdocHelper.cpp @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "JsdocHelper.h" +#include +#include "lexer/lexer.h" +#include "ir/ets/etsTuple.h" +#include "ir/statements/annotationDeclaration.h" + +namespace ark::es2panda::parser { +static constexpr std::string_view JSDOC_END = "*/"; +static constexpr std::string_view EMPTY_JSDOC = "Empty Jsdoc"; + +static constexpr size_t START_POS = 0; +static constexpr size_t COLLECT_CURRENT_POS = 1; + +// NOLINTBEGIN(modernize-avoid-c-arrays) +static constexpr std::string_view POTENTIAL_PREFIX[] = { + "@", "get", "set", "let", "const", "overload", "async", "readonly", + "abstract", "native", "static", "public", "private", "declare", "default", "export"}; +// NOLINTEND(modernize-avoid-c-arrays) + +// Note: Potential annotation allowed node need to collect jsdoc. +// NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) +static const std::unordered_set ANNOTATION_ALLOWED_NODE = { + ir::AstNodeType::METHOD_DEFINITION, ir::AstNodeType::CLASS_DECLARATION, + ir::AstNodeType::STRUCT_DECLARATION, ir::AstNodeType::FUNCTION_DECLARATION, + ir::AstNodeType::TS_INTERFACE_DECLARATION, ir::AstNodeType::CLASS_PROPERTY, + ir::AstNodeType::VARIABLE_DECLARATION, ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, + ir::AstNodeType::ARROW_FUNCTION_EXPRESSION, ir::AstNodeType::ANNOTATION_DECLARATION}; +// NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) + +static const ArenaVector &GetAstAnnotationUsage(const ir::AstNode *node) +{ + switch (node->Type()) { + case ir::AstNodeType::METHOD_DEFINITION: { + auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + return func->Annotations(); + } + case ir::AstNodeType::CLASS_DECLARATION: + return node->AsClassDeclaration()->Definition()->Annotations(); + case ir::AstNodeType::FUNCTION_DECLARATION: + return node->AsFunctionDeclaration()->Annotations(); + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + return node->AsTSInterfaceDeclaration()->Annotations(); + case ir::AstNodeType::CLASS_PROPERTY: + return node->AsClassProperty()->Annotations(); + case ir::AstNodeType::VARIABLE_DECLARATION: + return node->AsVariableDeclaration()->Annotations(); + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + return node->AsTSTypeAliasDeclaration()->Annotations(); + case ir::AstNodeType::ETS_PARAMETER_EXPRESSION: + return node->AsETSParameterExpression()->Annotations(); + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + return node->AsArrowFunctionExpression()->Annotations(); + case ir::AstNodeType::ANNOTATION_DECLARATION: + return node->AsAnnotationDeclaration()->Annotations(); + case ir::AstNodeType::STRUCT_DECLARATION: + return node->AsETSStructDeclaration()->Definition()->Annotations(); + default: + ES2PANDA_UNREACHABLE(); + } +} + +static void HandlePotentialPrefix(parser::JsdocHelper *jsdocHelper) +{ + jsdocHelper->Iterator().Reset(jsdocHelper->Node()->Start().index); + jsdocHelper->BackwardAndSkipSpace(1); + for (auto prefix : POTENTIAL_PREFIX) { + auto currentSv = jsdocHelper->SourceView(START_POS, jsdocHelper->Iterator().Index() + COLLECT_CURRENT_POS); + if (currentSv.EndsWith(prefix)) { + jsdocHelper->BackwardAndSkipSpace(prefix.length()); + } + } +} + +static void HandlePotentialPrefixOrAnnotationUsage(parser::JsdocHelper *jsdocHelper) +{ + if (ANNOTATION_ALLOWED_NODE.count(jsdocHelper->Node()->Type()) == 0) { + HandlePotentialPrefix(jsdocHelper); + return; + } + + auto const &annoUsage = GetAstAnnotationUsage(jsdocHelper->Node()); + if (annoUsage.empty()) { + HandlePotentialPrefix(jsdocHelper); + return; + } + + // Note: eat current iter. + jsdocHelper->Iterator().Reset(annoUsage[0]->Range().start.index - 1); + if (jsdocHelper->Iterator().Index() != START_POS) { + // Note: eat token `@` + jsdocHelper->BackwardAndSkipSpace(1); + } +} + +bool JsdocHelper::BackWardUntilJsdocStart() +{ + while (true) { + const char32_t cp = Iterator().Index() == START_POS ? util::StringView::Iterator::INVALID_CP : PeekBackWard(); + switch (cp) { + case util::StringView::Iterator::INVALID_CP: { + break; + } + case lexer::LEX_CHAR_ASTERISK: { + Backward(1); + if (PeekBackWard() == lexer::LEX_CHAR_SLASH) { + // Note: found `/*` here, it is only the common start of comments, not jsdoc. + return false; + } + if (PeekBackWard() != lexer::LEX_CHAR_ASTERISK) { + continue; + } + + if (Iterator().Index() == START_POS) { + break; + } + + Backward(1); + if (PeekBackWard() == lexer::LEX_CHAR_SLASH) { + return true; + } + continue; + } + default: { + SkipCpBackward(); + continue; + } + } + return false; + } +} + +util::StringView JsdocHelper::GetJsdocBackward() +{ + HandlePotentialPrefixOrAnnotationUsage(this); + size_t jsdocEndPos = Iterator().Index() + COLLECT_CURRENT_POS; + size_t backwardPos = jsdocEndPos; + auto currentSourceView = SourceView(START_POS, jsdocEndPos); + while (currentSourceView.EndsWith(JSDOC_END)) { + BackwardAndSkipSpace(JSDOC_END.length()); + if (!BackWardUntilJsdocStart()) { + break; + } + backwardPos = Iterator().Index(); + BackwardAndSkipSpace(1); + currentSourceView = SourceView(START_POS, Iterator().Index() + COLLECT_CURRENT_POS); + } + + if (backwardPos == jsdocEndPos) { + return EMPTY_JSDOC; + } + return SourceView(backwardPos, jsdocEndPos); +} + +// Note: Return first matched string that starts with `/*` or `/**` and ends with `*/` +util::StringView JsdocHelper::GetLicenseStringFromStart() +{ + Iterator().Reset(START_POS); + auto licenseStart = START_POS; + do { + const char32_t cp = Iterator().Peek(); + switch (cp) { + case util::StringView::Iterator::INVALID_CP: { + break; + } + case lexer::LEX_CHAR_ASTERISK: { + Forward(1); + if (Iterator().Peek() == lexer::LEX_CHAR_SLASH) { + Forward(1); + break; + } + continue; + } + case lexer::LEX_CHAR_SLASH: { + Forward(1); + if (Iterator().Peek() == lexer::LEX_CHAR_ASTERISK) { + licenseStart = Iterator().Index() - 1; + } + continue; + } + default: { + Iterator().SkipCp(); + continue; + } + } + break; + } while (true); + + return SourceView(licenseStart, Iterator().Index()); +} +} // namespace ark::es2panda::parser diff --git a/ets2panda/parser/JsdocHelper.h b/ets2panda/parser/JsdocHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..97418e245eb03e837c15d5171aaec1cdc1aa1571 --- /dev/null +++ b/ets2panda/parser/JsdocHelper.h @@ -0,0 +1,185 @@ +/** + * 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_JSDOC_HELPER_H +#define ES2PANDA_JSDOC_HELPER_H + +#include "parserImpl.h" +#include "parser/program/program.h" +#include "lexer/token/letters.h" +#include "ir/astNode.h" +#include "ir/base/classDefinition.h" +#include "ir/ets/etsModule.h" + +namespace ark::es2panda::parser { +using UStringView = util::StringView; +class JsdocHelper { +public: + explicit JsdocHelper(const ir::AstNode *inputNode) + { + auto root = inputNode; + while (root->Parent() != nullptr) { + root = root->Parent(); + } + root_ = root; + program_ = root_->AsETSModule()->Program(); + sourceCode_ = program_->SourceCode(); + iter_ = util::StringView::Iterator(sourceCode_); + InitNode(inputNode); + } + + NO_COPY_SEMANTIC(JsdocHelper); + DEFAULT_MOVE_SEMANTIC(JsdocHelper); + + ~JsdocHelper() = default; + + util::StringView GetJsdocBackward(); + util::StringView GetLicenseStringFromStart(); + + const ir::AstNode *Node() + { + return node_; + } + + util::StringView::Iterator &Iterator() + { + return iter_; + } + + util::StringView SourceView(size_t begin, size_t end) const + { + return sourceCode_.Substr(begin, end); + } + + void BackwardAndSkipSpace(size_t offset) + { + Iterator().Backward(offset); + SkipWhiteSpacesBackward(); + } + + void Backward(size_t offset) + { + Iterator().Backward(offset); + } + + void Forward(size_t offset) + { + Iterator().Forward(offset); + } + + char32_t PeekBackWard() const + { + return iter_.Peek(); + } + +private: + void InitNode(const ir::AstNode *input) + { + if (input->IsClassDefinition()) { + node_ = input->Parent(); + } else { + node_ = input; + } + } + + bool SkipWhiteSpacesBackwardHelper(const char32_t &cp) + { + if (cp < lexer::LEX_ASCII_MAX_BITS) { + return false; + } + + size_t cpSize {}; + + char32_t ch = Iterator().PeekCp(&cpSize); + switch (ch) { + case lexer::LEX_CHAR_LS: + case lexer::LEX_CHAR_PS: + case lexer::LEX_CHAR_NBSP: + case lexer::LEX_CHAR_ZWNBSP: + case lexer::LEX_CHAR_OGHAM: + case lexer::LEX_CHAR_NARROW_NO_BREAK_SP: + case lexer::LEX_CHAR_MATHEMATICAL_SP: + case lexer::LEX_CHAR_IDEOGRAPHIC_SP: + Iterator().Backward(cpSize); + return true; + default: + if (ch >= lexer::LEX_CHAR_ENQUAD && ch <= lexer::LEX_CHAR_ZERO_WIDTH_SP) { + Iterator().Backward(cpSize); + return true; + } + return false; + } + } + + void SkipWhiteSpacesBackward() + { + bool skipContinue = true; + while (skipContinue) { + auto cp = Iterator().Peek(); + switch (cp) { + case lexer::LEX_CHAR_CR: + case lexer::LEX_CHAR_LF: + case lexer::LEX_CHAR_VT: + case lexer::LEX_CHAR_FF: + case lexer::LEX_CHAR_SP: + case lexer::LEX_CHAR_TAB: + case lexer::LEX_CHAR_NEXT_LINE: + Iterator().Backward(1); + continue; + default: + skipContinue = SkipWhiteSpacesBackwardHelper(cp); + } + } + } + + void SkipCpBackward() + { + if (iter_.Index() == 0) { + return; + } + Backward(1U); + + char32_t cu0 = static_cast(iter_.Peek()); + if (cu0 < UStringView::Constants::UTF8_1BYTE_LIMIT) { + return; + } + + if ((cu0 & UStringView::Constants::UTF8_3BYTE_HEADER) == UStringView::Constants::UTF8_2BYTE_HEADER) { + Backward(1U); + return; + } + + if ((cu0 & UStringView::Constants::UTF8_4BYTE_HEADER) == UStringView::Constants::UTF8_3BYTE_HEADER) { + Backward(2U); + return; + } + + if (((cu0 & UStringView::Constants::UTF8_DECODE_4BYTE_MASK) == UStringView::Constants::UTF8_4BYTE_HEADER) && + (cu0 <= UStringView::Constants::UTF8_DECODE_4BYTE_LIMIT)) { + Backward(3U); + } + } + + bool BackWardUntilJsdocStart(); + + const ir::AstNode *root_ {}; + const parser::Program *program_ {}; + util::StringView sourceCode_ {}; + util::StringView::Iterator iter_ {nullptr}; + const ir::AstNode *node_ {}; +}; +} // namespace ark::es2panda::parser + +#endif diff --git a/ets2panda/parser/TSparser.cpp b/ets2panda/parser/TSparser.cpp index 164f34c1709b25800f00f11a958346c400d8b8ee..69368d4accaa49116bfee617847af2661966416e 100644 --- a/ets2panda/parser/TSparser.cpp +++ b/ets2panda/parser/TSparser.cpp @@ -149,6 +149,7 @@ ir::Decorator *TSParser::ParseDecorator() } auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); expr = @@ -161,6 +162,7 @@ ir::Decorator *TSParser::ParseDecorator() } auto *result = AllocNode(expr); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({start, expr->End()}); return result; @@ -199,6 +201,7 @@ ir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration() const util::StringView &ident = Lexer()->GetToken().Ident(); auto *id = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -441,6 +444,7 @@ ir::TypeNode *TSParser::ParseThisType(bool throwError) } auto *returnType = AllocNode(Allocator()); + ES2PANDA_ASSERT(returnType != nullptr); returnType->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -511,7 +515,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() } auto *typeOperator = AllocNode(type, ir::TSOperatorType::READONLY, Allocator()); - + ES2PANDA_ASSERT(typeOperator != nullptr); typeOperator->SetRange({typeOperatorStart, type->End()}); return typeOperator; @@ -524,7 +528,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() ir::TypeNode *type = ParseTypeAnnotation(&options); auto *typeOperator = AllocNode(type, ir::TSOperatorType::KEYOF, Allocator()); - + ES2PANDA_ASSERT(typeOperator != nullptr); typeOperator->SetRange({typeOperatorStart, type->End()}); return typeOperator; @@ -544,6 +548,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() auto *inferType = AllocNode(typeParam, Allocator()); + ES2PANDA_ASSERT(inferType != nullptr); inferType->SetRange({inferStart, Lexer()->GetToken().End()}); return inferType; @@ -638,6 +643,7 @@ ir::TSTupleType *TSParser::ParseTupleType() Lexer()->NextToken(); // eat ']' auto *tupleType = AllocNode(std::move(elements), Allocator()); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->SetRange({tupleStart, tupleEnd}); return tupleType; } @@ -687,6 +693,7 @@ ir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery) Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); ir::Expression *typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { @@ -734,6 +741,7 @@ ir::TSTypeParameter *TSParser::ParseMappedTypeParameter() lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); auto *paramName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(paramName != nullptr); paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -746,7 +754,7 @@ ir::TSTypeParameter *TSParser::ParseMappedTypeParameter() lexer::SourcePosition endLoc = constraint->End(); auto *typeParameter = AllocNode(paramName, constraint, nullptr, Allocator()); - + ES2PANDA_ASSERT(typeParameter != nullptr); typeParameter->SetRange({startLoc, endLoc}); return typeParameter; @@ -858,6 +866,7 @@ ir::TSTypePredicate *TSParser::ParseTypePredicate() if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) { endPos = parameterName->End(); result = AllocNode(parameterName, typeAnnotation, isAsserts, Allocator()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({startPos, endPos}); return result; } @@ -869,7 +878,7 @@ ir::TSTypePredicate *TSParser::ParseTypePredicate() endPos = typeAnnotation->End(); result = AllocNode(parameterName, typeAnnotation, isAsserts, Allocator()); - + ES2PANDA_ASSERT(result != nullptr); result->SetRange({startPos, endPos}); return result; @@ -891,6 +900,7 @@ ir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotatio Lexer()->NextToken(); auto *literalType = AllocNode(std::move(members), Allocator()); + ES2PANDA_ASSERT(literalType != nullptr); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType); literalType->SetVariable(typeVar); literalType->SetRange({bodyStart, bodyEnd}); @@ -938,6 +948,7 @@ ir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType) lexer::SourcePosition startLoc = elementType->Start(); auto *arrayType = AllocNode(elementType, Allocator()); + ES2PANDA_ASSERT(arrayType != nullptr); arrayType->SetRange({startLoc, endLoc}); return arrayType; @@ -976,6 +987,7 @@ ir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExten auto *unionType = AllocNode(std::move(types), Allocator()); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType); + ES2PANDA_ASSERT(unionType != nullptr); unionType->SetVariable(typeVar); unionType->SetRange({startLoc, endLoc}); @@ -1020,6 +1032,7 @@ ir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bo auto *intersectionType = AllocNode(std::move(types), Allocator()); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType); + ES2PANDA_ASSERT(intersectionType != nullptr); intersectionType->SetVariable(typeVar); intersectionType->SetRange({startLoc, endLoc}); @@ -1041,6 +1054,7 @@ private: return parser->AllocNode(bigintNode, parser->Allocator()); } auto *numberNode = parser->AllocNode(lexer->GetToken().GetNumber()); + CHECK_NOT_NULL(numberNode); numberNode->SetRange(lexer->GetToken().Loc()); return parser->AllocNode(numberNode, parser->Allocator()); @@ -1136,6 +1150,7 @@ ir::TypeNode *TSParser::ParseBasicType() return typeAnnotation; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError) { if (typeAnnotation != nullptr) { @@ -1200,6 +1215,7 @@ ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnot } auto *result = AllocNode(type, Allocator()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({typeStart, endLoc}); return result; @@ -1466,6 +1482,7 @@ bool TSParser::IsNamedFunctionExpression() ir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1508,6 +1525,7 @@ ir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature) : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE; auto *signatureMember = AllocNode( kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation)); + ES2PANDA_ASSERT(signatureMember != nullptr); signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()}); return signatureMember; @@ -1534,6 +1552,7 @@ ir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); auto *key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat key @@ -1581,12 +1600,14 @@ std::tuple TSParser::ParseInterfacePropertyKey() case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = Lexer()->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = Lexer()->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1597,6 +1618,7 @@ std::tuple TSParser::ParseInterfacePropertyKey() key = AllocNode(Lexer()->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1905,12 +1927,14 @@ ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, ir::ScriptFunction *func = ParseFunction(desc->newStatus); + ES2PANDA_ASSERT(func != nullptr); if (func->IsOverload() && !desc->decorators.empty()) { ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.", desc->decorators.front()->Start()); } auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -1923,6 +1947,7 @@ ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, func->AddFlag(ir::ScriptFunctionFlags::METHOD); auto *method = AllocNode(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; @@ -1998,6 +2023,7 @@ std::tuple TSParser::ParseComputedClassFieldOrIndexSignature(i if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) { auto id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat param @@ -2089,6 +2115,7 @@ std::tuple TSParser::Pa ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); } else { body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); endLoc = body->End(); } @@ -2110,6 +2137,7 @@ ir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector *s } auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index 059973a206a823dcff31fe782923bbab68302a48..64dc2383bc7e5e12726cc4b7c49469ab91c1a4be 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -130,7 +130,11 @@ bool TypedParser::IsNamespaceDecl() } auto savedPos = Lexer()->Save(); Lexer()->NextToken(); - bool isNamespaceDecl = Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT; + // namespace is a soft keyword, so it can be used as an identifier outside declarations + // If followed by an identifier (literal or keyword), it's treated as a declaration + // Using keywords as identifiers is invalid, but that error is handled later during parsing + bool isNamespaceDecl = + Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || Lexer()->GetToken().IsKeyword(); Lexer()->Rewind(savedPos); return isNamespaceDecl; } @@ -141,7 +145,11 @@ ir::Statement *TypedParser::ParsePotentialExpressionStatement(StatementParsingFl switch (Lexer()->GetToken().KeywordType()) { case lexer::TokenType::KEYW_TYPE: { - return ParseTypeAliasDeclaration(); + const auto maybeAlias = ParseTypeAliasStatement(); + if (maybeAlias != nullptr) { + return maybeAlias; + } + break; } case lexer::TokenType::KEYW_ABSTRACT: { Lexer()->NextToken(); // eat abstract keyword @@ -188,7 +196,11 @@ ir::TSTypeAssertion *TypedParser::ParseTypeAssertion() Lexer()->NextToken(); // eat '>' ir::Expression *expression = ParseExpression(); + if (expression == nullptr) { + return nullptr; + } auto *typeAssertion = AllocNode(typeAnnotation, expression); + ES2PANDA_ASSERT(typeAssertion != nullptr); typeAssertion->SetRange({start, Lexer()->GetToken().End()}); return typeAssertion; @@ -229,7 +241,7 @@ ir::ArrowFunctionExpression *TypedParser::ParseGenericArrowFunction() ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN); lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); - auto typeParamDeclOptions = TypeAnnotationParsingOptions::NO_OPTS; + auto typeParamDeclOptions = TypeAnnotationParsingOptions::REPORT_ERROR; ir::TSTypeParameterDeclaration *typeParamDecl = ParseTypeParameterDeclaration(&typeParamDeclOptions); if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { @@ -277,7 +289,7 @@ ir::TSModuleDeclaration *TypedParser::ParseAmbientExternalModuleDeclaration(cons name = AllocNode(Lexer()->GetToken().String()); } - + ES2PANDA_ASSERT(name != nullptr); name->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -295,6 +307,7 @@ ir::TSModuleDeclaration *TypedParser::ParseAmbientExternalModuleDeclaration(cons auto *moduleDecl = AllocNode(Allocator(), name, body, ir::TSModuleDeclaration::ConstructorFlags {isGlobal, true}); + ES2PANDA_ASSERT(moduleDecl != nullptr); moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()}); return moduleDecl; @@ -307,6 +320,7 @@ ir::TSModuleDeclaration *TypedParser::ParseModuleOrNamespaceDeclaration(const le } auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -323,6 +337,7 @@ ir::TSModuleDeclaration *TypedParser::ParseModuleOrNamespaceDeclaration(const le auto *moduleDecl = AllocNode(Allocator(), identNode, body, ir::TSModuleDeclaration::ConstructorFlags {false, false}); + ES2PANDA_ASSERT(moduleDecl != nullptr); moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()}); return moduleDecl; @@ -339,6 +354,7 @@ ir::TSModuleBlock *TypedParser::ParseTsModuleBlock() auto statements = ParseStatementList(); auto *blockNode = AllocNode(std::move(statements)); + ES2PANDA_ASSERT(blockNode != nullptr); blockNode->SetRange({startLoc, Lexer()->GetToken().End()}); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); @@ -415,10 +431,12 @@ ir::TypeNode *TypedParser::ParseInterfaceExtendsElement() if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; typeParamInst = ParseTypeParameterInstantiation(&options); + ES2PANDA_ASSERT(typeParamInst != nullptr); heritageEnd = typeParamInst->End(); } auto *typeReference = AllocNode(expr, typeParamInst, Allocator()); + ES2PANDA_ASSERT(typeReference != nullptr); typeReference->SetRange({heritageStart, heritageEnd}); return typeReference; } @@ -431,7 +449,9 @@ ArenaVector TypedParser::ParseInterfaceExtendsClause( while (true) { auto *typeReference = ParseInterfaceExtendsElement(); + ES2PANDA_ASSERT(typeReference != nullptr); auto *heritage = AllocNode(typeReference); + ES2PANDA_ASSERT(heritage != nullptr); heritage->SetRange(typeReference->Range()); extends.push_back(heritage); @@ -484,6 +504,7 @@ ir::Statement *TypedParser::ParseInterfaceDeclaration(bool isStatic) auto members = ParseTypeLiteralOrInterface(); auto *body = AllocNode(std::move(members)); + ES2PANDA_ASSERT(body != nullptr); body->SetRange({bodyStart, Lexer()->GetToken().End()}); const auto isExternal = IsExternal(); @@ -491,6 +512,7 @@ ir::Statement *TypedParser::ParseInterfaceDeclaration(bool isStatic) Allocator(), std::move(extends), ir::TSInterfaceDeclaration::ConstructorData {id, typeParamDecl, body, isStatic, isExternal, GetContext().GetLanguage()}); + ES2PANDA_ASSERT(interfaceDecl != nullptr); interfaceDecl->SetRange({interfaceStart, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -587,8 +609,9 @@ ArenaVector TypedParser::ParseTypeLiteralOrInterfaceBody() LogExpectedToken(lexer::TokenType::PUNCTUATOR_COMMA); } - if (Lexer()->GetToken().IsKeyword() && ((Lexer()->GetToken().Type() != lexer::TokenType::KEYW_STATIC) && - (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PRIVATE))) { + if (Lexer()->GetToken().IsKeyword() && (Lexer()->GetToken().Type() != lexer::TokenType::KEYW_STATIC && + Lexer()->GetToken().Type() != lexer::TokenType::KEYW_PRIVATE && + Lexer()->GetToken().Type() != lexer::TokenType::KEYW_DEFAULT)) { Lexer()->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); Lexer()->GetToken().SetTokenStr(ERROR_LITERAL); } @@ -679,8 +702,10 @@ ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const }, &endLoc, true); - auto *enumDeclaration = AllocNode(Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst}); + auto *enumDeclaration = + AllocNode(Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst}, GetContext().GetLanguage()); + ES2PANDA_ASSERT(enumDeclaration != nullptr); enumDeclaration->SetRange({enumStart, endLoc}); return enumDeclaration; @@ -717,7 +742,7 @@ ir::TSTypeParameter *TypedParser::ParseTypeParameter(TypeAnnotationParsingOption const auto &ident = Lexer()->GetToken().Ident(); auto *paramIdent = AllocNode(ident, Allocator()); - + ES2PANDA_ASSERT(paramIdent != nullptr); paramIdent->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -741,7 +766,7 @@ ir::TSTypeParameter *TypedParser::ParseTypeParameter(TypeAnnotationParsingOption } auto *typeParam = AllocNode(paramIdent, constraint, defaultType, Allocator()); - + ES2PANDA_ASSERT(typeParam != nullptr); typeParam->SetRange({startLoc, Lexer()->GetToken().End()}); return typeParam; @@ -876,6 +901,7 @@ ArenaVector TypedParser::ParseClassImplementClause() lexer::SourcePosition implStart = Lexer()->GetToken().Start(); auto [expr, implTypeParams] = ParseClassImplementsElement(); auto *impl = AllocNode(expr, implTypeParams); + ES2PANDA_ASSERT(impl != nullptr); impl->SetRange({implStart, Lexer()->GetToken().End()}); implements.push_back(impl); @@ -958,9 +984,10 @@ ir::ClassDefinition *TypedParser::ParseClassDefinition(ir::ClassDefinitionModifi flags |= ir::ModifierFlags::DECLARE; } - auto *classDefinition = - AllocNode(identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, - superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + auto *classDefinition = AllocNode( + Allocator(), identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, + std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetInternalName(privateBinding.View()); classDefinition->SetRange(bodyRange); @@ -994,7 +1021,7 @@ ir::AstNode *TypedParser::ParseProperty(const ArenaVector &proper property = AllocNode(propName, typeAnnotation, desc.modifiers & ir::ModifierFlags::READONLY); - + ES2PANDA_ASSERT(property != nullptr); property->SetRange({property->AsTSIndexSignature()->Param()->Start(), property->AsTSIndexSignature()->TypeAnnotation()->End()}); } else { @@ -1005,7 +1032,7 @@ ir::AstNode *TypedParser::ParseProperty(const ArenaVector &proper if (desc.isPrivateIdent) { LogError(diagnostic::DECORATORS_INVALID); } - + ES2PANDA_ASSERT(property != nullptr); property->AddDecorators(std::move(desc.decorators)); } } @@ -1191,13 +1218,11 @@ ir::Expression *TypedParser::ParseQualifiedName(ExpressionParseFlags flags) break; case lexer::TokenType::LITERAL_IDENT: expr = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(expr != nullptr); expr->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); break; default: - if ((flags & ExpressionParseFlags::POTENTIAL_NEW_ARRAY) != 0) { - return expr; - } LogError(diagnostic::ID_EXPECTED); return AllocBrokenExpression(Lexer()->GetToken().Loc()); } @@ -1248,6 +1273,7 @@ ir::Expression *TypedParser::ParseQualifiedReference(ir::Expression *typeName, E propName->SetRange(Lexer()->GetToken().Loc()); typeName = AllocNode(typeName, propName, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange({typeName->AsTSQualifiedName()->Left()->Start(), Lexer()->GetToken().End()}); if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { @@ -1269,7 +1295,6 @@ ir::AstNode *TypedParser::ParseTypeParameterInstantiationImpl(TypeAnnotationPars TypeAnnotationParsingOptions tmpOptions = *options &= ~TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE; // Need to parse correctly the cases like `x: T|C` tmpOptions &= ~TypeAnnotationParsingOptions::DISALLOW_UNION; - tmpOptions |= TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; ir::TypeNode *currentParam = ParseTypeAnnotation(&tmpOptions); if (currentParam == nullptr) { @@ -1488,14 +1513,6 @@ ParserStatus TypedParser::ValidateArrowParameter(ir::Expression *expr, bool *see [[fallthrough]]; } - case ir::AstNodeType::REST_ELEMENT: { - if (expr->AsRestElement()->IsOptional()) { - LogError(diagnostic::REST_PARAM_CANNOT_BE_OPTIONAL, {}, expr->Start()); - } - - ValidateArrowParameterBindings(expr->AsRestElement()->Argument()); - return ParserStatus::HAS_COMPLEX_PARAM; - } case ir::AstNodeType::IDENTIFIER: { const util::StringView &identifier = expr->AsIdentifier()->Name(); bool isOptional = expr->AsIdentifier()->IsOptional(); @@ -1527,4 +1544,9 @@ ParserStatus TypedParser::ValidateArrowParameter(ir::Expression *expr, bool *see return ParserStatus::NO_OPTS; } +ir::Statement *TypedParser::ParseTypeAliasStatement() +{ + return ParseTypeAliasDeclaration(); +} + } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/TypedParser.h b/ets2panda/parser/TypedParser.h index bb1379b9e51586619e4f9a587faaf4e574a5a019..86f09358168edef86ac87e23c0dd3e172bd8d47f 100644 --- a/ets2panda/parser/TypedParser.h +++ b/ets2panda/parser/TypedParser.h @@ -107,6 +107,7 @@ protected: { return false; } + virtual ir::Statement *ParseTypeAliasStatement(); virtual ir::TSTypeAliasDeclaration *ParseTypeAliasDeclaration() { return nullptr; diff --git a/ets2panda/parser/context/classPrivateContext.cpp b/ets2panda/parser/context/classPrivateContext.cpp index a902e95455abdfd3da483fb2eb6697b3d749ed4b..048ec7177a64c59159f1ff0717db992e31991d05 100644 --- a/ets2panda/parser/context/classPrivateContext.cpp +++ b/ets2panda/parser/context/classPrivateContext.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -24,7 +24,9 @@ namespace ark::es2panda::parser { bool ClassPrivateContext::AddElement(const ir::ClassElement *elem) { bool newPropIsStatic = elem->IsStatic(); - util::StringView newPropName = elem->Id()->Name(); + auto id = elem->Id(); + ES2PANDA_ASSERT(id != nullptr); + util::StringView newPropName = id->Name(); ir::MethodDefinitionKind newPropMethodKind = ir::MethodDefinitionKind::METHOD; if (elem->IsMethodDefinition()) { @@ -61,7 +63,9 @@ bool ClassPrivateContext::AddElement(const ir::ClassElement *elem) bool ClassPrivateContext::FindElement(const ir::Identifier *elem) const { for (const auto *it : elements_) { - if (it->Id()->Name().Compare(elem->Name()) == 0) { + auto id = it->Id(); + ES2PANDA_ASSERT(id != nullptr); + if (id->Name().Compare(elem->Name()) == 0) { return true; } } diff --git a/ets2panda/parser/context/parserContext.cpp b/ets2panda/parser/context/parserContext.cpp index f475a3578e837623bc8c5667ea058b97a5d1cb81..5b49e8a43824e5633428619c710f5215927e7828 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 diff --git a/ets2panda/parser/context/parserContext.h b/ets2panda/parser/context/parserContext.h index 29130fe409ecc597f42a89018045d5aa88ed0858..3c5fcd70e54648b81e0612dc7ae097390837bb15 100644 --- a/ets2panda/parser/context/parserContext.h +++ b/ets2panda/parser/context/parserContext.h @@ -73,7 +73,8 @@ enum class ParserStatus : uint64_t { DEPENDENCY_ANALYZER_MODE = 1ULL << 39ULL, - STATIC_BLOCK = 1ULL << 40ULL + STATIC_BLOCK = 1ULL << 40ULL, + IN_PACKAGE = 1ULL << 41ULL, }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 37c03683eb146388e86bb149022ca0294731df53..6d111ce34ace4c3348ba058e12bf2ad0e88774d0 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -114,6 +114,7 @@ ir::YieldExpression *ParserImpl::ParseYieldExpression() } auto *yieldNode = AllocNode(argument, isDelegate); + ES2PANDA_ASSERT(yieldNode != nullptr); yieldNode->SetRange({startLoc, endLoc}); return yieldNode; @@ -208,6 +209,7 @@ ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION; auto *arrayExpressionNode = AllocNode(nodeType, std::move(elements), Allocator(), trailingComma); + ES2PANDA_ASSERT(arrayExpressionNode != nullptr); arrayExpressionNode->SetRange({startLoc, endLoc}); if (inPattern) { @@ -321,6 +323,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF lexer_->NextToken(); auto statements = ParseStatementList(); body = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(body); body->SetRange({bodyStart, lexer_->GetToken().End()}); // This check is redundant since we have ParseStatementList() @@ -328,7 +331,6 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); endLoc = body->End(); } - // clang-format off funcNode = AllocNode( Allocator(), ir::ScriptFunction::ScriptFunctionData { @@ -338,9 +340,11 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF {}, context_.GetLanguage()}); // clang-format on + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({desc->startLoc, endLoc}); auto *arrowFuncNode = AllocNode(funcNode, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(funcNode->Range()); return arrowFuncNode; @@ -574,6 +578,7 @@ ir::Expression *ParserImpl::CreateBinaryAssignmentExpression(ir::Expression *ass { auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); + ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -589,16 +594,16 @@ ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpress ir::Expression *consequent = ParseAssignmentExpressionHelper(); ir::Expression *alternate = ParseExpression(); auto *conditionalExpr = AllocNode(lhsExpression, consequent, alternate); + ES2PANDA_ASSERT(conditionalExpr != nullptr); 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); @@ -606,17 +611,12 @@ 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); @@ -669,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, tokenType)); + return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression)); } default: break; @@ -702,6 +702,7 @@ ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenTyp auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); + ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -742,6 +743,7 @@ ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral() const auto templateStr = lexer_->ScanTemplateString(); if (templateStr.validSequence) { auto *const element = AllocNode(templateStr.str.View(), cooked); + ES2PANDA_ASSERT(element != nullptr); element->SetRange({lexer::SourcePosition {startPos.Iterator().Index(), startPos.Line(), GetProgram()}, lexer::SourcePosition {templateStr.end, lexer_->Line(), GetProgram()}}); quasis.push_back(element); @@ -767,6 +769,7 @@ ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral() } auto *templateNode = AllocNode(std::move(quasis), std::move(expressions), multilineStr); + ES2PANDA_ASSERT(templateNode != nullptr); templateNode->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -791,6 +794,7 @@ ir::Expression *ParserImpl::ParseNewExpression() if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { lexer::SourcePosition endLoc = callee->End(); auto *newExprNode = AllocNode(callee, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -816,6 +820,7 @@ ir::Expression *ParserImpl::ParseNewExpression() &endLoc, true); auto *newExprNode = AllocNode(callee, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -839,11 +844,8 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() LogError(diagnostic::NEW_TARGET_IS_NOT_ALLOWED); } - if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::NEW_TARGET_WITH_ESCAPED_CHARS); - } - auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::NEW_TARGET); + ES2PANDA_ASSERT(metaProperty != nullptr); metaProperty->SetRange(loc); lexer_->NextToken(); return metaProperty; @@ -856,6 +858,7 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() ir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -868,6 +871,7 @@ ir::BooleanLiteral *ParserImpl::ParseBooleanLiteral() lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE); auto *booleanNode = AllocNode(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE); + ES2PANDA_ASSERT(booleanNode != nullptr); booleanNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -878,6 +882,7 @@ ir::NullLiteral *ParserImpl::ParseNullLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL); auto *nullNode = AllocNode(); + ES2PANDA_ASSERT(nullNode != nullptr); nullNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -896,6 +901,7 @@ ir::Literal *ParserImpl::ParseNumberLiteral() numberNode = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(numberNode != nullptr); numberNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -907,6 +913,7 @@ ir::CharLiteral *ParserImpl::ParseCharLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR); auto *charNode = AllocNode(lexer_->GetToken().Utf16()); + ES2PANDA_ASSERT(charNode != nullptr); charNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -918,6 +925,7 @@ ir::StringLiteral *ParserImpl::ParseStringLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING); auto *stringNode = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(stringNode != nullptr); stringNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -928,6 +936,7 @@ ir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED); auto *undefinedNode = AllocNode(); + ES2PANDA_ASSERT(undefinedNode != nullptr); undefinedNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -939,6 +948,7 @@ ir::ThisExpression *ParserImpl::ParseThisExpression() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS); auto *thisExprNode = AllocNode(); + ES2PANDA_ASSERT(thisExprNode); thisExprNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -958,6 +968,7 @@ ir::RegExpLiteral *ParserImpl::ParseRegularExpression() reParser.ParsePattern(); auto *regexpNode = AllocNode(regexp.patternStr, regexp.flags, regexp.flagsStr); + ES2PANDA_ASSERT(regexpNode != nullptr); regexpNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -969,6 +980,7 @@ ir::SuperExpression *ParserImpl::ParseSuperExpression() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER); auto *superExprNode = AllocNode(); + ES2PANDA_ASSERT(superExprNode != nullptr); superExprNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); // eat super @@ -1017,6 +1029,7 @@ ir::Expression *ParserImpl::ParseHashMaskOperator() } auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(privateIdent != nullptr); privateIdent->SetPrivate(true); lexer_->NextToken(); @@ -1038,6 +1051,7 @@ ir::Expression *ParserImpl::ParseClassExpression() } auto *classExpr = AllocNode(classDefinition); + ES2PANDA_ASSERT(classExpr != nullptr); classExpr->SetRange({startLoc, classDefinition->End()}); return classExpr; @@ -1276,6 +1290,7 @@ void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::E amended->SetParent(nullptr); // Next line overwrite parent auto *binaryExpr = AllocNode(left, amended, operatorType); + ES2PANDA_ASSERT(binaryExpr != nullptr); binaryExpr->SetRange({left->Start(), amended->End()}); SetAmendedChildExpression(right, binaryExpr); } @@ -1302,8 +1317,9 @@ static ir::Expression *FindAndAmendChildExpression(ir::Expression *expression, c return shouldBeAmended ? expression : parentExpression; } -ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const lexer::TokenType operatorType) +ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, ExpressionParseFlags flags) { + lexer::TokenType operatorType = lexer_->GetToken().Type(); ES2PANDA_ASSERT(lexer::Token::IsBinaryToken(operatorType)); if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) { @@ -1314,6 +1330,11 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const le 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()) { @@ -1334,6 +1355,7 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const le } const lexer::SourcePosition &endPos = rightExpr->End(); rightExpr = AllocNode(left, rightExpr, operatorType); + ES2PANDA_ASSERT(rightExpr != nullptr); rightExpr->SetRange({left->Start(), endPos}); } @@ -1399,12 +1421,16 @@ ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool callExpr = AllocNode(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma); } + ES2PANDA_ASSERT(callExpr != nullptr); callExpr->SetRange({callee->Start(), endLoc}); isOptionalChain = false; if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { ParseTrailingBlock(callExpr); + if (callExpr->TrailingBlock() != nullptr) { + callExpr->SetRange({callee->Start(), callExpr->TrailingBlock()->End()}); + } return callExpr; } @@ -1428,11 +1454,13 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) const auto tokenType = lexer_->GetToken().Type(); if (tokenType == lexer::TokenType::LITERAL_IDENT) { auto *identNode = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetPrivate(isPrivate); identNode->SetRange(lexer_->GetToken().Loc()); returnExpression = AllocNode(leftSideExpr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, true); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({leftSideExpr->Start(), identNode->End()}); lexer_->NextToken(); } @@ -1449,6 +1477,7 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) returnExpression = AllocNode(leftSideExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, true); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({leftSideExpr->Start(), endLoc}); lexer_->NextToken(); } @@ -1461,6 +1490,7 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) if (tokenType == lexer::TokenType::PUNCTUATOR_BACK_TICK || lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BACK_TICK) { LogError(diagnostic::TAGGED_TEMPLATE_LITERALS_IN_OPTIONALCHAIN); + return AllocBrokenExpression(lexer_->GetToken().Loc()); } return returnExpression; @@ -1472,6 +1502,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expre switch (lexer_->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); + ES2PANDA_ASSERT(returnExpression != nullptr); (*returnExpression)->SetStart(startLoc); break; } @@ -1547,6 +1578,7 @@ ir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr auto *memberExpr = AllocNode(primaryExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()}); lexer_->NextToken(); return memberExpr; @@ -1560,12 +1592,17 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri ValidatePrivateIdentifier(); auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(privateIdent != nullptr); + if (program_->Extension() == util::gen::extension::ETS && privateIdent->Name().Is("prototype")) { + LogError(diagnostic::PROTOTYPE_ACCESS); + } privateIdent->SetRange({memberStart, lexer_->GetToken().End()}); privateIdent->SetPrivate(true); lexer_->NextToken(); auto *memberExpr = AllocNode(primaryExpr, privateIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()}); return memberExpr; } @@ -1573,8 +1610,12 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExpr, bool isOptional) { ir::Identifier *ident = ExpectIdentifier(true); + if (program_->Extension() == util::gen::extension::ETS && ident->Name().Is("prototype")) { + LogError(diagnostic::PROTOTYPE_ACCESS); + } auto *memberExpr = AllocNode(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, false, isOptional); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), ident->End()}); return memberExpr; @@ -1637,9 +1678,11 @@ ir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *r const lexer::SourcePosition startLoc) { ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); + ES2PANDA_ASSERT(propertyNode != nullptr); lexer::SourcePosition endLoc = propertyNode->End(); returnExpression = AllocNode(returnExpression, propertyNode, nullptr); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({startLoc, endLoc}); return returnExpression; @@ -1700,6 +1743,7 @@ ir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::Sou lexer::SourcePosition endLoc = expr->End(); auto chain = AllocNode(expr); + ES2PANDA_ASSERT(chain != nullptr); chain->SetRange({startLoc, endLoc}); if (expr == top) { @@ -1748,6 +1792,7 @@ ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, Exp returnExpression = AllocNode(returnExpression, lexer_->GetToken().Type(), false); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); } @@ -1798,6 +1843,7 @@ ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool ir::Expression *rightNode = ParseExpression(); auto *assignmentExpression = AllocNode( ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(assignmentExpression != nullptr); assignmentExpression->SetRange({returnNode->Start(), rightNode->End()}); return assignmentExpression; @@ -1873,15 +1919,11 @@ static bool IsShorthandDelimiter(char32_t cp) } } -void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags) +void ParserImpl::ValidateAccessor(ExpressionParseFlags flags) { if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) { LogError(diagnostic::UNEXPECTED_TOKEN); } - - if ((currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); - } } ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos) @@ -1904,6 +1946,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta const util::StringView &ident = lexer_->GetToken().Ident(); auto *key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); ir::Expression *value = AllocNode(ident, Allocator()); @@ -1921,6 +1964,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta auto *assignmentExpression = AllocNode( ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(assignmentExpression != nullptr); assignmentExpression->SetRange({value->Start(), rightNode->End()}); end = rightNode->End(); value = assignmentExpression; @@ -1930,6 +1974,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta } auto *returnProperty = AllocNode(key, value); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); return returnProperty; @@ -1951,12 +1996,11 @@ bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::Property *methodStatus |= ParserStatus::GENERATOR_FUNCTION; } - lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags(); char32_t nextCp = lexer_->Lookahead(); lexer::TokenType keywordType = lexer_->GetToken().KeywordType(); // Parse getter property if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) { - ValidateAccessor(flags, currentTokenFlags); + ValidateAccessor(flags); *propertyKind = ir::PropertyKind::GET; lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); @@ -1966,7 +2010,7 @@ bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::Property // Parse setter property if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) { - ValidateAccessor(flags, currentTokenFlags); + ValidateAccessor(flags); *propertyKind = ir::PropertyKind::SET; lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); @@ -1996,6 +2040,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = lexer_->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2003,6 +2048,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = lexer_->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2013,6 +2059,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) } else { key = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2078,11 +2125,13 @@ ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyK } ir::ScriptFunction *methodDefinitonNode = ParseFunction(newStatus); + ES2PANDA_ASSERT(methodDefinitonNode != nullptr); methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD); size_t paramsSize = methodDefinitonNode->Params().size(); auto *value = AllocNode(methodDefinitonNode); + ES2PANDA_ASSERT(value != nullptr); value->SetRange(methodDefinitonNode->Range()); if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) { @@ -2132,10 +2181,12 @@ ir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionP } ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); + ES2PANDA_ASSERT(value != nullptr); lexer::SourcePosition end = value->End(); auto *returnProperty = AllocNode(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); return returnProperty; @@ -2211,6 +2262,7 @@ ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags fla auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION; auto *objectExpression = AllocNode(nodeType, Allocator(), std::move(properties), trailingComma); + ES2PANDA_ASSERT(objectExpression != nullptr); objectExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -2257,6 +2309,7 @@ ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *star lexer::SourcePosition end = sequence.back()->End(); auto *sequenceNode = AllocNode(std::move(sequence)); + ES2PANDA_ASSERT(sequenceNode != nullptr); sequenceNode->SetRange({start, end}); return sequenceNode; @@ -2317,6 +2370,7 @@ ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFl returnExpr = AllocNode(argument, operatorType); } + ES2PANDA_ASSERT(returnExpr != nullptr); returnExpr->SetRange({start, end}); return returnExpr; @@ -2347,6 +2401,7 @@ ir::Expression *ParserImpl::ParseImportExpression() } auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::IMPORT_META); + ES2PANDA_ASSERT(metaProperty != nullptr); metaProperty->SetRange({startLoc, endLoc}); lexer_->NextToken(); @@ -2361,6 +2416,7 @@ ir::Expression *ParserImpl::ParseImportExpression() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); auto *importExpression = AllocNode(source); + ES2PANDA_ASSERT(importExpression != nullptr); importExpression->SetRange({startLoc, endImportLoc}); return importExpression; @@ -2396,9 +2452,11 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat } ir::ScriptFunction *functionNode = ParseFunction(newStatus); + ES2PANDA_ASSERT(functionNode != nullptr); functionNode->SetStart(startLoc); auto *funcExpr = AllocNode(ident, functionNode); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(functionNode->Range()); return funcExpr; diff --git a/ets2panda/parser/expressionTSParser.cpp b/ets2panda/parser/expressionTSParser.cpp index 86f1232891b4b65215fc1c02150c7d4c820c46f2..db51d03572968bb10d61c6a10049cf60f5ad94f9 100644 --- a/ets2panda/parser/expressionTSParser.cpp +++ b/ets2panda/parser/expressionTSParser.cpp @@ -137,6 +137,7 @@ ir::Expression *TSParser::ParsePotentialAsExpression(ir::Expression *expr) lexer::SourcePosition startLoc = expr->Start(); auto *asExpr = AllocNode(expr, typeAnnotation, isConst); + ES2PANDA_ASSERT(asExpr != nullptr); asExpr->SetRange({startLoc, Lexer()->GetToken().End()}); if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) { @@ -169,13 +170,9 @@ ir::AnnotatedExpression *TSParser::ParsePatternElementGetReturnNode(ExpressionPa } case lexer::TokenType::LITERAL_IDENT: { ir::AnnotatedExpression *returnNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(returnNode != nullptr); - if (returnNode->AsIdentifier()->Decorators().empty()) { - returnNode->SetRange(Lexer()->GetToken().Loc()); - } else { - returnNode->SetRange( - {returnNode->AsIdentifier()->Decorators().front()->Start(), Lexer()->GetToken().End()}); - } + returnNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -328,6 +325,7 @@ ir::Expression *TSParser::ParseModuleReference() } result = AllocNode(Lexer()->GetToken().String()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -340,6 +338,7 @@ ir::Expression *TSParser::ParseModuleReference() Lexer()->NextToken(); // eat ')' } else { result = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -354,9 +353,11 @@ ir::Expression *TSParser::ParseModuleReference() ir::TSTypeReference *TSParser::ParseConstExpression() { auto *identRef = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identRef != nullptr); identRef->SetRange(Lexer()->GetToken().Loc()); auto *typeReference = AllocNode(identRef, nullptr, Allocator()); + ES2PANDA_ASSERT(typeReference); typeReference->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -379,6 +380,8 @@ bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression } *returnExpression = AllocNode(*returnExpression); + ES2PANDA_ASSERT(*returnExpression != nullptr); + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); Lexer()->NextToken(); return false; @@ -435,6 +438,8 @@ private: } }; +// NOLINTNEXTLINE(readability-function-size) +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression, const lexer::SourcePosition &startLoc) { @@ -443,6 +448,7 @@ ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Express switch (Lexer()->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); + ES2PANDA_ASSERT(*returnExpression != nullptr); (*returnExpression)->SetStart(startLoc); break; } diff --git a/ets2panda/parser/parserFlags.h b/ets2panda/parser/parserFlags.h index a7ac93e3ba4f175ce31ba63dd7a8ab85fe4d6ef8..5f307af35408ea5ddf89ae0fc2fbd3618142f674 100644 --- a/ets2panda/parser/parserFlags.h +++ b/ets2panda/parser/parserFlags.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 @@ -69,6 +69,7 @@ enum class StatementParsingFlags : uint32_t { GLOBAL = 1U << 1U, IF_ELSE = 1U << 2U, LABELLED = 1U << 3U, + INIT_MODULE = 1U << 4U, STMT_LEXICAL_SCOPE_NEEDED = IF_ELSE | LABELLED, STMT_GLOBAL_LEXICAL = GLOBAL | ALLOW_LEXICAL, diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index b1cbdefa5b68e57d547c75538acf9782dbebc87c..a96e0eabc0c24a277eca86cb4321ee72c33375be 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -14,6 +14,7 @@ */ #include "parserImpl.h" +#include "forwardDeclForParserImpl.h" #include "parserStatusContext.h" #include "generated/diagnostic.h" @@ -28,6 +29,7 @@ #include "ir/expressions/arrayExpression.h" #include "ir/expressions/assignmentExpression.h" #include "ir/expressions/callExpression.h" +#include "ir/expressions/dummyNode.h" #include "ir/expressions/functionExpression.h" #include "ir/expressions/literals/bigIntLiteral.h" #include "ir/expressions/literals/numberLiteral.h" @@ -79,6 +81,7 @@ void ParserImpl::ParseProgram(ScriptKind kind) auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); auto *blockStmt = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockStmt != nullptr); blockStmt->SetRange({startLoc, lexer_->GetToken().End()}); program_->SetAst(blockStmt); @@ -334,6 +337,7 @@ std::tuple ParserImpl::ParseComputedClassFieldOrIndexSignature return {true, false, false}; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) { ir::Expression *propName = nullptr; @@ -347,6 +351,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) ValidateClassKey(desc); propName = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); propName->AsIdentifier()->SetPrivate(desc->isPrivateIdent); break; @@ -363,6 +368,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) } propName = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); break; } @@ -374,6 +380,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) } else { propName = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); break; @@ -453,6 +460,7 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, ir::ScriptFunction *func = ParseFunction(desc->newStatus); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -469,6 +477,7 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, : propName; auto *method = AllocNode(desc->methodKind, ident, funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; @@ -478,15 +487,13 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, const ArenaVector &properties, ir::Expression *propName, ir::TypeNode *typeAnnotation) { + ES2PANDA_ASSERT(propName != nullptr); lexer::SourcePosition propEnd = propName->End(); ir::ClassElement *property = nullptr; if (desc->classMethod) { - if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) { - LogError(diagnostic::DECLARE_MODIFIER_ON_INVALID_CLASS_ELEMENT); - } - property = ParseClassMethod(desc, properties, propName, &propEnd); + ES2PANDA_ASSERT(property != nullptr); property->SetRange({desc->propStart, propEnd}); return property; } @@ -506,7 +513,7 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, property = AllocNode(propName, value, typeAnnotation, desc->modifiers, Allocator(), desc->isComputed); - + ES2PANDA_ASSERT(property != nullptr); property->SetRange({desc->propStart, propEnd}); return property; @@ -585,6 +592,7 @@ ir::ClassElement *ParserImpl::ParseClassStaticBlock() auto *funcExpr = AllocNode(func); auto *staticBlock = AllocNode(funcExpr, Allocator()); + ES2PANDA_ASSERT(staticBlock != nullptr); staticBlock->SetRange({startPos, lexer_->GetToken().End()}); lexer_->NextToken(); // eat '}' @@ -676,11 +684,13 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo auto *key = AllocNode("constructor", Allocator()); if ((modifiers & ir::ClassDefinitionModifiers::SET_CTOR_ID) != 0U) { + ES2PANDA_ASSERT(key != nullptr); func->SetIdent(key->Clone(Allocator(), nullptr)); } auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, - ir::ModifierFlags::NONE, Allocator(), false); + ir::ModifierFlags::CONSTRUCTOR, Allocator(), false); + ES2PANDA_ASSERT(ctor != nullptr); const auto rangeImplicitContstuctor = lexer::SourceRange(startLoc, startLoc); ctor->IterateRecursively( @@ -700,7 +710,10 @@ void ParserImpl::CreateImplicitConstructor(ir::MethodDefinition *&ctor, ctor = BuildImplicitConstructor(modifiers, startLoc); if ((flags & ir::ModifierFlags::DECLARE) != 0) { - ctor->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + ES2PANDA_ASSERT(ctor != nullptr); + auto *ctorFunc = ctor->Function(); + ES2PANDA_ASSERT(ctorFunc != nullptr); + ctorFunc->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } } @@ -784,8 +797,9 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(ir::ClassDefinitionModifie ArenaVector implements(Allocator()->Adapter()); auto *classDefinition = - AllocNode(identNode, nullptr, superTypeParams, std::move(implements), ctor, superClass, - std::move(properties), modifiers, flags, GetContext().GetLanguage()); + AllocNode(Allocator(), identNode, nullptr, superTypeParams, std::move(implements), ctor, + superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetInternalName(privateBinding.View()); classDefinition->SetRange(bodyRange); @@ -830,6 +844,15 @@ ParserImpl::ClassBody ParserImpl::ParseClassBody(ir::ClassDefinitionModifiers mo if (CheckClassElement(property, ctor, properties)) { continue; } + auto isIndexer = [](ir::AstNode *node) { + return node->IsDummyNode() && node->AsDummyNode()->IsDeclareIndexer(); + }; + if (std::any_of(properties.begin(), properties.end(), + [&isIndexer](ir::AstNode *node) { return isIndexer(node); }) && + isIndexer(property)) { + LogError(diagnostic::MORE_INDEXER, {}, property->Start()); + continue; + } properties.push_back(property); } @@ -932,6 +955,7 @@ std::tuple ParserImpl:: } ir::BlockStatement *body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); return {true, body, body->End(), false}; } @@ -940,6 +964,11 @@ FunctionSignature ParserImpl::ParseFunctionSignature(ParserStatus status) { ir::TSTypeParameterDeclaration *typeParamDecl = ParseFunctionTypeParameters(); + // Check if constructor has type parameters + if ((status & ParserStatus::CONSTRUCTOR_FUNCTION) != 0 && typeParamDecl != nullptr) { + LogError(diagnostic::CONSTRUCTOR_TYPE_PARAMETERS); + } + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { auto parameter = (status & ParserStatus::ARROW_FUNCTION) != 0 ? ParseFunctionParameter() : nullptr; if (parameter != nullptr) { @@ -969,10 +998,8 @@ FunctionSignature ParserImpl::ParseFunctionSignature(ParserStatus status) LogError(diagnostic::EXTENSION_ACCESSOR_RECEIVER); } - ir::ScriptFunctionFlags throwMarker = ParseFunctionThrowMarker(true); - auto res = ir::FunctionSignature(typeParamDecl, std::move(params), returnTypeAnnotation, hasReceiver); - return {std::move(res), throwMarker}; + return {std::move(res), ir::ScriptFunctionFlags::NONE}; } ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus) @@ -997,6 +1024,7 @@ ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus) functionContext.Flags(), // CC-OFFNXT(G.FMT.02-CPP) project code style {}, // CC-OFFNXT(G.FMT.02-CPP) project code style context_.GetLanguage()}); // CC-OFF(G.FMT.02-CPP) project code style + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({startLoc, endLoc}); @@ -1020,12 +1048,9 @@ ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags) argument = ParseExpression(flags); } - if (inPattern && argument->IsAssignmentExpression()) { - LogError(diagnostic::RESTPARAM_INIT); - } - auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT; auto *spreadElementNode = AllocNode(nodeType, Allocator(), argument); + ES2PANDA_ASSERT(spreadElementNode != nullptr); spreadElementNode->SetRange({startLocation, argument->End()}); return spreadElementNode; } @@ -1193,6 +1218,39 @@ ArenaVector &ParserImpl::ParseExpressionsArrayFormatPlaceholde ES2PANDA_UNREACHABLE(); } +bool ParserImpl::ParsePunctuatorGreaterThan(bool throwError) +{ + switch (Lexer()->GetToken().Type()) { + 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; + } + default: { + if (throwError) { + LogError(diagnostic::EXPECTED_PARAM_GOT_PARAM, + {TokenToString(lexer::TokenType::PUNCTUATOR_GREATER_THAN), + TokenToString(Lexer()->GetToken().Type())}); + } + return false; + } + } + Lexer()->NextToken(); // eat `>` + return true; +} + util::StringView ParserImpl::ParseSymbolIteratorIdentifier() const noexcept { // Duplicate check - just in case of improper call! @@ -1224,6 +1282,51 @@ util::StringView ParserImpl::ParseSymbolIteratorIdentifier() const noexcept return util::StringView {compiler::Signatures::ITERATOR_METHOD}; } +void ParserImpl::EatTypeAnnotation() +{ + lexer_->NextToken(); // eat ':' or '|' + if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + LogUnexpectedToken(lexer_->GetToken()); + auto pos = lexer_->Save(); + lexer_->NextToken(); + while (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + // just skip usls tokens, we have an identifier after + lexer_->Rewind(pos); + lexer_->NextToken(); + pos = lexer_->Save(); + } + if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { + // if next token is not an ident, so current token should be an identifier + // and we set it as literal ident + lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); + lexer_->GetToken().SetTokenStr(ERROR_LITERAL); + } + } + lexer_->NextToken(); // eat type + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) { + EatTypeAnnotation(); + } +} + +void ParserImpl::ParseIndexSignature() +{ + if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + return; + } + lexer_->NextToken(); // eat param + + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { + return; + } + + EatTypeAnnotation(); + + if (!lexer_->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET)) { + return; + } + EatTypeAnnotation(); +} + ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, bool isUserDefinedType, TypeAnnotationParsingOptions options) { @@ -1236,8 +1339,7 @@ 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)) { + if (!IsValidIdentifierName(token) && ((options & TypeAnnotationParsingOptions::ADD_TYPE_PARAMETER_BINDING) == 0)) { LogError(diagnostic::PREDEFINED_TYPE_AS_IDENTIFIER, {token.Ident()}, tokenStart); lexer_->NextToken(); return AllocBrokenExpression(tokenStart); @@ -1254,18 +1356,29 @@ ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, } else if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { // Special case for processing of special '[Symbol.iterator]` identifier using in stdlib. tokenName = ParseSymbolIteratorIdentifier(); + if (tokenName.Empty()) { + LogError(diagnostic::ERROR_ARKTS_NO_PROPERTIES_BY_INDEX, {}); + ParseIndexSignature(); + return AllocBrokenExpression(Lexer()->GetToken().Start()); + } } if (tokenName.Empty()) { if ((options & TypeAnnotationParsingOptions::REPORT_ERROR) == 0) { return nullptr; } + if (token.IsLiteral()) { + LogError(diagnostic::LITERAL_VALUE_IDENT, {token.ToString()}, tokenStart); + } else if (token.IsKeyword()) { + LogError(diagnostic::HARD_KEYWORD_IDENT, {token.ToString()}, tokenStart); + } LogError(diagnostic::IDENTIFIER_EXPECTED_HERE, {TokenToString(tokenType)}, tokenStart); lexer_->NextToken(); return AllocBrokenExpression(tokenStart); } auto *ident = AllocNode(tokenName, Allocator()); + ES2PANDA_ASSERT(ident != nullptr); // NOTE: here actual token can be changed! ident->SetRange({tokenStart, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -1441,6 +1554,7 @@ ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourcePosition &p ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourceRange &range) { auto *node = AllocNode(Allocator()); + ES2PANDA_ASSERT(node != nullptr); node->SetRange(range); return node; } @@ -1453,6 +1567,7 @@ ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourcePosition &pos) ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourceRange &range) { auto node = AllocNode(Allocator()); + ES2PANDA_ASSERT(node != nullptr); node->SetRange(range); return node; } diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index d64de90591844ae65634a889dd50971c16c1b197..cd39352b1d1015be72c794a3ccb5842142086e0e 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -26,6 +26,7 @@ #include "parser/program/program.h" #include "util/diagnosticEngine.h" #include "util/helpers.h" +#include "util/recursiveGuard.h" namespace ark::es2panda::lexer { class RegExpParser; @@ -37,6 +38,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; @@ -59,7 +64,9 @@ enum class TypeAnnotationParsingOptions : uint32_t { ALLOW_DECLARATION_SITE_VARIANCE = 1U << 14U, DISALLOW_UNION = 1U << 15U, POTENTIAL_NEW_ARRAY = 1U << 16U, - ANNOTATION_NOT_ALLOW = 1U << 17U + ANNOTATION_NOT_ALLOW = 1U << 17U, + INSTANCEOF = 1U << 18U, + TYPE_ALIAS_CONTEXT = 1U << 19U }; class ParserImpl { @@ -77,6 +84,11 @@ public: return false; } + [[nodiscard]] virtual bool IsValidIdentifierName([[maybe_unused]] const lexer::Token &token) const noexcept + { + return true; + } + ETSParser *AsETSParser() { ES2PANDA_ASSERT(IsETSParser()); @@ -101,6 +113,16 @@ public: lexer::SourcePosition GetPositionForDiagnostic() const; + void SetContext(public_lib::Context *ctx) + { + ctx_ = ctx; + } + + public_lib::Context *Context() const + { + return ctx_; + } + protected: virtual void ParseProgram(ScriptKind kind); static ExpressionParseFlags CarryExpressionParserFlag(ExpressionParseFlags origin, ExpressionParseFlags carry); @@ -113,7 +135,7 @@ protected: ir::VariableDeclaratorFlag GetFlag(VariableParsingFlags flags); - void ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags); + void ValidateAccessor(ExpressionParseFlags flags); void CheckPropertyKeyAsyncModifier(ParserStatus *methodStatus); ir::Property *ParseShorthandProperty(const lexer::LexerPosition *startPos); void ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus); @@ -126,7 +148,8 @@ protected: // ExpressionParser.Cpp ir::Expression *ParseKeywordExpression(); - ir::Expression *ParseBinaryExpression(ir::Expression *left, const lexer::TokenType operatorType); + ir::Expression *ParseBinaryExpression(ir::Expression *left, + ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); void ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression); ir::Expression *ParseMemberExpression(bool ignoreCallExpression = false, ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); @@ -136,7 +159,7 @@ protected: void ValidateGroupedExpression(ir::Expression *lhsExpression); ir::Expression *ParseImportExpression(); ir::Expression *ParseOptionalChain(ir::Expression *leftSideExpr); - ir::Expression *ParsePropertyKey(ExpressionParseFlags flags); + virtual ir::Expression *ParsePropertyKey(ExpressionParseFlags flags); void ValidateAssignmentTarget(ExpressionParseFlags flags, ir::Expression *node); void ValidateLvalueAssignmentTarget(ir::Expression *node); void ValidateArrowParameterBindings(const ir::Expression *node); @@ -176,6 +199,7 @@ protected: friend class ETSNolintParser; friend class lexer::RegExpParser; friend class util::SourcePositionHelper; + friend class JsdocHelper; void LogExpectedToken(lexer::TokenType tokenType); void LogUnexpectedToken(lexer::TokenType tokenType); @@ -227,6 +251,9 @@ protected: return false; } + void ParseIndexSignature(); + void EatTypeAnnotation(); + bool ParsePunctuatorGreaterThan(bool throwError = true); util::StringView ParseSymbolIteratorIdentifier() const noexcept; ir::Identifier *ExpectIdentifier(bool isReference = false, bool isUserDefinedType = false, TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR); @@ -291,6 +318,8 @@ protected: // NOLINTNEXTLINE(google-default-arguments) virtual ir::Statement *ParseStructStatement(StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags = ir::ModifierFlags::NONE); + virtual ir::Statement *ParseInterfaceStatement(StatementParsingFlags flags); + virtual ir::Statement *ParseEnumStatement(StatementParsingFlags flags); ir::Statement *ParseStatementBasedOnTokenType(StatementParsingFlags flags); ir::Statement *ParseVarStatement(); ir::Statement *ParseLetStatement(StatementParsingFlags flags); @@ -410,6 +439,7 @@ protected: virtual ir::AnnotatedExpression *ParseVariableDeclaratorKey(VariableParsingFlags flags); virtual ir::Statement *ParseAnnotationsInStatement(StatementParsingFlags flags); + virtual ir::Statement *ParseInitModuleStatement(StatementParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclarator(ir::Expression *init, lexer::SourcePosition startLoc, VariableParsingFlags flags); virtual ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, @@ -460,11 +490,6 @@ protected: return nullptr; } - virtual ir::ScriptFunctionFlags ParseFunctionThrowMarker([[maybe_unused]] const bool isRethrowsAllowed) - { - return ir::ScriptFunctionFlags::NONE; - } - using NodeFormatType = std::tuple; virtual ir::Identifier *ParseIdentifierFormatPlaceholder(std::optional nodeFormat); virtual ir::Statement *ParseStatementFormatPlaceholder(); @@ -560,6 +585,11 @@ protected: const std::function &parseElement, lexer::SourcePosition *sourceEnd = nullptr, bool allowTrailingSep = false); + RecursiveContext &RecursiveCtx() + { + return recursiveCtx_; + } + private: bool GetCanBeForInOf(ir::Expression *leftNode, ir::AstNode *initNode); Program *program_; @@ -569,6 +599,8 @@ private: lexer::Lexer *lexer_ {}; const util::Options *options_; util::DiagnosticEngine &diagnosticEngine_; + public_lib::Context *ctx_ {nullptr}; + RecursiveContext recursiveCtx_; }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index cd4ef559335f29546def94def9687fae01b755d2..2386dc848ad4ad7a2be23e166b0248c2334a7049 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,59 @@ #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()), + extension_(varbinder != nullptr ? varbinder->Extension() : ScriptExtension::INVALID), 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()); +} + +bool Program::IsGenAbcForExternal() const { + return compiler::GetPhaseManager()->Context()->config->options->GetCompilationMode() == + CompilationMode::GEN_ABC_FOR_EXTERNAL_SOURCE && + genAbcForExternalSource_; } std::string Program::Dump() const @@ -50,12 +94,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() @@ -84,6 +132,7 @@ void Program::SetPackageInfo(const util::StringView &name, util::ModuleKind kind // NOTE(vpukhov): part of ongoing design void Program::MaybeTransformToDeclarationModule() { + ES2PANDA_ASSERT(ast_ != nullptr); if (IsPackage() || ast_->Statements().empty()) { return; } @@ -112,6 +161,37 @@ 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; +} + +void Program::RemoveAstChecked() +{ + 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 +204,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..fbb24ddfd2e1089f694870eeeca6edd1bc22e76c 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,15 +35,38 @@ 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 }; +enum class ScriptKind { SCRIPT, MODULE, STDLIB, GENEXTERNAL }; + +#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: @@ -51,10 +76,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 +102,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 +190,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 +275,25 @@ public: return moduleInfo_.kind == util::ModuleKind::PACKAGE; } - void MarkASTAsChecked() + bool IsDeclForDynamicStaticInterop() const { - isASTchecked_ = true; + return moduleInfo_.isDeclForDynamicStaticInterop; } - bool IsASTChecked() const + void SetFlag(ProgramFlags flag); + bool GetFlag(ProgramFlags flag) const; + void SetASTChecked(); + void RemoveAstChecked(); + bool IsASTChecked(); + + void MarkASTAsLowered() { - return isASTchecked_; + isASTlowered_ = true; + } + + bool IsASTLowered() const + { + return isASTlowered_; } bool IsStdLib() const @@ -272,6 +303,13 @@ public: (FileName().Is("etsstdlib")); } + bool IsGenAbcForExternal() const; + + void SetGenAbcForExternalSources(bool genAbc = true) + { + genAbcForExternalSource_ = genAbc; + } + varbinder::ClassScope *GlobalClassScope(); const varbinder::ClassScope *GlobalClassScope() const; @@ -285,16 +323,7 @@ public: void AddNodeToETSNolintCollection(const ir::AstNode *node, const std::set &warningsCollection); bool NodeContainsETSNolint(const ir::AstNode *node, ETSWarnings warning); - std::vector> &DeclGenExportNodes() - { - // NOTE: ExportNodes is not supported now. - return declGenExportNodes_; - } - - void AddDeclGenExportNode(const std::string &declGenExportStr, ir::AstNode *node) - { - declGenExportNodes_.emplace_back(declGenExportStr, node); - } + bool MergeExternalSource(const ExternalSource *externalSource); // The name "IsDied", because correct value of canary is a necessary condition for the life of "Program", but // not sufficient @@ -312,13 +341,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_ {}; @@ -327,19 +383,33 @@ private: ExternalSource externalSources_; DirectExternalSource directExternalSources_; ScriptKind kind_ {}; + bool isASTlowered_ {}; + bool genAbcForExternalSource_ {false}; ScriptExtension extension_ {}; ETSNolintsCollectionMap etsnolintCollection_; util::ModuleInfo moduleInfo_; - bool isASTchecked_ {}; + 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 9cfb10992b8bb3cc5456bfb32bd1c3b0a77c5f82..1a490f379b30ea32b4d6bada6c36e8077bb00f5b 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -62,6 +62,7 @@ #include "lexer/lexer.h" #include "lexer/token/letters.h" #include "lexer/token/sourceLocation.h" +#include "util/recursiveGuard.h" #include "util/ustring.h" #include "generated/diagnostic.h" @@ -90,6 +91,14 @@ ir::Statement *ParserImpl::ParseStatementLiteralIdentHelper(StatementParsingFlag // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParserImpl::ParseStatementPunctuatorsHelper(StatementParsingFlags flags) { + TrackRecursive trackRecursive(RecursiveCtx()); + if (!trackRecursive) { + LogError(diagnostic::DEEP_NESTING); + while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + Lexer()->NextToken(); + } + return AllocBrokenStatement(Lexer()->GetToken().Loc()); + } switch (lexer_->GetToken().Type()) { case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: return ParseBlockStatement(); @@ -179,15 +188,18 @@ 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); lexer_->NextToken(); return nullptr; case lexer::TokenType::KEYW_ENUM: - return ParseEnumDeclaration(); + return ParseEnumStatement(flags); case lexer::TokenType::KEYW_INTERFACE: - return ParseInterfaceDeclaration(false); + return ParseInterfaceStatement(flags); case lexer::TokenType::PUNCTUATOR_AT: if (IsETSParser()) { return ParseAnnotationsInStatement(flags); @@ -198,6 +210,11 @@ ir::Statement *ParserImpl::ParseStatementBasedOnTokenType(StatementParsingFlags } } +ir::Statement *ParserImpl::ParseInitModuleStatement([[maybe_unused]] StatementParsingFlags flags) +{ + ES2PANDA_UNREACHABLE(); +} + ir::Statement *ParserImpl::ParseAnnotationsInStatement([[maybe_unused]] StatementParsingFlags flags) { ES2PANDA_UNREACHABLE(); @@ -217,6 +234,7 @@ ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::LET); + ES2PANDA_ASSERT(variableDecl != nullptr); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -235,6 +253,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) lexer_->NextToken(); auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl != nullptr); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -248,6 +267,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) ir::EmptyStatement *ParserImpl::ParseEmptyStatement() { auto *empty = AllocNode(); + ES2PANDA_ASSERT(empty != nullptr); empty->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return empty; @@ -256,6 +276,7 @@ ir::EmptyStatement *ParserImpl::ParseEmptyStatement() ir::Statement *ParserImpl::ParseDebuggerStatement() { auto *debuggerNode = AllocNode(); + ES2PANDA_ASSERT(debuggerNode != nullptr); debuggerNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); ConsumeSemicolon(debuggerNode); @@ -275,6 +296,7 @@ ir::Statement *ParserImpl::ParseFunctionStatement(StatementParsingFlags flags) stmts.push_back(funcDecl); auto *localBlockStmt = AllocNode(Allocator(), std::move(stmts)); + ES2PANDA_ASSERT(localBlockStmt != nullptr); localBlockStmt->SetRange(funcDecl->Range()); return funcDecl; @@ -289,7 +311,7 @@ ir::Statement *ParserImpl::ParsePotentialExpressionStatement(StatementParsingFla ir::Statement *ParserImpl::ParseStructStatement([[maybe_unused]] StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { - LogError(diagnostic::ILLEGAL_START_EXPRESSION); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"STRUCT"}); return ParseStructDeclaration(modifiers, modFlags); } @@ -304,6 +326,24 @@ ir::Statement *ParserImpl::ParseClassStatement(StatementParsingFlags flags, ir:: return ParseClassDeclaration(modifiers, modFlags); } +ir::Statement *ParserImpl::ParseInterfaceStatement(StatementParsingFlags flags) +{ + if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) { + LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT); + } + + return ParseInterfaceDeclaration(false); +} + +ir::Statement *ParserImpl::ParseEnumStatement(StatementParsingFlags flags) +{ + if ((flags & StatementParsingFlags::ALLOW_LEXICAL) == 0) { + LogError(diagnostic::LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT); + } + + return ParseEnumDeclaration(); +} + ir::Statement *ParserImpl::ParseStructDeclaration(ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags) { const lexer::SourcePosition startLoc = lexer_->GetToken().Start(); @@ -320,6 +360,7 @@ ir::Statement *ParserImpl::ParseStructDeclaration(ir::ClassDefinitionModifiers m lexer::SourcePosition endLoc = classDefinition->End(); auto *structDecl = AllocNode(classDefinition, Allocator()); + ES2PANDA_ASSERT(structDecl != nullptr); structDecl->SetRange({startLoc, endLoc}); return structDecl; } @@ -340,6 +381,7 @@ ir::Statement *ParserImpl::ParseClassDeclaration(ir::ClassDefinitionModifiers mo lexer::SourcePosition endLoc = classDefinition->End(); auto *classDecl = AllocNode(classDefinition, Allocator()); + ES2PANDA_ASSERT(classDecl != nullptr); classDecl->SetRange({startLoc, endLoc}); return classDecl; } @@ -366,6 +408,7 @@ void ParserImpl::ConsumeSemicolon(ir::Statement *statement) auto const &token = lexer_->GetToken(); auto tokenType = token.Type(); if (tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { + ES2PANDA_ASSERT(statement != nullptr); statement->SetEnd(token.End()); lexer_->NextToken(); return; @@ -421,6 +464,7 @@ bool ParserImpl::ParseDirective(ArenaVector *statements) bool isDirective = exprNode->IsStringLiteral(); auto *exprStatement = AllocNode(exprNode); + ES2PANDA_ASSERT(exprStatement != nullptr); exprStatement->SetRange(exprNode->Range()); ConsumeSemicolon(exprStatement); @@ -451,6 +495,7 @@ ir::BlockStatement *ParserImpl::ParseBlockStatement() auto statements = ParseStatementList(); auto *blockNode = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockNode != nullptr); blockNode->SetRange({startLoc, lexer_->GetToken().End()}); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); @@ -482,6 +527,7 @@ ir::Statement *ParserImpl::ParseBreakStatement() } auto *breakStatement = AllocNode(); + ES2PANDA_ASSERT(breakStatement != nullptr); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -501,9 +547,11 @@ ir::Statement *ParserImpl::ParseBreakStatement() } auto *identNode = AllocNode(label, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); auto *breakStatement = AllocNode(identNode); + ES2PANDA_ASSERT(breakStatement != nullptr); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -532,6 +580,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { auto *continueStatement = AllocNode(); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); return continueStatement; @@ -540,6 +589,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() if (lexer_->GetToken().NewLine() || lexer_->GetToken().Type() == lexer::TokenType::EOS || lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { auto *continueStatement = AllocNode(); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, endLoc}); return continueStatement; } @@ -554,9 +604,11 @@ ir::Statement *ParserImpl::ParseContinueStatement() } auto *identNode = AllocNode(label, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); auto *continueStatement = AllocNode(identNode); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -571,8 +623,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 +648,16 @@ 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); + ES2PANDA_ASSERT(doWhileStatement != nullptr); doWhileStatement->SetRange({startLoc, endLoc}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -628,9 +687,11 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { if (canBeAnonymous) { ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE); + ES2PANDA_ASSERT(func != nullptr); func->SetStart(startLoc); auto *funcDecl = AllocNode(Allocator(), func, true); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); return funcDecl; } @@ -645,10 +706,12 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou newStatus |= ParserStatus::FUNCTION_DECLARATION; ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(identNode); func->SetStart(startLoc); auto *funcDecl = AllocNode(Allocator(), func); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); if (func->IsOverload() && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -660,9 +723,11 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) { + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_INIT_MODULE && IsETSParser()) { + return ParseInitModuleStatement(flags); + } const auto startPos = lexer_->Save(); ParserStatus savedStatus = context_.Status(); - auto tokenType = lexer_->GetToken().Type(); if (tokenType == lexer::TokenType::KEYW_PUBLIC || tokenType == lexer::TokenType::KEYW_PRIVATE || tokenType == lexer::TokenType::KEYW_PROTECTED) { @@ -697,10 +762,12 @@ ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) } ir::Expression *exprNode = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); + context_.Status() = savedStatus; lexer::SourcePosition endPos = exprNode->End(); auto *exprStatementNode = AllocNode(exprNode); + ES2PANDA_ASSERT(exprStatementNode != nullptr); exprStatementNode->SetRange({startPos.GetToken().Start(), endPos}); ConsumeSemicolon(exprStatementNode); @@ -724,6 +791,15 @@ std::tuple ParserImpl::Par ir::Expression *rightNode = nullptr; if (lexer_->GetToken().IsForInOf()) { + ES2PANDA_ASSERT(initNode != nullptr); + if (!initNode->IsVariableDeclaration()) { + LogError(diagnostic::INVALID_LEFT_HAND_IN_FOR_OF, {}, lexer_->GetToken().Start()); + return {forKind, rightNode, updateNode}; + } + if (initNode->AsVariableDeclaration()->Declarators().empty()) { + LogError(diagnostic::INVALID_LEFT_HAND_IN_FOR_OF, {}, initNode->Start()); + return {forKind, rightNode, updateNode}; + } const ir::VariableDeclarator *varDecl = initNode->AsVariableDeclaration()->Declarators().front(); if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_IN) { @@ -817,6 +893,8 @@ std::tuple std::tuple ParserImpl::ParseForInOf( ir::Expression *leftNode, ExpressionParseFlags exprFlags, bool isAwait) { + ES2PANDA_ASSERT(lexer_ != nullptr); + ES2PANDA_ASSERT(leftNode != nullptr); ir::Expression *updateNode = nullptr; ir::Expression *rightNode = nullptr; if (lexer_->GetToken().IsForInOf()) { @@ -831,6 +909,7 @@ std::tuple ir::AstNode *initNode = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ? ParseSequenceExpression(expr) : expr; + ES2PANDA_ASSERT(initNode != nullptr); if (initNode->IsConditionalExpression()) { ir::ConditionalExpression *condExpr = initNode->AsConditionalExpression(); @@ -947,6 +1026,8 @@ bool ParserImpl::GetCanBeForInOf(ir::Expression *leftNode, ir::AstNode *initNode if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { lexer_->NextToken(); canBeForInOf = false; + } else if (!initNode->IsVariableDeclaration()) { + LogError(diagnostic::INVALID_LEFT_HAND_IN_FOR_OF); } else if (initNode->AsVariableDeclaration()->Declarators().size() > 1 && lexer_->GetToken().IsForInOf()) { LogError(diagnostic::INVALID_LEFT_HAND_IN_FOR_OF, {}, initNode->AsVariableDeclaration()->Declarators()[1]->Start()); @@ -983,6 +1064,7 @@ ir::Statement *ParserImpl::CreateForStatement(ForStatementNodes &&nodes, ForStat } } + ES2PANDA_ASSERT(forStatement != nullptr); forStatement->SetRange({startLoc, nodes.body->End()}); return forStatement; @@ -1060,6 +1142,7 @@ ir::Statement *ParserImpl::ParseIfStatement() } auto *ifStatement = AllocNode(test, consequent, alternate); + ES2PANDA_ASSERT(ifStatement != nullptr); ifStatement->SetRange({startLoc, endLoc}); return ifStatement; } @@ -1079,6 +1162,7 @@ ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &po SavedParserContext newCtx(this, ParserStatus::IN_LABELED, actualLabel); auto *identNode = AllocNode(actualLabel, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(pos.GetToken().Loc()); lexer_->NextToken(); @@ -1090,6 +1174,7 @@ ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &po ir::Statement *body = ParseStatement(StatementParsingFlags::LABELLED); auto *labeledStatement = AllocNode(identNode, body); + ES2PANDA_ASSERT(labeledStatement != nullptr); labeledStatement->SetRange({pos.GetToken().Start(), body->End()}); return labeledStatement; @@ -1129,6 +1214,7 @@ ir::Statement *ParserImpl::ParseReturnStatement() returnStatement = AllocNode(); } + ES2PANDA_ASSERT(returnStatement != nullptr); returnStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(returnStatement); @@ -1164,6 +1250,7 @@ ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault) default: { LogError(diagnostic::UNEXPECTED_TOKEN_PARAM_EXPECTED_CASE_OR_DEFAULT, {lexer::TokenToString(lexer_->GetToken().Type())}); + testExpr = AllocBrokenExpression(caseStartLoc); } } @@ -1184,6 +1271,7 @@ ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault) } auto *caseNode = AllocNode(testExpr, std::move(consequents)); + ES2PANDA_ASSERT(caseNode != nullptr); caseNode->SetRange({caseStartLoc, caseEndLoc}); return caseNode; } @@ -1215,6 +1303,7 @@ ir::Statement *ParserImpl::ParseSwitchStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); auto *switchStatement = AllocNode(discriminant, std::move(cases)); + ES2PANDA_ASSERT(switchStatement != nullptr); switchStatement->SetRange({startLoc, endLoc}); return switchStatement; } @@ -1239,6 +1328,7 @@ ir::Statement *ParserImpl::ParseThrowStatement() lexer::SourcePosition endLoc = expression->End(); auto *throwStatement = AllocNode(expression); + ES2PANDA_ASSERT(throwStatement != nullptr); throwStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(throwStatement); @@ -1290,9 +1380,11 @@ ir::CatchClause *ParserImpl::ParseCatchClause() } ir::BlockStatement *catchBlock = ParseBlockStatement(); + ES2PANDA_ASSERT(catchBlock != nullptr); lexer::SourcePosition endLoc = catchBlock->End(); auto *catchClause = AllocNode(param, catchBlock); + ES2PANDA_ASSERT(catchClause != nullptr); catchClause->SetRange({catchStartLoc, endLoc}); return catchClause; @@ -1329,6 +1421,7 @@ ir::Statement *ParserImpl::ParseTryStatement() while (lexer_->GetToken().Type() == lexer::TokenType::KEYW_CATCH) { catchClause = ParseCatchClause(); + ES2PANDA_ASSERT(catchClause != nullptr); endLoc = catchClause->End(); catchClauses.push_back(catchClause); } @@ -1337,12 +1430,14 @@ ir::Statement *ParserImpl::ParseTryStatement() lexer_->NextToken(); // eat 'finally' keyword finallyClause = ParseBlockStatement(); + ES2PANDA_ASSERT(finallyClause != nullptr); endLoc = finallyClause->End(); } ArenaVector> finalizerInsertions(Allocator()->Adapter()); auto *tryStatement = AllocNode(body, std::move(catchClauses), finallyClause, finalizerInsertions); + ES2PANDA_ASSERT(tryStatement != nullptr); tryStatement->SetRange({startLoc, endLoc}); return tryStatement; } @@ -1484,6 +1579,11 @@ ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags) ir::VariableDeclarator *declarator = ParseVariableDeclarator(flags); if (declarator != nullptr) { // Error processing. declarators.push_back(declarator); + if (declarator->Init() != nullptr && declarator->Init()->IsETSClassLiteral()) { + ParseClassBody({}); + LogError(diagnostic::UNSUPPORTED_CLASS_LITERAL); + return AllocBrokenStatement(declarator->Init()->Start()); + } } if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA) { @@ -1507,6 +1607,7 @@ ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags) lexer::SourcePosition endLoc = declarators.back()->End(); auto *declaration = AllocNode(varKind, Allocator(), std::move(declarators)); + ES2PANDA_ASSERT(declaration != nullptr); declaration->SetRange({startLoc, endLoc}); return declaration; @@ -1518,17 +1619,23 @@ 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); + ES2PANDA_ASSERT(whileStatement != nullptr); whileStatement->SetRange({startLoc, endLoc}); return whileStatement; @@ -1579,6 +1686,7 @@ ir::ExportDefaultDeclaration *ParserImpl::ParseExportDefaultDeclaration(const le ES2PANDA_ASSERT(declNode != nullptr); lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -1602,6 +1710,7 @@ ir::Identifier *ParserImpl::ParseNamedExport(lexer::Token *exportedToken) const util::StringView &exportedString = exportedToken->Ident(); auto *exported = AllocNode(exportedString, Allocator()); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(exportedToken->Loc()); return exported; @@ -1619,9 +1728,11 @@ ir::ExportAllDeclaration *ParserImpl::ParseExportAllDeclaration(const lexer::Sou lexer_->NextToken(); // eat exported name } ir::StringLiteral *source = ParseFromClause(); + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *exportDeclaration = AllocNode(source, exported); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(exportDeclaration); @@ -1676,6 +1787,7 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: } auto *exportDeclaration = AllocNode(Allocator(), source, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endPos}); ConsumeSemicolon(exportDeclaration); @@ -1730,6 +1842,7 @@ ir::Statement *ParserImpl::ParseNamedExportDeclaration(const lexer::SourcePositi lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -1778,6 +1891,7 @@ void ParserImpl::ParseNameSpaceImport(ArenaVector *specifiers) ir::Identifier *local = ParseNamedImport(&lexer_->GetToken()); auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, lexer_->GetToken().End()}); specifiers->push_back(specifier); @@ -1795,6 +1909,7 @@ ir::Identifier *ParserImpl::ParseNamedImport(lexer::Token *importedToken) CheckRestrictedBinding(importedToken->KeywordType()); auto *local = AllocNode(importedToken->Ident(), Allocator()); + ES2PANDA_ASSERT(local != nullptr); local->SetRange(importedToken->Loc()); return local; @@ -1841,6 +1956,7 @@ ir::AstNode *ParserImpl::ParseImportDefaultSpecifier(ArenaVector lexer_->NextToken(); // eat local name auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); @@ -1873,6 +1989,7 @@ ir::StringLiteral *ParserImpl::ParseFromClause(bool requireFrom) } auto *source = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(source != nullptr); source->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -1929,8 +2046,10 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) source = ParseFromClause(false); } + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); @@ -1945,19 +2064,24 @@ 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); + ES2PANDA_ASSERT(broken != nullptr); + 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() { auto *empty = AllocNode(); + ES2PANDA_ASSERT(empty != nullptr); empty->SetRange(lexer_->GetToken().Loc()); return empty; } diff --git a/ets2panda/parser/statementTSParser.cpp b/ets2panda/parser/statementTSParser.cpp index 34dce05dc1519e8d5a8204a63f683bc81d4011f4..b0a451bcd38a8e6b9058b610c281183fb618cbb2 100644 --- a/ets2panda/parser/statementTSParser.cpp +++ b/ets2panda/parser/statementTSParser.cpp @@ -131,6 +131,7 @@ ir::TSImportEqualsDeclaration *TSParser::ParseTsImportEqualsDeclaration(const le } auto *id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat id name @@ -190,6 +191,7 @@ ir::ExportDefaultDeclaration *TSParser::ParseExportDefaultDeclaration(const lexe lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -265,6 +267,7 @@ ir::Statement *TSParser::ParseNamedExportDeclaration(const lexer::SourcePosition lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -293,6 +296,7 @@ ir::Statement *TSParser::ParseExportDeclaration(StatementParsingFlags flags) } default: { auto ret = ParseNamedExportDeclaration(startLoc); + ES2PANDA_ASSERT(ret != nullptr); if (ret->IsBrokenStatement()) { return ret; } @@ -322,6 +326,7 @@ ir::Statement *TSParser::ParseConstStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl != nullptr); variableDecl->SetStart(constVarStar); ConsumeSemicolon(variableDecl); @@ -364,8 +369,10 @@ ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsin source = ParseFromClause(false); } + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); diff --git a/ets2panda/public/CMakeLists.txt b/ets2panda/public/CMakeLists.txt index 487f24869d6c34945369d9e00d2bcfe18d3353aa..965ef9d300021cd9e2b19404ce342b52f5264a4c 100644 --- a/ets2panda/public/CMakeLists.txt +++ b/ets2panda/public/CMakeLists.txt @@ -24,6 +24,20 @@ set(ES2PANDA_API ${CMAKE_CURRENT_SOURCE_DIR}/ignoredAllowed.yaml ) +set(CHECK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/out) +set(GENERATED_STAMP ${CHECK_OUTPUT_DIR}/build_consistency_check.stamp) + +find_package(Python3 REQUIRED) +add_custom_command( + OUTPUT ${GENERATED_STAMP} + COMMAND ${Python3_EXECUTABLE} + ./../scripts/check_build_system_consistency.py + "${CMAKE_CURRENT_SOURCE_DIR}/.." + COMMAND ${CMAKE_COMMAND} -E make_directory ${CHECK_OUTPUT_DIR} + COMMAND ${CMAKE_COMMAND} -E touch ${GENERATED_STAMP} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/varbinder/variableFlags.h ${GENERATED_DIR}/options.h @@ -59,7 +73,6 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/checker/types/ts/nonPrimitiveType.h ${ES2PANDA_ROOT}/ir/ts/tsTypeParameterInstantiation.h ${ES2PANDA_ROOT}/ir/module/importDeclaration.h - ${ES2PANDA_ROOT}/checker/types/ets/etsDynamicType.h ${ES2PANDA_ROOT}/ir/statements/doWhileStatement.h ${ES2PANDA_ROOT}/ir/expressions/literals/bigIntLiteral.h ${ES2PANDA_ROOT}/ir/expressions/assignmentExpression.h @@ -131,8 +144,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 @@ -147,7 +160,6 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/ir/ts/tsParenthesizedType.h ${ES2PANDA_ROOT}/ir/ts/tsModuleDeclaration.h ${ES2PANDA_ROOT}/ir/ets/etsPackageDeclaration.h - ${ES2PANDA_ROOT}/checker/types/ets/etsDynamicFunctionType.h ${ES2PANDA_ROOT}/ir/expressions/literals/regExpLiteral.h ${ES2PANDA_ROOT}/ir/ets/etsNewArrayInstanceExpression.h ${ES2PANDA_ROOT}/checker/types/ets/etsVoidType.h @@ -188,6 +200,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/checker/types/ets/etsTupleType.h ${ES2PANDA_ROOT}/checker/types/signature.h ${ES2PANDA_ROOT}/ir/ets/etsPrimitiveType.h + ${ES2PANDA_ROOT}/ir/ets/etsIntrinsicNode.h ${ES2PANDA_ROOT}/ir/as/namedType.h ${ES2PANDA_ROOT}/ir/statements/throwStatement.h ${ES2PANDA_ROOT}/ir/statements/forOfStatement.h @@ -237,6 +250,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/ir/ts/tsImportEqualsDeclaration.h ${ES2PANDA_ROOT}/ir/validationInfo.h ${ES2PANDA_ROOT}/ir/base/methodDefinition.h + ${ES2PANDA_ROOT}/ir/base/overloadDeclaration.h ${ES2PANDA_ROOT}/ir/ts/tsIntersectionType.h ${ES2PANDA_ROOT}/checker/types/ts/nullType.h ${ES2PANDA_ROOT}/checker/types/ts/unknownType.h @@ -321,7 +335,6 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/ir/expressions/objectExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/module/importSpecifier.yaml ${LIBGEN_DIR}/gen/headers/ir/expressions/conditionalExpression.yaml - ${LIBGEN_DIR}/gen/headers/checker/types/ets/etsDynamicFunctionType.yaml ${LIBGEN_DIR}/gen/headers/ir/expressions/callExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/expressions/literals/bigIntLiteral.yaml ${LIBGEN_DIR}/gen/headers/ir/base/classElement.yaml @@ -426,6 +439,7 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/checker/types/ets/intType.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ts/objectLiteralType.yaml ${LIBGEN_DIR}/gen/headers/checker/types/typeFlag.yaml + ${LIBGEN_DIR}/gen/headers/ir/ets/etsIntrinsicNode.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsPackageDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsImportDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ets/etsStructDeclaration.yaml @@ -435,7 +449,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 @@ -446,7 +459,6 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/ir/expressions/blockExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsTypeLiteral.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsTypeParameter.yaml - ${LIBGEN_DIR}/gen/headers/checker/types/ets/etsDynamicType.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ets/charType.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsBooleanKeyword.yaml ${LIBGEN_DIR}/gen/headers/ir/base/spreadElement.yaml @@ -486,6 +498,7 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/ir/expressions/directEvalExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsTypeParameterDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/base/methodDefinition.yaml + ${LIBGEN_DIR}/gen/headers/ir/base/overloadDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsNullKeyword.yaml ${LIBGEN_DIR}/gen/headers/ir/ts/tsInterfaceHeritage.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ts/enumLiteralType.yaml @@ -614,7 +627,7 @@ add_custom_command( OUTPUT ${ES2PANDA_API_GENERATED} COMMAND python3 -B ${CMAKE_CURRENT_SOURCE_DIR}/headers_parser/main.py --es2panda-root "${ES2PANDA_ROOT}" --lib-gen-dir "${LIBGEN_DIR}" --headers ${HEADERS_TO_BE_PARSED} - DEPENDS ${HEADERS_TO_BE_PARSED} ${HEADERS_PARSER_SOURCES} + DEPENDS ${HEADERS_TO_BE_PARSED} ${HEADERS_PARSER_SOURCES} ${GENERATED_STAMP} ) add_custom_target(gen_yamls DEPENDS es2panda_options_gen es2panda_keywords ${ES2PANDA_API_GENERATED} ${HEADERS_PARSER_SOURCES}) @@ -623,13 +636,17 @@ add_custom_target(gen_yamls DEPENDS es2panda_options_gen es2panda_keywords ${ES2 set(ES2PANDA_PUBLIC_SOURCES ${LIB_NAME}.cpp ../declgen_ets2ts/declgenEts2Ts.cpp + ../declgen_ets2ts/isolatedDeclgenChecker.cpp ../util/generateBin.cpp ../util/options.cpp ../util/plugin.cpp ) +if (PANDA_TARGET_WINDOWS) + set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib") +endif() -panda_add_library(es2panda-public ${PANDA_DEFAULT_LIB_TYPE} ${ES2PANDA_PUBLIC_SOURCES}) +panda_frontend_add_library(es2panda-public ${PANDA_DEFAULT_LIB_TYPE} ${ES2PANDA_PUBLIC_SOURCES}) add_dependencies(es2panda-lib gen_api) add_dependencies(es2panda-public es2panda-lib) diff --git a/ets2panda/public/README.md b/ets2panda/public/README.md index 57fe81ca490db4b94a6408c44127110c4c6c1629..819296956a07ff4543543c580bc8cd0d8d012156 100644 --- a/ets2panda/public/README.md +++ b/ets2panda/public/README.md @@ -472,9 +472,7 @@ All the types/classes listed below are represented in the IDL without any change - `Type` - ast_type_additional_children: - `ETSStringType` - - `ETSDynamicType` - `ETSAsyncFuncReturnType` - - `ETSDynamicFunctionType` - `ETSEnumType` - `ETSBigIntType` - ast_variables: diff --git a/ets2panda/public/cppToCTypes.yaml b/ets2panda/public/cppToCTypes.yaml index 42f4006ec8453b53148ce3c45bb6775a489acf39..b65c6a310c6843706a28bd06990e9762fc79c01d 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: @@ -466,7 +466,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\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: @@ -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())-> @@ -2105,7 +2105,7 @@ change_types: namespace: "parser::" cast: expression: >- - auto |es2panda_arg.type.ptr_depth||arg_name|E2p = + auto |es2panda_arg.type.ptr_depth||arg_name|E2p = reinterpret_cast(|arg_name|); var_name: '|arg_name|E2p' reverse_cast: @@ -2135,7 +2135,7 @@ change_types: expression: auto &|arg_name|E2p = *reinterpret_cast(|arg_name|); var_name: '|arg_name|E2p' reverse_cast: - start: >- + start: >- reinterpret_cast( reinterpret_cast(context)->allocator->New( end: '))' @@ -2199,12 +2199,26 @@ change_types: type: name: 'Language' min_ptr_depth: 1 + optional: true new_args: + - type: + name: 'Es2pandaLanguage' + ptr_depth: 0 + name: '|arg_name|' + namespace: '' cast: expression: >- + auto |es2panda_arg.type.ptr_depth||arg_name|E2p = + reinterpret_cast(context)->allocator-> + New(static_cast(|arg_name|)); + default_expression: >- auto |es2panda_arg.type.ptr_depth||arg_name|E2p = reinterpret_cast(context)->allocator-> New(Language::Id::ETS); + reverse_cast: + start: >- + static_cast( + end: '->GetId())' var_name: '|arg_name|E2p' - es2panda_arg: @@ -2212,10 +2226,21 @@ change_types: type: name: 'Language' max_ptr_depth: 0 + optional: true new_args: + - type: + name: 'Es2pandaLanguage' + ptr_depth: 0 + name: '|arg_name|' + namespace: '' cast: expression: >- - ark::es2panda::Language |arg_name|E2p {Language::Id::ETS}; + ark::es2panda::Language |arg_name|E2p {static_cast(|arg_name|)}; + default_expression: ark::es2panda::Language |arg_name|E2p {Language::Id::ETS}; + reverse_cast: + start: >- + static_cast( + end: '.GetId())' var_name: '|arg_name|E2p' - es2panda_arg: @@ -2789,7 +2814,7 @@ change_types: min_ptr_depth: 1 new_args: - type: - name: "ArenaMap" + name: "Map" ptr_depth: '|es2panda_arg.type.ptr_depth_int|' template_args: - type: @@ -3644,6 +3669,26 @@ change_types: current_class: TSInterfaceDeclaration max_ptr_depth: 0 min_ptr_depth: 0 + optional: true + default_new_args: + - name: 'id' + type: + name: es2panda_AstNode + ptr_depth: 1 + - name: 'typeParams' + type: + name: es2panda_AstNode + ptr_depth: 1 + - name: 'body' + type: + name: es2panda_AstNode + ptr_depth: 1 + - name: isStatic + type: + name: bool + - name: isExternal + type: + name: bool new_args: - name: 'id' type: @@ -3663,8 +3708,18 @@ change_types: - name: isExternal type: name: bool + - type: + name: 'Es2pandaLanguage' + ptr_depth: 0 + name: 'language' cast: expression: "\ + auto es2pandaId = reinterpret_cast(id);\n + auto es2pandaTypeParams = reinterpret_cast(typeParams);\n + auto es2pandaBody = reinterpret_cast(body);\n + ark::es2panda::Language es2pandaLang {static_cast(language)};\n + " + default_expression: "\ auto es2pandaId = reinterpret_cast(id);\n auto es2pandaTypeParams = reinterpret_cast(typeParams);\n auto es2pandaBody = reinterpret_cast(body);\n @@ -3679,6 +3734,7 @@ change_types: current_class: ScriptFunction max_ptr_depth: 0 min_ptr_depth: 0 + optional: true new_args: - name: '|arg_name|body' type: @@ -3695,16 +3751,43 @@ change_types: - name: '|arg_name|flags' type: name: int + - type: + name: 'Es2pandaLanguage' + ptr_depth: 0 + name: '|arg_name|lang' + default_new_args: + - name: '|arg_name|body' + type: + name: es2panda_AstNode + ptr_depth: 1 + - name: '|arg_name|signature' + type: + name: es2panda_FunctionSignature + ptr_depth: 1 + - name: '|arg_name|funcFlags' + type: + name: int + ptr_depth: 0 + - name: '|arg_name|flags' + type: + name: int cast: expression: " auto *|arg_name|bodyE2p = reinterpret_cast(|arg_name|body);\n auto |arg_name|signatureE2p = std::move(*reinterpret_cast(|arg_name|signature));\n auto |arg_name|funcFlagsE2p = E2pToIrScriptFunctionFlags((Es2pandaScriptFunctionFlags)|arg_name|funcFlags);\n auto |arg_name|flagsE2p = E2pToIrModifierFlags((Es2pandaModifierFlags)|arg_name|flags);\n - ark::es2panda::Language |arg_name|lang {Language::Id::ETS};\n + ark::es2panda::Language |arg_name|langE2p {static_cast(|arg_name|lang)};\n + " + default_expression: " + auto *|arg_name|bodyE2p = reinterpret_cast(|arg_name|body);\n + auto |arg_name|signatureE2p = std::move(*reinterpret_cast(|arg_name|signature));\n + auto |arg_name|funcFlagsE2p = E2pToIrScriptFunctionFlags((Es2pandaScriptFunctionFlags)|arg_name|funcFlags);\n + auto |arg_name|flagsE2p = E2pToIrModifierFlags((Es2pandaModifierFlags)|arg_name|flags);\n + ark::es2panda::Language |arg_name|langE2p {Language::Id::ETS};\n " var_name: "ir::ScriptFunction::ScriptFunctionData {|arg_name|bodyE2p, std::move(|arg_name|signatureE2p), - |arg_name|funcFlagsE2p, |arg_name|flagsE2p, |arg_name|lang}" + |arg_name|funcFlagsE2p, |arg_name|flagsE2p, |arg_name|langE2p}" - es2panda_arg: name: '|arg_name|' diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 4d549eb26cef6c305b742c04860ed7efd21445df..81b369462330b35829cc53c73e1945778f69c393 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -14,6 +14,7 @@ */ #include "es2panda_lib.h" +#include #include #include @@ -27,14 +28,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" @@ -132,7 +131,7 @@ __attribute__((unused)) es2panda_variantDoubleCharArrayBool EnumMemberResultToEs // NOLINTBEGIN(cppcoreguidelines-pro-type-union-access) // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-simplify-subscript-expr) es2panda_variantDoubleCharArrayBool es2panda_variant; - es2panda_variant.index = variant.index(); + es2panda_variant.index = static_cast(variant.index()); switch (es2panda_variant.index) { case es2panda_variantIndex::CAPI_DOUBLE: es2panda_variant.variant.d = std::get(variant); @@ -214,10 +213,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))) { @@ -235,19 +248,34 @@ 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; } delete cfg->options; + cfg->diagnosticEngine->FlushDiagnostic(); delete cfg->diagnosticEngine; delete cfg; } +extern "C" __attribute__((unused)) char const *GetAllErrorMessages(es2panda_Context *context) +{ + auto *ctx = reinterpret_cast(context); + ES2PANDA_ASSERT(ctx != nullptr); + ES2PANDA_ASSERT(ctx->config != nullptr); + ES2PANDA_ASSERT(ctx->allocator != nullptr); + auto *cfg = reinterpret_cast(ctx->config); + ES2PANDA_ASSERT(cfg != nullptr); + ES2PANDA_ASSERT(cfg->diagnosticEngine != nullptr); + auto allMessages = cfg->diagnosticEngine->PrintAndFlushErrorDiagnostic(); + size_t bufferSize = allMessages.length() + 1; + char *cStringMessages = reinterpret_cast(ctx->allocator->Alloc(bufferSize)); + [[maybe_unused]] auto err = memcpy_s(cStringMessages, bufferSize, allMessages.c_str(), bufferSize); + ES2PANDA_ASSERT(err == EOK); + return cStringMessages; +} + extern "C" const es2panda_Options *ConfigGetOptions(es2panda_Config *config) { auto options = reinterpret_cast(config)->options; @@ -265,78 +293,233 @@ static void CompileJob(public_lib::Context *context, varbinder::FunctionScope *s funcEmitter.Generate(); } -__attribute__((unused)) static es2panda_Context *CreateContext(es2panda_Config *config, std::string &&source, - const char *fileName) +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->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; +} + +static Context *InitContext(es2panda_Config *config) { 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; - return reinterpret_cast(res); + return res; } if (cfg->options->GetExtension() != ScriptExtension::ETS) { res->errorMessage = "Invalid extension. Plugin API supports only ETS."; res->state = ES2PANDA_STATE_ERROR; - return reinterpret_cast(res); + res->diagnosticEngine = cfg->diagnosticEngine; + return 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->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); + return res; +} - varbinder->SetProgram(res->parserProgram); +__attribute__((unused)) static es2panda_Context *CreateContext(es2panda_Config *config, std::string &&source, + const char *fileName, + es2panda_GlobalContext *globalContext, bool isExternal, + bool genStdLib) +{ + auto res = InitContext(config); + if (res->state == ES2PANDA_STATE_ERROR) { + return reinterpret_cast(res); + } + auto *cfg = reinterpret_cast(config); - varbinder->SetContext(res); - res->codeGenCb = CompileJob; - res->phaseManager = new compiler::PhaseManager(ScriptExtension::ETS, res->allocator); - res->emitter = new compiler::ETSEmitter(res); - res->program = nullptr; - res->state = ES2PANDA_STATE_NEW; + res->isExternal = isExternal; + res->globalContext = reinterpret_cast(globalContext); + + 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); + } + + 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 *CreateCacheContextFromString(es2panda_Config *config, + const char *source, + char const *fileName, + es2panda_GlobalContext *globalContext, + bool isExternal) +{ + return CreateContext(config, std::string(source), fileName, globalContext, isExternal, false); +} + +extern "C" __attribute__((unused)) es2panda_Context *CreateContextFromMultiFile(es2panda_Config *config, + char const *sourceFileNames) +{ + return CreateContext(config, "", sourceFileNames, 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); +} + +extern __attribute__((unused)) es2panda_Context *CreateContextGenerateAbcForExternalSourceFiles( + es2panda_Config *config, int fileNamesCount, char const *const *fileNames) +{ + auto res = InitContext(config); + if (res->state == ES2PANDA_STATE_ERROR) { + return reinterpret_cast(res); + } + auto *cfg = reinterpret_cast(config); + + ES2PANDA_ASSERT(cfg->options->IsSimultaneous()); + for (size_t i = 0; i < static_cast(fileNamesCount); ++i) { + const char *cName = *(fileNames + i); + std::string fileName(cName); + res->sourceFileNames.emplace_back(std::move(fileName)); + } + + res->input = ""; + res->sourceFileName = ""; + res->sourceFile = new SourceFile(res->sourceFileName, res->input, cfg->options->IsModule()); + ir::DisableContextHistory(); + res->allocator = new ThreadSafeArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + + InitializeContext(res); + return reinterpret_cast(res); +} + +extern "C" __attribute__((unused)) es2panda_Context *CreateContextFromStringWithHistory(es2panda_Config *config, + const char *source, + char const *fileName) +{ + // NOTE: gogabr. avoid copying source. + es2panda_Context *context = CreateContextFromString(config, source, fileName); + ir::EnableContextHistory(); + return context; } __attribute__((unused)) static Context *Parse(Context *ctx) @@ -347,16 +530,42 @@ __attribute__((unused)) static Context *Parse(Context *ctx) return ctx; } - ctx->phaseManager->Restart(); - 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->phaseManager->Reset(); + + if (ctx->isExternal && ctx->allocator != ctx->globalContext->stdLibAllocator) { + ctx->sourceFileNames.emplace_back(ctx->sourceFileName); + parser::ETSParser::AddGenExtenralSourceToParseList(ctx); + } else if (ctx->config->options->IsSimultaneous()) { + parser::ETSParser::AddGenExtenralSourceToParseList(ctx); + std::unordered_set sourceFileNamesSet(ctx->sourceFileNames.begin(), ctx->sourceFileNames.end()); + ctx->MarkGenAbcForExternal(sourceFileNamesSet, ctx->parserProgram->ExternalSources()); + } else { + ctx->parser->ParseScript(*ctx->sourceFile, + ctx->config->options->GetCompilationMode() == CompilationMode::GEN_STD_LIB); + } + ctx->state = ES2PANDA_STATE_PARSED; + ctx->phaseManager->SetCurrentPhaseIdToAfterParse(); return ctx; } +__attribute__((unused)) static bool SetProgramGenAbc(Context *ctx, const char *path) +{ + util::StringView pathView(path); + public_lib::Context *context = reinterpret_cast(ctx); + for (auto &[_, extPrograms] : context->externalSources) { + (void)_; + for (auto *prog : extPrograms) { + if (prog->AbsoluteName() == pathView) { + prog->SetGenAbcForExternalSources(); + return true; + } + } + } + return false; +} + __attribute__((unused)) static Context *Bind(Context *ctx) { - // NOTE: Remove duplicated code in all phases if (ctx->state < ES2PANDA_STATE_PARSED) { ctx = Parse(ctx); } @@ -366,12 +575,12 @@ __attribute__((unused)) static Context *Bind(Context *ctx) ES2PANDA_ASSERT(ctx->state == ES2PANDA_STATE_PARSED); while (auto phase = ctx->phaseManager->NextPhase()) { - phase->Apply(ctx, ctx->parserProgram); - if (phase->Name() == compiler::ResolveIdentifiers::NAME) { + if (phase->Name() == "plugins-after-bind") { break; } + phase->Apply(ctx, ctx->parserProgram); } - ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_BOUND : ES2PANDA_STATE_ERROR; + ctx->state = ES2PANDA_STATE_BOUND; return ctx; } @@ -387,15 +596,37 @@ __attribute__((unused)) static Context *Check(Context *ctx) ES2PANDA_ASSERT(ctx->state >= ES2PANDA_STATE_PARSED && ctx->state < ES2PANDA_STATE_CHECKED); while (auto phase = ctx->phaseManager->NextPhase()) { - phase->Apply(ctx, ctx->parserProgram); - if (phase->Name() == compiler::CheckerPhase::NAME) { + if (phase->Name() == "plugins-after-check") { break; } + 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) { @@ -411,6 +642,18 @@ __attribute__((unused)) static Context *Lower(Context *ctx) 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; } @@ -498,6 +741,7 @@ extern "C" __attribute__((unused)) es2panda_Context *ProceedToState(es2panda_Con ctx->state = ES2PANDA_STATE_ERROR; break; } + return reinterpret_cast(ctx); } @@ -506,17 +750,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); @@ -614,6 +868,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; @@ -637,14 +897,72 @@ 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, es2panda_SourcePosition *pos) +{ + auto *allocator = reinterpret_cast(context)->allocator; + auto diagnosticInfo = allocator->New(); + diagnosticInfo->kind = kind; + diagnosticInfo->args = args; + diagnosticInfo->argc = argc; + diagnosticInfo->pos = pos; + return diagnosticInfo; +} + +extern "C" es2panda_SuggestionInfo *CreateSuggestionInfo(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, const char *substitutionCode, + const char *title, es2panda_SourceRange *range) +{ + auto *allocator = reinterpret_cast(context)->allocator; + auto suggestionInfo = allocator->New(); + suggestionInfo->kind = kind; + suggestionInfo->args = args; + suggestionInfo->argc = argc; + suggestionInfo->substitutionCode = substitutionCode; + suggestionInfo->title = title; + suggestionInfo->range = range; + return suggestionInfo; +} + +extern "C" void LogDiagnosticWithSuggestion(es2panda_Context *context, const es2panda_DiagnosticInfo *diagnosticInfo, + const es2panda_SuggestionInfo *suggestionInfo) +{ + 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 E2pRange = reinterpret_cast(suggestionInfo->range); + auto posE2p = reinterpret_cast(diagnosticInfo->pos); + auto suggestion = ctx->diagnosticEngine->CreateSuggestion( + suggestionkind, suggestionParams, suggestionInfo->substitutionCode, suggestionInfo->title, 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) { @@ -677,7 +995,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) @@ -685,6 +1008,21 @@ 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 SourcePositionCol([[maybe_unused]] es2panda_Context *context, es2panda_SourcePosition *position) +{ + static const size_t EMPTY = 1; + auto es2pandaPosition = reinterpret_cast(position); + if (es2pandaPosition->Program() == nullptr) { + return EMPTY; + } + return es2pandaPosition->ToLocation().col; +} + extern "C" size_t SourcePositionIndex([[maybe_unused]] es2panda_Context *context, es2panda_SourcePosition *position) { return reinterpret_cast(position)->index; @@ -737,7 +1075,7 @@ 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) { @@ -769,30 +1107,264 @@ extern "C" es2panda_AstNode *DeclarationFromIdentifier([[maybe_unused]] es2panda return reinterpret_cast(compiler::DeclarationFromIdentifier(E2pNode)); } +extern "C" bool IsImportTypeKind([[maybe_unused]] es2panda_Context *context, es2panda_AstNode *node) +{ + auto E2pNode = reinterpret_cast(node); + if (E2pNode->IsETSImportDeclaration()) { + return E2pNode->AsETSImportDeclaration()->IsTypeKind(); + } + + if (E2pNode->IsImportDeclaration()) { + return E2pNode->AsETSImportDeclaration()->IsTypeKind(); + } + + auto ctx = reinterpret_cast(context); + auto id = ctx->config->diagnosticKindStorage.size() + 1; + auto type = util::DiagnosticType::PLUGIN_WARNING; + util::DiagnosticMessageParams params {}; + diagnostic::DiagnosticKind *kind = &ctx->config->diagnosticKindStorage.emplace_back(type, id, "Insert wrong node!"); + ctx->diagnosticEngine->LogDiagnostic(*kind, params, E2pNode->Start()); + return false; +} + +extern "C" char *GetLicenseFromRootNode(es2panda_Context *ctx, es2panda_AstNode *node) +{ + auto E2pNode = reinterpret_cast(node); + auto *allocator = reinterpret_cast(ctx)->allocator; + return StringViewToCString(allocator, compiler::GetLicenseFromRootNode(E2pNode)); +} + +extern "C" char *JsdocStringFromDeclaration([[maybe_unused]] es2panda_Context *ctx, es2panda_AstNode *node) +{ + auto E2pNode = reinterpret_cast(node); + auto *allocator = reinterpret_cast(ctx)->allocator; + return StringViewToCString(allocator, compiler::JsdocStringFromDeclaration(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) + const char *outputEts, bool exportAll, + bool isolated, const char *recordFile) { 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; declgenOptions.outputDeclEts = outputDeclEts ? outputDeclEts : ""; declgenOptions.outputEts = outputEts ? outputEts : ""; + declgenOptions.isolated = isolated; + declgenOptions.recordFile = recordFile ? recordFile : ""; return ark::es2panda::declgen_ets2ts::GenerateTsDeclarations(checker, ctxImpl->parserProgram, declgenOptions) ? 0 : 1; } +// #28937 Will be removed after binary import support is fully implemented. +__attribute__((unused)) static std::string GetFileNameByPath(const std::string &path) +{ + auto lastSlash = path.find_last_of("/\\"); + std::string filename = (lastSlash == std::string::npos) ? path : path.substr(lastSlash + 1); + + auto lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename = filename.substr(0, lastDot); + } + + lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename = filename.substr(0, lastDot); + } + + return filename; +} + +// #28937 Will be removed after binary import support is fully implemented. +__attribute__((unused)) static bool HandleMultiFileMode(Context *ctxImpl, const std::string &outputPath) +{ + std::string outputStem = GetFileNameByPath(outputPath); + auto &externalSources = ctxImpl->parserProgram->DirectExternalSources(); + + for (const auto &entry : externalSources) { + for (auto *prog : entry.second) { + if (prog == nullptr || !prog->IsGenAbcForExternal()) { + continue; + } + + if (prog->FileName().Mutf8() == outputStem) { + compiler::HandleGenerateDecl(*prog, *ctxImpl->diagnosticEngine, outputPath); + return !ctxImpl->diagnosticEngine->IsAnyError(); + } + } + } + + return false; +} + +// #28937 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; + } + + // Multiple file mode + if (ctxImpl->config->options->IsSimultaneous()) { + bool success = HandleMultiFileMode(ctxImpl, outputPath); + return success ? 0 : 1; + } + + // Single file mode + compiler::HandleGenerateDecl(*ctxImpl->parserProgram, *ctxImpl->diagnosticEngine, outputPath); + 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); + + auto &stmt = parserProgram->Ast()->StatementsForUpdates(); + bool hasUseStatic = !stmt.empty() && stmt.front()->IsExpressionStatement(); + if (hasUseStatic) { + auto *expansion = stmt.front()->AsExpressionStatement()->GetExpression(); + hasUseStatic = hasUseStatic && expansion->IsStringLiteral() && + expansion->AsStringLiteral()->Str() == compiler::Signatures::STATIC_PROGRAM_FLAG; + } + size_t insertIndex = hasUseStatic ? 1 : 0; - parserProgram->Ast()->Statements().insert(parserProgram->Ast()->Statements().begin(), importDeclE2p); + stmt.insert(stmt.begin() + insertIndex, importDeclE2p); importDeclE2p->SetParent(parserProgram->Ast()); ctx->parser->AsETSParser()->AddExternalSource(ctx->parser->AsETSParser()->ParseSources()); @@ -802,16 +1374,44 @@ 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, + GetAllErrorMessages, ConfigGetOptions, CreateContextFromFile, + CreateCacheContextFromFile, CreateContextFromString, + CreateContextFromStringWithHistory, + CreateCacheContextFromString, + CreateContextGenerateAbcForExternalSourceFiles, ProceedToState, DestroyContext, + CreateGlobalContext, + DestroyGlobalContext, ContextState, ContextErrorMessage, ContextProgram, @@ -830,27 +1430,44 @@ es2panda_Impl g_impl = { UpdateNumberLiteral, CreateNumberLiteral, UpdateNumberLiteral, + NumberLiteralStrConst, AllocMemory, CreateSourcePosition, CreateSourceRange, + SourcePositionCol, SourcePositionIndex, SourcePositionLine, SourceRangeStart, SourceRangeEnd, CreateDiagnosticKind, + CreateDiagnosticInfo, + CreateSuggestionInfo, + LogDiagnosticWithSuggestion, LogDiagnostic, GetSemanticErrors, GetSyntaxErrors, GetPluginErrors, GetWarnings, + IsAnyError, AstNodeFindNearestScope, AstNodeRebind, AstNodeRecheck, Es2pandaEnumFromString, Es2pandaEnumToString, DeclarationFromIdentifier, + IsImportTypeKind, + JsdocStringFromDeclaration, + GetLicenseFromRootNode, + 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 ced577b98809ee6217a08d179d8db87e2086db8e..a1562a4fd690c3c9a576037d2ff968a103a2f1f3 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; @@ -131,7 +132,6 @@ typedef struct es2panda_OverloadInfo { enum es2panda_ContextState { ES2PANDA_STATE_NEW, ES2PANDA_STATE_PARSED, - ES2PANDA_STATE_SCOPE_INITED, ES2PANDA_STATE_BOUND, ES2PANDA_STATE_CHECKED, ES2PANDA_STATE_LOWERED, @@ -140,6 +140,33 @@ enum es2panda_ContextState { ES2PANDA_STATE_ERROR }; + +typedef struct es2panda_SuggestionInfo { + const es2panda_DiagnosticKind *kind; + const char **args; + size_t argc; + const char *substitutionCode; + const char *title; + es2panda_SourceRange *range; +} es2panda_SuggestionInfo; + +typedef struct es2panda_DiagnosticInfo { + const es2panda_DiagnosticKind *kind; + const char **args; + size_t argc; + es2panda_SourcePosition *pos; +} es2panda_DiagnosticInfo; + +enum es2panda_PluginDiagnosticType { ES2PANDA_PLUGIN_WARNING, ES2PANDA_PLUGIN_ERROR, ES2PANDA_PLUGIN_SUGGESTION }; + +typedef enum Es2pandaLanguage { + LANGUAGE_AS, + LANGUAGE_JS, + LANGUAGE_TS, + LANGUAGE_ETS, +} Es2pandaLanguage; + +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" @@ -147,15 +174,32 @@ 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); + char const *(*GetAllErrorMessages)(es2panda_Context *context); 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 *(*CreateContextFromStringWithHistory)(es2panda_Config *config, const char *source, + char const *file_name); + es2panda_Context *(*CreateCacheContextFromString)(es2panda_Config *config, const char *source, + char const *file_name, es2panda_GlobalContext *globalContext, + bool isExternal); + es2panda_Context *(*CreateContextGenerateAbcForExternalSourceFiles)(es2panda_Config *config, int fileNamesCount, + char const *const *fileNames); 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); @@ -183,34 +227,61 @@ 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); es2panda_SourceRange *(*CreateSourceRange)(es2panda_Context *context, es2panda_SourcePosition *start, es2panda_SourcePosition *end); + size_t (*SourcePositionCol)(es2panda_Context *context, es2panda_SourcePosition *position); size_t (*SourcePositionIndex)(es2panda_Context *context, es2panda_SourcePosition *position); 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_SourcePosition *position); + es2panda_SuggestionInfo *(*CreateSuggestionInfo)(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, const char *substitutionCode, + const char *title, es2panda_SourceRange *range); + void (*LogDiagnosticWithSuggestion)(es2panda_Context *context, const es2panda_DiagnosticInfo *diagnosticInfo, + const es2panda_SuggestionInfo *suggestionInfo); 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); + bool (*IsImportTypeKind)(es2panda_Context *ctx, es2panda_AstNode *node); + char *(*JsdocStringFromDeclaration)(es2panda_Context *ctx, es2panda_AstNode *node); + char *(*GetLicenseFromRootNode)(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); + const char *outputEts, bool exportAll, bool isolated, + const char *recordFile); 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 d036b8ec2e0410b9bc099d43a55f498d639897e1..4b8d6c0261180889855a8d57510e8067e0e0e22b 100644 --- a/ets2panda/public/es2panda_lib.idl.erb +++ b/ets2panda/public/es2panda_lib.idl.erb @@ -19,6 +19,7 @@ typedef (String or f64 or boolean) es2panda_variantDoubleCharArrayBool; [Entity=Class] interface es2panda_Config {}; [Entity=Class] interface es2panda_Context {}; +[Entity=Class] interface es2panda_GlobalContext {}; [Entity=Class] interface es2panda_Program {}; [Entity=Class] interface es2panda_ExternalSource {}; [Entity=Class] interface es2panda_ArkTsConfig {}; @@ -117,13 +118,34 @@ interface es2panda_OverloadInfo { 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; + attribute String title; + attribute es2panda_SourceRange range; +}; + +interface es2panda_DiagnosticInfo { + attribute es2panda_DiagnosticKind kind; + attribute sequence args; + attribute u32 argc; + attribute es2panda_SourcePosition pos; +}; + +dictionary es2panda_PluginDiagnosticType { + i32 ES2PANDA_PLUGIN_WARNING = 0; + i32 ES2PANDA_PLUGIN_ERROR = 1; + i32 ES2PANDA_PLUGIN_SUGGESTION = 2; }; [Entity=Class] interface VoidPtr {}; // void * @@ -150,12 +172,19 @@ typedef u64 Es2panda<%= name %>; interface es2panda_Impl { es2panda_Config CreateConfig(i32 argc, sequence argv); void DestroyConfig(es2panda_Config config); + String GetAllErrorMessages(es2panda_Context context); es2panda_Options ConfigGetOptions(es2panda_Config config); es2panda_Context CreateContextFromFile(es2panda_Config config, String source_file_name); + es2panda_Context CreateCacheContextFromFile(es2panda_Config config, String source_file_name, es2panda_GlobalContext globalContext, boolean isExternal); es2panda_Context CreateContextFromString(es2panda_Config config, String source, String file_name); + es2panda_Context CreateContextFromStringWithHistory(es2panda_Config config, String source, String file_name); + es2panda_Context CreateCacheContextFromString(es2panda_Config config, String source, String file_name, es2panda_GlobalContext globalContext, boolean isExternal); + es2panda_Context CreateContextGenerateAbcForExternalSourceFiles(es2panda_Config config, i32 fileNamesCount, sequence fileNames); es2panda_Context ProceedToState(es2panda_Context context, es2panda_ContextState state); // context is consumed void DestroyContext(es2panda_Context context); + es2panda_GlobalContext CreateGlobalContext(es2panda_Config config, sequence externalFileList, u32 fileNum, boolean LspUsage); + void DestroyGlobalContext(es2panda_GlobalContext globalContext); es2panda_ContextState ContextState(es2panda_Context context); String ContextErrorMessage(es2panda_Context context); @@ -175,21 +204,36 @@ 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_SourcePosition position); + es2panda_SuggestionInfo CreateSuggestionInfo(es2panda_Context context, es2panda_DiagnosticKind kind, + sequence args, u32 argc, String substitutionCode, + String message, es2panda_SourceRange range); + void LogDiagnosticWithSuggestion(es2panda_Context context, es2panda_DiagnosticInfo diagnosticInfo, + es2panda_SuggestionInfo suggestionInfo); 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); + 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); ir.AstNode DeclarationFromIdentifier(es2panda_Context ctx, ir.Identifier node); + boolean IsImportTypeKind(es2panda_Context ctx, ir.AstNode node); + String JsdocStringFromDeclaration(es2panda_Context ctx, ir.AstNode node); + String GetLicenseFromRootNode(es2panda_Context ctx, ir.AstNode 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); + void InvalidateFileCache(es2panda_GlobalContext globalContext, String fileName); + void RemoveFileCache(es2panda_GlobalContext globalContext, String fileName); + void AddFileCache(es2panda_GlobalContext globalContext, String fileName); % Es2pandaLibApi::ast_nodes&.each do |ast_node| % if ast_node != 'AstNode' && ast_node != 'TypeNode' @@ -221,7 +265,8 @@ interface es2panda_Impl { namespace ir { -[Entity=Class, c_type=es2panda_AstNode] interface NumberLiteral: Literal { +% 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); @@ -236,6 +281,8 @@ namespace ir { 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 diff --git a/ets2panda/public/es2panda_lib.rb b/ets2panda/public/es2panda_lib.rb index 6a9ba96525220a20065019a7593281d346da7db6..9e922c7ba26fa13fc2b5a837cd06192456d494fb 100644 --- a/ets2panda/public/es2panda_lib.rb +++ b/ets2panda/public/es2panda_lib.rb @@ -33,6 +33,8 @@ module Es2pandaLibApi @is_scope_type = false @is_code_gen = false @is_decl_type = false + @is_optional = false + @default_optional = false @const = '' @base_namespace = '' @@ -245,7 +247,13 @@ module Es2pandaLibApi [found_change_type_link, err_msg] end - def initialize(arg_info, base_namespace) + def set_default_expression_cast(found_change_type) + return unless found_change_type && @is_optional && @default_optional + found_change_type.cast['expression'] = found_change_type.cast['default_expression'] + found_change_type.new_args = found_change_type.default_new_args || [] + end + + def initialize(arg_info, base_namespace, default_optional = false) found_change_type_link, err_msg = Arg.get_change_type_info_with_err_msg(arg_info) raise err_msg unless err_msg.nil? @@ -254,6 +262,7 @@ module Es2pandaLibApi @const = Arg.const(arg_info) @es2panda_arg['const'] = @const @base_namespace = base_namespace + @default_optional = default_optional @is_ast_node = Arg.is_ast_node(es2panda_arg) @is_ast_node_add_children = Arg.is_ast_node_add_children(es2panda_arg) @@ -267,6 +276,8 @@ module Es2pandaLibApi if found_change_type_link found_change_type = Marshal.load(Marshal.dump(found_change_type_link)) + @is_optional = found_change_type.es2panda_arg.respond_to?('optional') && found_change_type.es2panda_arg['optional'] + set_default_expression_cast(found_change_type) placeholders = find_placeholders(found_change_type.es2panda_arg) @@ -402,12 +413,13 @@ module Es2pandaLibApi Arg.set_const_modifier(@lib_args, @const) Arg.set_const_modifier(@idl_args, @const) - tmp = Arg.new(@lib_args[0], @base_namespace) + tmp = Arg.new(@lib_args[0], @base_namespace, @default_optional) @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 + @is_optional = tmp.is_optional return if tmp.check_allowed_type(@lib_args[0]) nested_arg_transform @@ -508,6 +520,7 @@ module Es2pandaLibApi attr_reader :return_args attr_reader :idl_return_args attr_reader :const + attr_reader :is_optional def lib_args_to_str @lib_args.map do |lib_arg| @@ -806,31 +819,43 @@ module Es2pandaLibApi usings = usings_map constructor_overload = {} idl_constructor_overload = {} - dig(:constructors)&.each do |constructor| - if check_no_gen_constructor(constructor) - args = [] - begin - constructor_cast - constructor.args&.each do |arg| - arg['type'] = replace_with_usings(arg['type'], usings) - arg['type'] = add_base_namespace(arg['type']) - arg['type']['current_class'] = constructor.name - args << Arg.new(arg, class_base_namespace) + constructors = dig(:constructors) + constructors_with_optional = [] + [constructors, constructors_with_optional].each do |constructors_list| + is_with_optional_list = constructors_list == constructors_with_optional + constructors_list&.each do |constructor| + if check_no_gen_constructor(constructor) + begin + args = [] + constructor_cast + optional_args_info = [] + constructor.args&.each do |arg| + arg['type'] = replace_with_usings(arg['type'], usings) + arg['type'] = add_base_namespace(arg['type']) + arg['type']['current_class'] = constructor.name + processed_arg = Arg.new(arg, class_base_namespace, !is_with_optional_list) + if processed_arg.is_optional && !is_with_optional_list + optional_args_info << { name: arg['type']['name'] } + end + args << processed_arg + end + if !optional_args_info.empty? && !is_with_optional_list + constructors_with_optional << Marshal.load(Marshal.dump(constructor)) + end + rescue StandardError => e + error_catch_log('Constructor', constructor, e, 'Create' + class_name) + else + Es2pandaLibApi.stat_add_constructor(1, class_name, class_base_namespace, 'Create' + class_name) + Es2pandaLibApi.stat_add_class(1, class_name) + + 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 } end - rescue StandardError => e - error_catch_log('Constructor', constructor, e, 'Create' + class_name) else - Es2pandaLibApi.stat_add_constructor(1, class_name, class_base_namespace, 'Create' + class_name) - Es2pandaLibApi.stat_add_class(1, class_name) - - 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 } + Es2pandaLibApi.log('info', "Banned constructor for class '#{class_name}'\n") end - else - Es2pandaLibApi.log('info', "Banned constructor for class '#{class_name}'\n") end end res @@ -985,39 +1010,52 @@ module Es2pandaLibApi template_extends.each do |template_extend| methods += Es2pandaLibApi.classes['ir'][template_extend]['methods'] end - methods.each do |method| - if check_no_gen_method(method) - begin - return_type = Type.new(add_base_namespace(replace_with_usings(method.return_type, usings)), - class_base_namespace, 'return') - const = get_const_modifier(method) - const_return = get_const_return_modifier(return_type) - - args = [] - method.args.each do |arg| - arg['type'] = add_base_namespace(replace_with_usings(arg['type'], usings)) - args << Arg.new(arg, class_base_namespace) + methods_with_optional = [] + [methods, methods_with_optional].each do |methods_list| + is_with_optional_list = methods_list == methods_with_optional + methods_list&.each do |method| + if check_no_gen_method(method) + begin + return_type = Type.new(add_base_namespace(replace_with_usings(method.return_type, usings)), + class_base_namespace, 'return') + const = get_const_modifier(method) + const_return = get_const_return_modifier(return_type) + + args = [] + optional_args_info = [] + method.args.each_with_index do |arg, arg_index| + arg['type'] = add_base_namespace(replace_with_usings(arg['type'], usings)) + processed_arg = Arg.new(arg, class_base_namespace, !is_with_optional_list) + if processed_arg.is_optional && !is_with_optional_list + optional_args_info << { name: arg['type']['name'] } + end + args << processed_arg + end + + if !optional_args_info.empty? && !is_with_optional_list + methods_with_optional << Marshal.load(Marshal.dump(method)) + end + + return_expr = get_return_expr(return_type, call_cast, [const, const_return], method, args, 'method') + rescue StandardError => e + stat_function_overload = Marshal.load(Marshal.dump(function_overload)) + error_catch_log('Method', method, e, class_name + + get_new_method_name(stat_function_overload, method.name, const)) + else + stat_function_overload = Marshal.load(Marshal.dump(function_overload)) + Es2pandaLibApi.stat_add_method(1, class_name, class_base_namespace, class_name + + get_new_method_name(stat_function_overload, method.name, const)) + Es2pandaLibApi.log('info', 'supported method: ', method.name, ' class: ', class_name, "\n") + + res << { 'name' => method.name, 'const' => const, 'return_arg_to_str' => return_type.return_args_to_str, + 'overload_name' => get_new_method_name(function_overload, method.name, const), 'args' => args, + 'idl_name' => get_new_method_name(idl_function_overload, method.name, const, true), + 'return_type' => return_type, 'return_expr' => return_expr, 'raw_decl' => method.raw_declaration, + 'const_return' => const_return, 'get_modifier' => method['additional_attributes'] } end - - return_expr = get_return_expr(return_type, call_cast, [const, const_return], method, args, 'method') - rescue StandardError => e - stat_function_overload = Marshal.load(Marshal.dump(function_overload)) - error_catch_log('Method', method, e, class_name + - get_new_method_name(stat_function_overload, method.name, const)) else - stat_function_overload = Marshal.load(Marshal.dump(function_overload)) - Es2pandaLibApi.stat_add_method(1, class_name, class_base_namespace, class_name + - get_new_method_name(stat_function_overload, method.name, const)) - Es2pandaLibApi.log('info', 'supported method: ', method.name, ' class: ', class_name, "\n") - - res << { 'name' => method.name, 'const' => const, 'return_arg_to_str' => return_type.return_args_to_str, - 'overload_name' => get_new_method_name(function_overload, method.name, const), 'args' => args, - 'idl_name' => get_new_method_name(idl_function_overload, method.name, const, true), - 'return_type' => return_type, 'return_expr' => return_expr, 'raw_decl' => method.raw_declaration, - 'const_return' => const_return, 'get_modifier' => method['additional_attributes'] } + Es2pandaLibApi.log('info', "Banned method\n") end - else - Es2pandaLibApi.log('info', "Banned method\n") end end res @@ -1078,7 +1116,8 @@ module Es2pandaLibApi @info_log = false @debug_log = false - @warning_log = true + # 29204 + @warning_log = false @backtrace_log = false @stat_log = false @type_stat_log = false @@ -1242,9 +1281,7 @@ module Es2pandaLibApi def ast_type_additional_children %w[ ETSStringType - ETSDynamicType ETSAsyncFuncReturnType - ETSDynamicFunctionType ETSEnumType ETSBigIntType ] @@ -1380,6 +1417,7 @@ module Es2pandaLibApi es2panda_Options es2panda_Path es2panda_OverloadInfo + Es2pandaLanguage ] end @@ -1494,6 +1532,8 @@ 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) + next if class_definition.name == 'NumberLiteral' # it is defined manually + @classes['ir'][class_definition.name] = class_data end diff --git a/ets2panda/public/es2panda_lib_impl.inc.erb b/ets2panda/public/es2panda_lib_impl.inc.erb index e2ecc211727769deef7456b20c04ab0633f0e68c..6e6468b21c7f6313f1bfdcd3b5c859facf9d3fb1 100644 --- a/ets2panda/public/es2panda_lib_impl.inc.erb +++ b/ets2panda/public/es2panda_lib_impl.inc.erb @@ -259,6 +259,11 @@ extern "C" <%= classData.constructor_type().lib_type_to_str() auto oriOverloads = e2pOriginal->AsMethodDefinition()->Overloads(); newE2pNode->AsMethodDefinition()->SetOverloads(std::move(oriOverloads)); +% end +% if className == "AssignmentExpression" + if (e2pOriginal->AsAssignmentExpression()->IsIgnoreConstAssign()) { + newE2pNode->SetIgnoreConstAssign(); + } % end return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str() %>>(newE2pNode); diff --git a/ets2panda/public/headers_parser/supported_types.py b/ets2panda/public/headers_parser/supported_types.py index 6e6f805b628401ae73c6384adadf605c5974567d..c10aabea13b671c8486a2a4b73b77c1d577e9375 100644 --- a/ets2panda/public/headers_parser/supported_types.py +++ b/ets2panda/public/headers_parser/supported_types.py @@ -64,6 +64,7 @@ ast_nodes_supported = [ "MemberExpression", "MetaProperty", "MethodDefinition", + "OverloadDeclaration", "NamedType", "NewExpression", "NullLiteral", @@ -89,7 +90,6 @@ ast_nodes_supported = [ "ETSTypeReferencePart", "ETSUnionType", "ETSKeyofType", - "ETSLaunchExpression", "ETSNewArrayInstanceExpression", "ETSNewMultiDimArrayInstanceExpression", "ETSNewClassInstanceExpression", @@ -175,7 +175,6 @@ ast_nodes_supported = [ ] all_types_supported = [ - # Cpp types "char", "short", @@ -187,16 +186,13 @@ all_types_supported = [ "long double", "bool", "void", - # enums "AstNodeFlags", - "BoxingUnboxingFlags", "ModifierFlags", "ScriptFunctionFlags", "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 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 59992aa8d172cad56cbe6fec17899c8312a98394..3c86e801fe0102fdcc81a4a8947c30fbcd3481c4 100644 --- a/ets2panda/public/ignoredAllowed.yaml +++ b/ets2panda/public/ignoredAllowed.yaml @@ -96,7 +96,6 @@ ignored_list: - name: optional namespace: std - name: WrapperDesc - - name: Language - name: ScopedDebugInfoPlugin - name: Args namespace: parser diff --git a/ets2panda/public/public.cpp b/ets2panda/public/public.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c946299fed9258dbaf13770b1708ef1cd0db42a7 --- /dev/null +++ b/ets2panda/public/public.cpp @@ -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. + */ + +#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()]; +} + +void Context::MarkGenAbcForExternal(std::unordered_set &genAbcList, public_lib::ExternalSource &extSources) +{ + size_t genCount = 0; + std::unordered_set genAbcListAbsolute; + + for (auto &path : genAbcList) { + genAbcListAbsolute.insert(os::GetAbsolutePath(path)); + } + for (auto &[_, extPrograms] : extSources) { + (void)_; + bool setFlag = false; + for (auto *prog : extPrograms) { + if (auto it = genAbcListAbsolute.find(prog->AbsoluteName().Mutf8()); it != genAbcListAbsolute.end()) { + ++genCount; + setFlag = true; + } + } + if (!setFlag) { + continue; + } + for (auto *prog : extPrograms) { + prog->SetGenAbcForExternalSources(); + } + } + + if (genCount != genAbcListAbsolute.size()) { + diagnosticEngine->LogFatalError(diagnostic::SIMULTANEOUSLY_MARK_FAILED.Message()); + } +} + +} // namespace ark::es2panda::public_lib diff --git a/ets2panda/public/public.h b/ets2panda/public/public.h index ba457ce9928862ffe2c60721443ed1b2878c0020..72c7553a18454f2d47da38885160feb121da5090 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" @@ -23,7 +24,7 @@ #include "compiler/core/compileQueue.h" #include "parser/ETSparser.h" -#include "checker/checker.h" +#include "checker/ETSchecker.h" #include "compiler/core/emitter.h" namespace ark::es2panda::util { @@ -32,24 +33,184 @@ class Options; namespace ark::es2panda::compiler { 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); + } + + // NOTE(zhelyapov): It's calling side responsibility to release resources + void ClearCheckers() + { + checkers_.clear(); + } + + checker::SemanticAnalyzer *GetAnalyzer() const; + + void PushAnalyzer(checker::SemanticAnalyzer *analyzer) + { + return analyzers_.push_back(analyzer); + } + + // NOTE(zhelyapov): It's calling side responsibility to release resources + void ClearAnalyzers() + { + analyzers_.clear(); + } + + util::StringView GetDupProgramOriginalPath(util::StringView oldPath) + { + if (auto it = dupPrograms.find(oldPath); it != dupPrograms.end()) { + return it->second->AbsoluteName(); + } + return oldPath; + } + + void MarkGenAbcForExternal(std::unordered_set &genAbcList, public_lib::ExternalSource &extSources); + 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 contextLiterals; @@ -58,8 +219,6 @@ struct Context { 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; @@ -67,7 +226,21 @@ 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; + std::vector sourceFileNames; + std::map dupPrograms {}; + // 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 old mode 100644 new mode 100755 index c9aae37f601ccd9adeb84a44c87a5ed49ac5ecfb..fbb054131fd8ab3f8dc75b4f42118d588c4e9f9e --- a/ets2panda/scripts/arkui-setup.sh +++ b/ets2panda/scripts/arkui-setup.sh @@ -13,6 +13,7 @@ # limitations under the License. set -ex +set -o pipefail function about() { cat <<-ENDHELP @@ -23,13 +24,13 @@ function about() { --openlab-token Token to access to openlab (you can ask this information from Titova Tatiana) Please use this file to set up your .npmrc - https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/wikis/npmrc + BZ - https://gitee.com/rri_opensource/koala_projects/wikis/Environment%20Setup/%20npmrc%20(blue%20zone) + GZ - https://gitee.com/rri_opensource/koala_projects/wikis/Environment%20Setup/npmrc%20(yellow%20and%20green%20zone) Use these instructions to manually prepare ArkUI Hello app - https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/wikis/How%20to%20Build%20the%20Shopping%20Application%20(for%20host) - https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/wikis/How%20to%20Build%20the%20Shopping%20Application%20(for%20Board%20and%20Mobile%20Devices) + HOST - https://gitee.com/titovatatiana/arkcompiler_ets_frontend/wikis/Guide:%20How%20to%20Download%20and%20Build%20ArkUI%20Project + DEVICE - https://gitee.com/rri_opensource/koala_projects/wikis/Setup%20Guide/Trivial%20Build%20%2526%20Setup%20Guide Use these instructions to install custom compiler - https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/wikis/Setup%20custom%20SDK%20to%20run%20apps - https://gitee.com/openharmony-sig/arkcompiler_ets_frontend/wikis/How%20to%20build%20es2panda + https://gitee.com/titovatatiana/arkcompiler_ets_frontend/wikis/How%20to%20manage%20the%20integration%20process%20with%20ArkUI%20jobs ENDHELP } @@ -39,6 +40,10 @@ while [ -n "$1" ]; do about exit 0 ;; + --demo) + DEMO="${2}" + shift 2 + ;; --nexus-repo) NEXUS_REPO="${2}" shift 2 @@ -66,7 +71,7 @@ fi HUAWEI_MIRROR="${HUAWEI_MIRROR:-https://repo.huaweicloud.com/repository/npm/}" KOALA_REGISTRY="${KOALA_REGISTRY:-https://$NEXUS_REPO/repository/koala-npm/}" -NINJA_OPTIONS="-j ${NPROC_PER_JOB}" +export NINJA_OPTIONS="-j ${NPROC_PER_JOB}" retry() { local -r -i max_attempts="$1"; shift @@ -106,6 +111,7 @@ function do_checkout() { git checkout FETCH_HEAD || exit 1 [ -n "${patch}" ] && git apply "${patch}" } + git log -1 popd >/dev/null 2>&1 || exit 1 } @@ -124,6 +130,7 @@ npm config set package-lock false npm config set strict-ssl false npm config set registry "${HUAWEI_MIRROR}" npm config set @koalaui:registry "${KOALA_REGISTRY}" +npm config set @idlizer:registry "${KOALA_REGISTRY}" npm config set @panda:registry "https://$NEXUS_REPO/repository/koala-npm/" npm config set @ohos:registry "https://repo.harmonyos.com/npm/" if [ -z "${KOALA_REPO}" ] ; then @@ -133,15 +140,60 @@ fi npm install -d pushd incremental/tools/panda/ || exit 1 -if [ -z "${PANDA_SDK_TARBALL}" ] ; then -npm run panda:sdk:install +if [ -z "${PANDA_SDK_HOST_TARBALL}" ] ; then + npm run panda:sdk:install else -npm install "${PANDA_SDK_TARBALL}" + npm install "${PANDA_SDK_HOST_TARBALL}" + if [ -n "${PANDA_SDK_DEV_TARBALL}" ] ; then + npm install "${PANDA_SDK_DEV_TARBALL}" + else + echo "PANDA_SDK_DEV_TARBALL is not set, skipping!" + fi fi popd >/dev/null 2>&1 || exit 1 -pushd arkoala-arkts || exit 1 -npm install -d +function run_script() { + npm run $1 | tee out.txt + if [ -n "$(grep 'Error:' out.txt)" ] ; then + exit 1 + fi +} + +export ENABLE_BUILD_CACHE=0 + +# Compile libarkts +pushd ui2abc/libarkts || exit 1 +run_script "regenerate" +run_script "compile --prefix ../fast-arktsc" +run_script "run" popd >/dev/null 2>&1 || exit 1 -return 0 +# Compile memo-plugin, ui-plugins + +# need to fix ui2abc tests +# run_script "all --prefix ui2abc" +run_script "build:all --prefix ui2abc" + +run_script "build:deps --prefix ets-tests" + +if [ -z "${DEMO}" ] ; then + echo "Just compiled ArkUI, but no demo specified." + exit 1 +fi + +case "${DEMO}" in + "shopping") + run_script "run:node --prefix arkoala-arkts/shopping/user" + ;; + "trivial") + run_script "run --prefix arkoala-arkts/trivial/user" + ;; + "empty") + ;; + *) + echo "Unknown demo" "${DEMO}" + exit 1 + ;; +esac + +echo "ArkUI ${DEMO} demo completed successfully." diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index cbe2883b04ba43cd8c2e80358e254d70b1ced544..daa4c0a040e90c35e3ff557b687084f0ed12d049 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_7-1-type-error +ARKUI_DEV_BRANCH=panda_rev_10-remove-deprecated-ani-array-api ARKUI_DEST=koala-sig diff --git a/ets2panda/scripts/check_build_system_consistency.py b/ets2panda/scripts/check_build_system_consistency.py new file mode 100755 index 0000000000000000000000000000000000000000..ecae9d8327ee0636359f2efd43d25a32dbaa98ca --- /dev/null +++ b/ets2panda/scripts/check_build_system_consistency.py @@ -0,0 +1,198 @@ +#!/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 sys +import os +import re +import fnmatch + + +def parse_cmake_file_list(text, patterns): + file_list = [] + file_dict = {} + for match in re.finditer(r'([^\'"]*\.[a-zA-Z]+)', text): + filename = match.group(0) + filename = filename.split("\n") + + for file in filename: + if file.endswith(patterns): + file_list.append(file.strip().split("/")[-1]) + file_dict[file.strip().split("/")[-1]] = file.strip() + return file_list, file_dict + + +def parse_gn_file_list(text, patterns): + file_list = [] + file_dict = {} + for match in re.finditer(r'[\"]([^\'"]*\.[a-zA-Z]+)[\"]', text): + filename = match.group(1) + if any(fnmatch.fnmatch(filename, pat) for pat in patterns): + file_list.append(os.path.basename(filename)) + file_dict[os.path.basename(filename)] = filename + return file_list, file_dict + + +def classify_files(files, files_dict): + sources = [] + headers = [] + yamls = [] + sources_dict = {} + headers_dict = {} + yamls_dict = {} + + for file in files: + if file.endswith(".cpp"): + sources.append(file) + sources_dict[file] = files_dict.get(file) + elif file.endswith(".h"): + headers.append(file) + headers_dict[file] = files_dict.get(file) + elif file.endswith(".yaml"): + yamls.append(file) + yamls_dict[file] = files_dict.get(file) + + return sources, headers, yamls, sources_dict, headers_dict, yamls_dict + + +def parse_root_cmake(file_path): + with open(file_path, "r") as f: + content1 = f.read() + + sources = [] + sources_dict = {} + + for match in re.finditer(r"set\s*\(\s*\w+\s+(.*?)\s*\)", content1, re.DOTALL): + files, files_dict = parse_cmake_file_list(match.group(1), ".cpp") + sources.extend(files) + sources_dict.update(files_dict) + + return sources, sources_dict + + +def parse_public_cmake(file_path): + with open(file_path, "r") as f: + content = f.read() + headers, yamls = [], [] + headers_dict, yamls_dict = {}, {} + + for match in re.finditer(r"set\s*\(\s*\w+\s+(.*?)\s*\)", content, re.DOTALL): + files, files_dict = parse_cmake_file_list(match.group(1), (".h", ".yaml")) + _, h, y, _, hd, yd = classify_files(files, files_dict) + headers.extend(h) + yamls.extend(y) + headers_dict.update(hd) + yamls_dict.update(yd) + + return headers, yamls, headers_dict, yamls_dict + + +def parse_gn(file_path): + with open(file_path, "r") as f: + content = f.read() + + sources, headers, yamls = [], [], [] + sources_dict, headers_dict, yamls_dict = {}, {}, {} + + for match in re.finditer( + r"(libes2panda_sources|HEADERS_TO_BE_PARSED|" + r"ES2PANDA_API_GENERATED|ES2PANDA_API|" + r"generated_headers)\s*=\s*\[(.*?)\]", + content, + re.DOTALL, + ): + files, files_dict = parse_gn_file_list(match.group(2), ["*.cpp", "*.h", "*.yaml"]) + s, h, y, sd, hd, yd = classify_files(files, files_dict) + sources.extend(s) + headers.extend(h) + yamls.extend(y) + sources_dict.update(sd) + headers_dict.update(hd) + yamls_dict.update(yd) + + return sources, sources_dict, headers, headers_dict, yamls, yamls_dict + + +def compare_file_lists(cmake_files, cmake_files_dict, gn_files, gn_files_dict, file_type, location): + cmake_set = set(cmake_files) + gn_set = set(gn_files) + + only_in_cmake = cmake_set - gn_set + only_in_gn = gn_set - cmake_set + + if only_in_cmake: + only_in_cmake_path = [] + for file in only_in_cmake: + only_in_cmake_path.append(cmake_files_dict[file]) + print(f"{file_type} files only exist in CMake file:", sorted(only_in_cmake_path)) + if file_type == "source file(.cpp)": + print( + f"please add the missing {file_type} files to libes2panda_sources in ets2panda/BUILD.gn!" + ) + else: + print(f"please add the missing {file_type} files to {location} in ets2panda/BUILD.gn!") + if only_in_gn: + only_in_gn_path = [] + for file in only_in_gn: + only_in_gn_path.append(gn_files_dict[file]) + print(f"{file_type} files only exist in GN file:", sorted(only_in_gn_path)) + if file_type == "source file(.cpp)": + print(f"please add the missing {file_type} files to {location} in ets2panda/CMakeList.txt!") + else: + print( + f"please add the missing {file_type} files to {location} in ets2panda/public/CMakeList.txt!" + ) + + return len(only_in_cmake) == 0 and len(only_in_gn) == 0 + + +def main(): + work_dir = sys.argv[1] + cmake_src, cmake_src_dict = parse_root_cmake(os.path.join(work_dir, "CMakeLists.txt")) + ( + cmake_hdr, + cmake_yaml, + cmake_hdr_dict, + cmake_yaml_dict, + ) = parse_public_cmake(os.path.join(work_dir, "public/CMakeLists.txt")) + + gn_src, gn_src_dict, gn_hdr, gn_hdr_dict, gn_yaml, gn_yaml_dict = parse_gn( + os.path.join(work_dir, "BUILD.gn") + ) + + src_consistent = compare_file_lists( + cmake_src, cmake_src_dict, gn_src, gn_src_dict, "*.cpp", "ES2PANDA_LIB_SRC" + ) + hdr_consistent = compare_file_lists( + cmake_hdr, cmake_hdr_dict, gn_hdr, gn_hdr_dict, "*.h", "HEADERS_TO-BE-PARSED" + ) + yaml_consistent = compare_file_lists( + cmake_yaml, + cmake_yaml_dict, + gn_yaml, + gn_yaml_dict, + "*.yaml", + "ES2PANDA_API_GENERATED", + ) + + if src_consistent and hdr_consistent and yaml_consistent: + print("all file types are consistent beetween CMake and GN") + return 0 + print("Warning! inconsistent file found beetween CMake and GN") + return 1 + + +if __name__ == "__main__": + exit(main()) diff --git a/ets2panda/scripts/hello-build.sh b/ets2panda/scripts/hello-build.sh index 1c568e8cfcf2d6bd7087b1efd1d0bf976294eca9..6f7e31f9a593780c08571ea35c43547aaa7915fc 100755 --- a/ets2panda/scripts/hello-build.sh +++ b/ets2panda/scripts/hello-build.sh @@ -19,13 +19,6 @@ set -ex set -o pipefail SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -source "${SCRIPT_DIR}"/arkui-setup.sh - -pushd arkoala-arkts || exit 1 -NINJA_OPTIONS="${NINJA_OPTIONS}" npm run trivial:all:node:ci | tee out.txt -if [ -n "$(grep 'Error:' out.txt)" ] ; then - exit 1 -fi -popd >/dev/null 2>&1 || exit 1 +"${SCRIPT_DIR}"/arkui-setup.sh --demo trivial exit 0 diff --git a/ets2panda/scripts/normalize_yaml b/ets2panda/scripts/normalize_yaml new file mode 100755 index 0000000000000000000000000000000000000000..71ff8527fc0e64eb5bc8d695828dde8ccdb70748 --- /dev/null +++ b/ets2panda/scripts/normalize_yaml @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE(pronai) need idempotence test and negative tests for non-normal YAMLs + +import io +import os +import posixpath +import shutil +import subprocess +import sys +# YAML parser/dumper that preserves formatting +from ruamel import yaml +import numpy as np +import math + +usage = f"""\ +Usage: {sys.argv[0]} [--all] inputs + + inputs: a (possibly empty) list of paths to diagnostic YAMLs + --all: run on all YAMLs that look like they include diagnostics + -h | --help: print this help + """ + +permissible_collision_chance = 0.001 +simultaneous_commits = 10 +# how many new ids each commit adds, based on analysis of previous commits, this is ceil(avg) +# it must be a positive int +ids_per_commit = 2 +# we model commits with multiple ids as two commits +# this makes the math a lot easier and is a pessimistic approximation +effective_alloc_rate = simultaneous_commits * ids_per_commit + + +# see https://en.wikipedia.org/wiki/Birthday_problem +def collision_prob(n): + # the factorials are optimized away + return 1 - math.prod(range(n - effective_alloc_rate + 1, n+1)) / n ** effective_alloc_rate + +# binary search for a solution +def compute_range(): + min_range = effective_alloc_rate + upper_bound = min_range + lower_bound = min_range + step = 1 + while collision_prob(upper_bound) >= permissible_collision_chance: + lower_bound = upper_bound + upper_bound+=step + step*=2 + while lower_bound < upper_bound: + mid = (upper_bound+lower_bound)/2 + # n must be integer + mid_lo = math.floor(mid) + mid_hi = math.ceil(mid) + p_lo = collision_prob(mid_lo) + p_hi = collision_prob(mid_hi) + # higher n gives lower p! + if p_hi > permissible_collision_chance: + # p is too high, need higher n + lower_bound = mid_hi + else: # p_hi <= permissible_collision_chance + if permissible_collision_chance > p_lo: + upper_bound = mid_lo + else: # permissible_collision_chance <= p_lo + min_range = mid_hi + break + return min_range + +min_range = compute_range() + +# needed to make sure we are using the right numpy dtype +assert math.ceil(math.log2(min_range))<32 +dtype = np.uint32 + +def normalize(in_path): + out_path = in_path + ".new" + with open(in_path) as in_file, open(out_path, "w+") as out_file: + parser = yaml.YAML() + parser.preserve_quotes = True + parser.width = 120 + docs = parser.load(in_file) + doc = docs[next(iter(docs.keys()))] + doc.sort(key=lambda item: item['name']) + rng = np.random.default_rng() + if "graveyard" in docs: + docs["graveyard"].sort() + for diagnostic in doc: + if "id" in diagnostic and "graveyard" in docs: + continue + # we re-compute this every time because it's easier than splitting the ranges after each allocation + # it can be optimized later if necessary + # either way, we only add 1-2 IDs in each commit, so at most it doubles the run time + allocated = np.fromiter((int(diagnostic['id']) for diagnostic in doc if 'id' in diagnostic), dtype) + # add 0 as sentinel value, so we can deal with deletions + # 1 is the first actually available id, it's taken as of press time, but it might not remain that way + allocated = np.append(allocated, [0]) + allocated.sort() + if "graveyard" not in docs: + print(f"{in_path}: filling graveyard") + docs.insert(len(docs), "graveyard", sorted(list(set(range(1, allocated[-1]+1)).difference(set(allocated))))) + if 'id' in diagnostic: + continue + allocated = np.append(allocated, docs["graveyard"]) + allocated.sort() + gaps = allocated[1:]-allocated[:-1]-1 + gaps = np.append(gaps, [min_range-gaps.sum()]) + non_unique = gaps<0 + assert len(gaps) == len(allocated) + if np.any(non_unique): + raise ValueError(f"Non unique ids in yaml {in_path}:", allocated[non_unique]) + # choose from the available intervals using their size as weight + p = gaps + # need to normalize them so they sum to 1 + p = p / np.sum(p, dtype=float) + ival_id = rng.choice(len(allocated), p=p) + ival_start = 1+allocated[ival_id] + ival_size = gaps[ival_id] + # generate a random number from the interval + iid = ival_start+rng.choice(ival_size) + gaps[ival_id]-=1 + diagnostic.insert(1, 'id', int(iid)) + sio = io.StringIO() + parser.dump(docs, sio) + contents = sio.getvalue() + # make sure there is at least one blank line before each list item + prev="not blank" + for line in contents.splitlines(keepends=True): + # print("prev", prev) + # print("line", line) + if line.lstrip().startswith("- name:") and prev.strip()!="": + out_file.write("\n") + pass + out_file.write(line) + prev=line + usage_comment = "# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing.\n" + if prev.strip() != usage_comment.strip(): + out_file.write(usage_comment) + os.rename(out_path, in_path) + +def known_file_paths(): + repo_base = posixpath.dirname(shutil.which(sys.argv[0])) + "/../../" + for relative in subprocess.run(["git", "grep", "--files-with-matches", "-e" "^ message:", "--", "**.yaml"], cwd = repo_base, stdout=subprocess.PIPE).stdout.decode().splitlines(): + yield repo_base + relative + +def main(): + params = sys.argv[1:] + if "-h" in sys.argv or "--help" in params: + print(usage, file=sys.stderr) + sys.exit(1) + if "--all" in params: + params = [p for p in params if p != "--all"] + for path in known_file_paths(): + params.append(path) + for path in params: + print("Processing", path) + normalize(path) + +if __name__ == "__main__": + main() diff --git a/ets2panda/scripts/shopping-build.sh b/ets2panda/scripts/shopping-build.sh index a672523db27c78568e2109d34054b3a6add62c87..c539e1de7d3e7e18615bab83d032f6bf3d71df1d 100755 --- a/ets2panda/scripts/shopping-build.sh +++ b/ets2panda/scripts/shopping-build.sh @@ -19,13 +19,6 @@ set -ex set -o pipefail SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -source "${SCRIPT_DIR}"/arkui-setup.sh - -pushd arkoala-arkts || exit 1 -NINJA_OPTIONS="${NINJA_OPTIONS}" npm run shopping:all:node | tee out.txt -if [ -n "$(grep 'Error:' out.txt)" ] ; then - exit 1 -fi -popd >/dev/null 2>&1 || exit 1 +"${SCRIPT_DIR}"/arkui-setup.sh --demo shopping exit 0 diff --git a/ets2panda/test/CMakeLists.txt b/ets2panda/test/CMakeLists.txt index 646ffd28a7f27ffd3a5c2e8aa5c3b197f3d96e0a..4f93b770d714d363126516a9a4235bdde2a79ae8 100644 --- a/ets2panda/test/CMakeLists.txt +++ b/ets2panda/test/CMakeLists.txt @@ -29,6 +29,8 @@ if(PANDA_TARGET_ARM32 OR PANDA_ARM64_TESTS_WITH_SANITIZER) return() endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions") + add_custom_target(es2panda_tests COMMENT "Running es2panda test suites") add_custom_target(es2panda_gtests COMMENT "Running es2panda gtest suites") set(DEFAULT_TEST_GROUP ets_tests) @@ -58,6 +60,7 @@ function(ets2panda_add_gtest TARGET) ${ES2PANDA_ROOT}/test/utils/checker_test.cpp ${ES2PANDA_ROOT}/test/utils/scope_init_test.cpp ${ES2PANDA_ROOT}/test/utils/plugin_conversion_rule_test.cpp + ${ES2PANDA_ROOT}/test/utils/panda_executable_path_getter.cpp ${ARG_CPP_SOURCES} LIBRARIES es2panda-public @@ -86,4 +89,4 @@ endif() add_subdirectory(tsconfig) add_subdirectory(options) add_subdirectory(unit) -add_subdirectory(depanalyzer) \ No newline at end of file +add_subdirectory(depanalyzer) diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets b/ets2panda/test/ast/compiler/ets/AnnotationForTypeAliaDecl.ets similarity index 57% rename from ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets rename to ets2panda/test/ast/compiler/ets/AnnotationForTypeAliaDecl.ets index 5c5b4c8143ed66fc8c5458efc3352432f11a819f..52168f2026b0f3974bbdd610b99f22dcf2af51d0 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets +++ b/ets2panda/test/ast/compiler/ets/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,17 @@ function main(): void { @Anno({name : "2", id : 1}) @Anno2({name : "ab"}) - type t10 = FixedArray + type t10 = string[] } + + +/* @@? 47:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 47:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 50:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 50:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 53:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 53:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 56:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 56:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 60:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 60:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_1.ets b/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6bcecc08b108c82e890c26cca09adede03514cfd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_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. + */ + +const e = 123 +@interface Ajno { + b:e: string[][X (c + d)],% + +/* @@? 18:7 Error TypeError: Cannot find type 'e'. */ +/* @@? 18:17 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:29 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token 'end of stream'. */ + diff --git a/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_2.ets b/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..733c4a5ea39287c5feff86ad9570d5792ccd1d8f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/Const_Literal_As_TypeAnnotation_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. + */ + +const e = true +@interface Ajno { + b:e: string[][X (c + d)],% + +/* @@? 18:7 Error TypeError: Cannot find type 'e'. */ +/* @@? 18:17 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:29 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token 'end of stream'. */ + diff --git a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets index 00f05b825e33f297adf1eaa28bc47b04beefb2fa..7e3feec7a61195e2ddb1839dea824c9e1a2230ea 100644 --- a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets +++ b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets @@ -26,7 +26,7 @@ export declare const int_17 = 12345 export declare const int_18: number = 12345 declare const x1: int = 5 declare const x2: int = -5 -declare const y1: float = 5.55 +declare const y1: float = 5.55f declare const y2: double = -5.55 declare const x3: int = 0x5 declare const x4: int = 0b101 @@ -43,24 +43,24 @@ declare const x31 = 0x5 declare const x41 = 0b101 declare const x51 = "abc" -/* @@? 16:37 Error TypeError: Initializers are not allowed in ambient contexts: byte_1 */ -/* @@? 16:66 Error TypeError: Initializers are not allowed in ambient contexts: byte_2 */ -/* @@? 17:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_12 */ -/* @@? 17:64 Error TypeError: Initializers are not allowed in ambient contexts: byte_22 */ -/* @@? 18:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_13 */ -/* @@? 18:70 Error TypeError: Initializers are not allowed in ambient contexts: byte_23 */ -/* @@? 19:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_14 */ -/* @@? 20:30 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_1 */ -/* @@? 22:31 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_12 */ -/* @@? 24:36 Error TypeError: Initializers are not allowed in ambient contexts: int_16 */ -/* @@? 26:39 Error TypeError: Initializers are not allowed in ambient contexts: int_18 */ -/* @@? 27:25 Error TypeError: Initializers are not allowed in ambient contexts: x1 */ -/* @@? 28:25 Error TypeError: Initializers are not allowed in ambient contexts: x2 */ -/* @@? 29:27 Error TypeError: Initializers are not allowed in ambient contexts: y1 */ -/* @@? 30:28 Error TypeError: Initializers are not allowed in ambient contexts: y2 */ -/* @@? 31:25 Error TypeError: Initializers are not allowed in ambient contexts: x3 */ -/* @@? 32:25 Error TypeError: Initializers are not allowed in ambient contexts: x4 */ -/* @@? 33:28 Error TypeError: Initializers are not allowed in ambient contexts: x5 */ -/* @@? 34:27 Error TypeError: Initializers are not allowed in ambient contexts: x6 */ -/* @@? 35:20 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: x7 */ -/* @@? 36:20 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: x8 */ +/* @@? 16:37 Error TypeError: Initializers are not allowed in ambient contexts: byte_1 */ +/* @@? 16:66 Error TypeError: Initializers are not allowed in ambient contexts: byte_2 */ +/* @@? 17:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_12 */ +/* @@? 17:38 Error TypeError: Type 'Int' cannot be assigned to type 'Byte' */ +/* @@? 17:64 Error TypeError: Type 'Int' cannot be assigned to type 'Byte' */ +/* @@? 17:64 Error TypeError: Initializers are not allowed in ambient contexts: byte_22 */ +/* @@? 18:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_13 */ +/* @@? 18:70 Error TypeError: Initializers are not allowed in ambient contexts: byte_23 */ +/* @@? 19:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_14 */ +/* @@? 24:36 Error TypeError: Initializers are not allowed in ambient contexts: int_16 */ +/* @@? 26:39 Error TypeError: Initializers are not allowed in ambient contexts: int_18 */ +/* @@? 27:25 Error TypeError: Initializers are not allowed in ambient contexts: x1 */ +/* @@? 28:25 Error TypeError: Initializers are not allowed in ambient contexts: x2 */ +/* @@? 29:27 Error TypeError: Initializers are not allowed in ambient contexts: y1 */ +/* @@? 30:28 Error TypeError: Initializers are not allowed in ambient contexts: y2 */ +/* @@? 31:25 Error TypeError: Initializers are not allowed in ambient contexts: x3 */ +/* @@? 32:25 Error TypeError: Initializers are not allowed in ambient contexts: x4 */ +/* @@? 33:28 Error TypeError: Initializers are not allowed in ambient contexts: x5 */ +/* @@? 34:27 Error TypeError: Initializers are not allowed in ambient contexts: x6 */ +/* @@? 35:20 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: x7 */ +/* @@? 36:20 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: x8 */ diff --git a/ets2panda/test/ast/compiler/ets/DeclareIndexerTest.ets b/ets2panda/test/ast/compiler/ets/DeclareIndexerTest.ets index 7cf36bcc8b7057d45402c54cb177cf50fe9a53d4..4bc211702aec007aadc16ba78c9c77aae9a249f8 100644 --- a/ets2panda/test/ast/compiler/ets/DeclareIndexerTest.ets +++ b/ets2panda/test/ast/compiler/ets/DeclareIndexerTest.ets @@ -17,6 +17,13 @@ declare class A { [index: number]: string // indexer declaration } +declare class B { + [index: int] : number +} + +declare interface C { + [index :int]: string + } function main () { 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 3de018767341ea54bfa6a78c5aff26f2e82fc7bd..abbbc6bccaff53f3ff6c63ad434b903258ec6965 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 @@ -24,10 +24,10 @@ enum Size{S, M, L, XL, XXL} testProperty5: FixedArray = [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 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' */ +/* @@? 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 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 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 dc97fe475cf0e40b547aaae9d3aadfb2f4f030b9..5199df48ef335f06341128c52126aaa31ce326fe 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 @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 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 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' */ +/* @@? 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 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 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/iterabletypes_with_protected_iterator_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/iterabletypes_with_protected_iterator_neg.ets index b38952b6572cc4b57d81e1b5b96e0d7aa5b9e5b4..fdf880e427517b300b99be0997400cf5410a3d3c 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/iterabletypes_with_protected_iterator_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/iterabletypes_with_protected_iterator_neg.ets @@ -38,7 +38,7 @@ class A { function main(): int { let a = new A; for(let it of a) { - assertEQ(it, a.data[idx]); + arktest.assertEQ(it, a.data[idx]); ++idx; } return 0; 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..f7e4961dcdb9b8ea852ca4950f38203106724f4b 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..05c91630b4f9070b50bc20129ec3aa6acbf5fc47 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 @@ -17,7 +17,7 @@ class C { public met(...p: FixedArray): string { return "nR" } - public met(...p: FixedArray): string { + public met(...p: FixedArray): string { return "NR" } } @@ -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..80478738c55f20bfcaeaaaacef2a466c5dc59c40 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 @@ -25,6 +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/FixedArray/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets index 2af023757fc898a051425c220ea4a619a89fef5e..9c64efd7b21a138359a11964330e7278b2852fde 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:FixedArray):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets index 555c100c078481c32e38300fd99a6310d4c8b66a..de366a4ce9c8977af5dafbc712422a52ccb5c62b 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets @@ -22,8 +22,8 @@ function main() { } /* @@? 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. */ +/* @@? 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: 'double[]' cannot be spread in tuple. */ -/* @@? 21:105 Error TypeError: 'String[]' cannot be spread in tuple. */ +/* @@? 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/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 de7338a66b303278d853c1e38403b62b69b99fb7..baddef4e13b7be0894b3837afa1b74bfe705e61c 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,12 +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 TypeError: Class name 'Int' used in the wrong context */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:43 Error SyntaxError: Unexpected token 'Int'. */ +/* @@? 18:43 Error SyntaxError: Class cannot be used as object. */ +/* @@? 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:49 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets index 616aaac57f0cc84b2026365cd45c3ef6d585592c..93fac978914f250b1021c0d0dbd1dfcc7e6efb10 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets @@ -41,18 +41,17 @@ function getUnion(): A | B { function main() { const u = getUnion() - assertEQ(/* @@ label1 */u.fld1, 42) - assertEQ(/* @@ label2 */u.fld2, 42.0) - assertEQ(/* @@ label3 */u.fld3[0], "abc") - assertEQ(/* @@ label4 */u.fld4[0], "def") - assertEQ(/* @@ label5 */u.fld5, 42.0) - assertEQ(/* @@ label6 */u.fld6, 42.0) - assertEQ(/* @@ label7 */u.fld7, 42.0) - assertEQ(/* @@ label8 */u.fld8, new Map()) + arktest.assertEQ(/* @@ label1 */u.fld1, 42) + arktest.assertEQ(u.fld2, 42.0) + arktest.assertEQ(/* @@ label3 */u.fld3[0], "abc") + arktest.assertEQ(/* @@ label4 */u.fld4[0], "def") + arktest.assertEQ(/* @@ label5 */u.fld5, 42.0) + arktest.assertEQ(/* @@ label6 */u.fld6, 42.0) + arktest.assertEQ(/* @@ label7 */u.fld7, 42.0) + arktest.assertEQ(/* @@ label8 */u.fld8, new Map()) } /* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label2 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label3 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label4 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label5 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee093b8b105916362453ed31d7f5934951e419bd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_neg.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A {} +class B extends A {} +class C {} + +let ac: FixedArray | FixedArray = [new A(), new B()] +let b: FixedArray = [new B(), new B()] + +let cOnly: FixedArray = b + +/* @@? 23:28 Error TypeError: Type 'FixedArray' cannot be assigned to type 'FixedArray' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_1.ets b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..d754b99b1e4d57023add7b093906eb043b842256 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_1.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 {} +class B extends A {} +class C {} + +let ac: FixedArray | FixedArray = [new A(), new B()] +let b: FixedArray = [new B(), new B()] + +function assertFixedArrayOfA(u: FixedArray | FixedArray) { + if (u instanceof FixedArray) { + arktest.assertTrue(u.length === 2) + for (let i = 0; i < u.length; i++) { + arktest.assertTrue(u[i] instanceof A) + } + return + } + arktest.assertTrue(false) +} + +function main() { + ac = b + assertFixedArrayOfA(ac) +} diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_2.ets b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..9a6cc4f3afc8e88502ab2650a55ff36993999bba --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/union_subtyping_pos_2.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. + */ + + +function f(arg: FixedArray | Array) { + if (arg instanceof FixedArray) { + arktest.assertTrue(arg.length === 2) + let sum = 0 + for (let i = 0; i < arg.length; i++) { + sum += arg[i] + } + arktest.assertTrue(sum === 3) + return + } + + arktest.assertTrue(arg.length === 2) + let cat = "" + for (let i = 0; i < arg.length; i++) { + cat = cat + arg[i] + } + arktest.assertTrue(cat === "3344") +} + +function main() { + f([1, 2]) + f(["33", "44"]) +} diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/unresolved_reference.ets b/ets2panda/test/ast/compiler/ets/FixedArray/unresolved_reference.ets index 3213a83ac10b83029e0ce7f1d4bfad9d552fa97a..eef306e686bcfd4523e7ecaae7ba1d023ba732c3 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/unresolved_reference.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/unresolved_reference.ets @@ -37,5 +37,5 @@ function main() { let a = (new A).b } -/* @@? 28:13 Error TypeError: Unresolved reference b */ +/* @@? 16:13 Error TypeError: Unresolved reference b */ /* @@? 37:21 Error TypeError: Property 'b' does not exist on type 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType10.ets b/ets2panda/test/ast/compiler/ets/FunctionType10.ets index 2c1abfa1d121e6b26ba5b553c24bcb4b614b90cc..fc1a41058c3a1591eeb1191af23770bbf55deb22 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType10.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType10.ets @@ -21,4 +21,4 @@ function main() { let goo : int = /* @@ label */foo } -/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType3.ets b/ets2panda/test/ast/compiler/ets/FunctionType3.ets index b4524e83ece4d36ed4c4de4d8527dcca58131ff3..0e68f79c692c8675402c8406b4d827ad2a7c600e 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType3.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType3.ets @@ -24,4 +24,4 @@ function main(): void { } /* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ 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/ast/compiler/ets/FunctionType9.ets b/ets2panda/test/ast/compiler/ets/FunctionType9.ets index d3da4e621a5f74b05c5b51622ef748656aa7af78..acca71fd797608676d07375928d73a2327c82174 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType9.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType9.ets @@ -19,7 +19,10 @@ class A { } - private cb: (a: int) => void = this.foo; + private cb: (a: int) => void; + constructor () { + this.cb = this.foo; + } } function main(): void { diff --git a/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets index e4aa2cd0ce15b3402c5df5e68586c4894df26094..3f64bda07d045c37056f9502464d36fbdcbcb0aa 100644 --- a/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets +++ b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets @@ -16,8 +16,6 @@ let f = ()=>int {} f() -/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ /* @@? 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/Invalid_rest_element_wtih_tuple_type.ets b/ets2panda/test/ast/compiler/ets/Invalid_rest_element_wtih_tuple_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..2df27d5f56a862325f9c2a6c08f4187c54b23292 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/Invalid_rest_element_wtih_tuple_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. + */ + +class TH { + static restMethod(...v: [number, B, C]) { + } +} + +function main() { + let mc = new TH +} + +/* @@? 17:38 Error TypeError: Cannot make a static reference to the non-static type B */ +/* @@? 17:41 Error TypeError: Cannot make a static reference to the non-static type C */ diff --git a/ets2panda/test/ast/compiler/ets/IsValidRestArgument.ets b/ets2panda/test/ast/compiler/ets/IsValidRestArgument.ets new file mode 100755 index 0000000000000000000000000000000000000000..f5bc78e6d615240a3622f2d826156ced55b26ee5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/IsValidRestArgument.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 {} + +class C { + foo(...p: [A, B]) {} +} + +(new C()).foo({v.r2} +) + +/* @@? 23:1 Error TypeError: Expected 2 arguments, got 1. */ +/* @@? 23:1 Error TypeError: No matching call signature for foo(...) */ +/* @@? 23:15 Error TypeError: need to specify target type for class composite */ +/* @@? 23:17 Error SyntaxError: Unexpected token, expected ':'. */ diff --git a/ets2panda/test/ast/compiler/ets/LambdaParameterWithImplicitType.ets b/ets2panda/test/ast/compiler/ets/LambdaParameterWithImplicitType.ets new file mode 100644 index 0000000000000000000000000000000000000000..2cde0dd68986def9af9d335f874e106fcd582d0b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/LambdaParameterWithImplicitType.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. + */ + +const foo = async (): Promise => { + return 42.0; // Return a double to satisfy the Promise +}; + +foo().then((result) => { // crash - issue #26815 + console.log(`Async function returned: ${result}`); +}); + +let fooArray = ["a", "b", "c"]; +let fooArrayMapped = fooArray.map(x => x + " is mapped"); // crash - issue #26856 +let fooArrayMappedAndChecked = fooArray.map(x => x == "a"); // crash - issue #26856 diff --git a/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_1.ets b/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_1.ets index b26b68025313ade9dc58efe270fae3c5bb300d96..0cae5d18a7c057823b44ef1ea811dea80572ef69 100644 --- a/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_1.ets @@ -37,4 +37,4 @@ const router:RouterT = { -/* @@? 32:5 Error TypeError: Method 'back' cannot be used as a key of object literal. */ +/* @@? 32:5 Error TypeError: Class or interface methods cannot be initialized within an object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_2.ets b/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_2.ets index 94b38ec334b264e87ffd6110a3ef21cf0744022d..73db0e88aac5800417321f72e873488a0cc4d7e9 100644 --- a/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/ObjectLiteral_neg_2.ets @@ -20,4 +20,4 @@ class A { let a:A = {back:()=>{}} -/* @@? 20:12 Error TypeError: Method 'back' cannot be used as a key of object literal. */ +/* @@? 20:12 Error TypeError: Class or interface methods cannot be initialized within an object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/ParserImpl_ParserForInOf_nullptr.ets b/ets2panda/test/ast/compiler/ets/ParserImpl_ParserForInOf_nullptr.ets new file mode 100755 index 0000000000000000000000000000000000000000..26506215d980ea86deaaa9c63956a4cd8b396564 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ParserImpl_ParserForInOf_nullptr.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. + */ + +{% for + const enum Direction { + __empty = 1, + } + +/* @@? 16:2 Error SyntaxError: Unexpected token '%'. */ +/* @@? 16:4 Error SyntaxError: Unexpected token 'for'. */ +/* @@? 17:3 Error SyntaxError: Expected '(', got 'const'. */ +/* @@? 31:70 Error SyntaxError: Invalid left-hand side in 'for' statement: must have a single binding. */ +/* @@? 31:70 Error SyntaxError: Expected ';', got 'end of stream'. */ +/* @@? 31:70 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 31:70 Error SyntaxError: Unexpected token, expected ';'. */ +/* @@? 31:70 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 31:70 Error SyntaxError: Expected ')', got 'end of stream'. */ +/* @@? 31:70 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 31:70 Error SyntaxError: Expected '}', got 'end of stream'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/Partial_utility_type_0.ets b/ets2panda/test/ast/compiler/ets/Partial_utility_type_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..b72c198c605052e4f6589d7b3d89bd93663db680 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/Partial_utility_type_0.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 {} + +function foo() { + let x1: Partial = {} + let x2: Partial = {} + let x3: Partial = {} + let x4: Partial = {} + let x5: Partial = {} +} + + +/* @@? 20:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 21:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 22:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 23:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 24:20 Error TypeError: T in Partial must be a class or an interface type. */ diff --git a/ets2panda/test/ast/compiler/ets/PromiseAllSettledRejectIgnored.ets b/ets2panda/test/ast/compiler/ets/PromiseAllSettledRejectIgnored.ets new file mode 100644 index 0000000000000000000000000000000000000000..db53e7267ea62d5e3296ec20f8e7dbf290d25537 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/PromiseAllSettledRejectIgnored.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 Fulfill implements PromiseLike { + then(onFulfill?: (value: string) => U | PromiseLike, _?: + (error: Error) => E | PromiseLike): PromiseLike> { + return Promise.resolve(onFulfill!('abc')); + } +} + +class Reject implements PromiseLike { + then(onFulfilled?: (value: string) => U | PromiseLike, onRejected?: + (error: Error) => E | PromiseLike): PromiseLike> { + onFulfilled!('def'); + return Promise.reject(onRejected!(new Error('xyz')) as Error); + } +} + +let thenable: PromiseLike[] = [new Fulfill(), new Reject()]; +Promise.allSettled(thenable).then((values: PromiseSettledResult[]): void => { + if (values.length != 2) { + console.log('Test failed. Expected a string array of length 2 but got length ' + values.length + '.'); + return; + } + if (values[0].status != PromiseStatus.fulfilled || values[1].status != PromiseStatus.fulfilled) { + console.log('Test failed. Expected all elements has status \'fulfilled\'.'); + return; + } + let v: string = (values[0] as PromiseFulfilledResult).value; + if (v != 'abc') { + console.log('Test failed. Expected the first elements has value \'abc\' but got ' + v + '.'); + return; + } + v = (values[1] as PromiseFulfilledResult).value; + if (v != 'def') { + console.log('Test failed. Expected the first elements has value \'abc\' but got ' + v + '.'); + return; + } + console.log('Test passed.'); +}, (error: Error): void => { + console.log('Test failed. The promise should not be rejected.'); +}).catch((e: Error): void => { + console.log('Test failed: ' + e); +}); + +/* @@? 19:16 Error TypeError: Type 'Promise' is not compatible with the enclosing method's return type 'PromiseLike|Awaited>' */ +/* @@? 27:16 Error TypeError: Type 'Promise' is not compatible with the enclosing method's return type 'PromiseLike|Awaited>' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/Required_utility_type_0.ets b/ets2panda/test/ast/compiler/ets/Required_utility_type_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..00fd2a2a6e27e1da5b191c8875782731d22a791c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/Required_utility_type_0.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 A {} +class B {} + +function foo() { + let x1: Partial = {} + let x2: Partial = {} + let x3: Partial = {} + let x4: Partial = {} + let x5: Partial = {} +} + + + +/* @@? 20:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 21:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 22:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 23:20 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 24:20 Error TypeError: T in Partial must be a class or an interface type. */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets index f3352a60e9bd190b64671a2bc36c34e2c8a40f4e..367544573fd5d6029d211b7044a177e3ef6c5fab 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets @@ -16,4 +16,4 @@ class A>{} class B{} class C extends A/* @@ label */{} -/* @@@ label Error TypeError: Type B is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets index 9b39a2bf97fa56b04a110ef37a068abcf8d5f42e..da65d44cd5fef34d89df69ae4dfae461eb0e77c9 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets @@ -17,4 +17,4 @@ class A>{} class P2{} class P1 extends A/* @@ label */{} -/* @@@ label Error TypeError: Type P2 is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'P2' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_function.ets b/ets2panda/test/ast/compiler/ets/ambient_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f20bea7e3be6d1b0e1abfbbdf848db4ecef2343 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_function.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 a1: [number] | null = null; +let a2: [number] = [0x00000001]; + +declare function capset(...p: [number]): void; + +function capset(...p: [number]) {} + +function main() { + capset(...(a1 ?? a2)); +} + +/* @@? 21:1 Error TypeError: Method declaration `capset` must all ambient or non-ambient */ +/* @@? 24:3 Error TypeError: This expression is not callable. */ 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_indexer_multiple_dummy_nodes.ets b/ets2panda/test/ast/compiler/ets/ambient_indexer_multiple_dummy_nodes.ets new file mode 100644 index 0000000000000000000000000000000000000000..139fe4e7de49136400150be3bf3027041e294ed2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_indexer_multiple_dummy_nodes.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. + */ + +//// [a.tsx] +declare const React: object; + +declare namespace JSX { + interface IntrinsicElements { + [k: number]: object | undefined; + [k: number]: object | undefined; + } +} + +/* @@? 20:30 Error TypeError: Only one index signature is allowed in a class or interface. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword01.ets b/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword01.ets new file mode 100644 index 0000000000000000000000000000000000000000..f15e011c885d34272c31c8bfc22205624347c78a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword01.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. + */ + +declare interface XXX { + default goo(): void + default goo(a: number): void + default goo(a: number, b: string): void +} + +interface YYY { + goo(): void + bar(): void {} +} + +class AAA implements XXX { + +} + +let aaa = new AAA(); + +aaa.goo(); diff --git a/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword02.ets b/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword02.ets new file mode 100644 index 0000000000000000000000000000000000000000..a644ed266b136953fb5ea75e0977aafe8a39f8f2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_interface_default_keyword02.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. + */ + +declare interface XXX { + default bar(a: number): number { + return a; + } + foo(a: number): void {} +} + +interface YYY { + default foo(): void + default baz(): void {} +} + +/* @@? 17:36 Error TypeError: Native, Abstract and Declare methods cannot have body. */ +/* @@? 20:26 Error TypeError: Native, Abstract and Declare methods cannot have body. */ +/* @@? 24:7 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 24:18 Error SyntaxError: Private interface methods must have body. */ +/* @@? 25:7 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_namesapce04.ets b/ets2panda/test/ast/compiler/ets/ambient_namesapce04.ets index 2f94e6b211099caf8f854c0e11ad69626db12558..22b20fdb661e543f2e6a4d3b3d7eb7921f2704b1 100644 --- a/ets2panda/test/ast/compiler/ets/ambient_namesapce04.ets +++ b/ets2panda/test/ast/compiler/ets/ambient_namesapce04.ets @@ -21,4 +21,4 @@ declare namespace MySpace{ } /* @@? 18:20 Error TypeError: Native, Abstract and Declare methods cannot have body. */ -/* @@? 19:12 Error TypeError: Native and Declare methods should have explicit return type. */ \ No newline at end of file +/* @@? 19:9 Error TypeError: Native and Declare methods should have explicit return type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/anno_required_fields.ets b/ets2panda/test/ast/compiler/ets/anno_required_fields.ets new file mode 100644 index 0000000000000000000000000000000000000000..3791299398ac689ef2f36c845c9db3fd5315a60a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/anno_required_fields.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 AnnoSrc.ClassAuthor { + mutilArray:number[][] = [ + [...(()=>{})] + ] +} + +@ClassAuthor +function main() {} + +/* @@? 16:12 Error TypeError: Cannot find type 'AnnoSrc'. */ +/* @@? 16:20 Error TypeError: 'ClassAuthor' type does not exist. */ +/* @@? 17:29 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets b/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.ets new file mode 100644 index 0000000000000000000000000000000000000000..c077a76fd0de0cd1798da4d69b10e1ffa6f67022 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_decl_dot_empty.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. + */ + +@interface Message. +{ +} + +/* @@? 16:12 Error SyntaxError: Invalid annotation name. */ +/* @@? 17:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets b/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.ets new file mode 100644 index 0000000000000000000000000000000000000000..195205770f44ca73bc0d7620e1f006014838e9d9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_dot_with_empty.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 MyTest { + @Consume. + private property1; +} + +/* @@? 17:6 Error SyntaxError: Invalid annotation name. */ +/* @@? 18:5 Error SyntaxError: Identifier expected. */ +/* @@? 18:22 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_for_class.ets b/ets2panda/test/ast/compiler/ets/annotation_for_class.ets new file mode 100755 index 0000000000000000000000000000000000000000..89298795b21ffd842cb9a613c46e74a5324c43b4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_for_class.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. + */ + +// Step 1: Define an enum with a numeric constant +enum MyEnum { + EnumField = 42 +} + +// Step 2: Define an annotation with a field initialized using the enum value +@interface ClassAnnotation { + field: number = MyEnum.EnumField; +} + +// Step 3: Apply the annotation to a class +@ClassAnnotation +class MyClass { +} 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..c3ec1fa0a18f3dc1d24d5cc9dc8f0d3b8556dbd8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/Retension_invalid_params.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. + */ + +@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 */ +/* @@? 16:12 Error TypeError: Invalid value for annotation field, expected a constant literal. */ 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 97418d3a03a6d4fb4b1671fe297b3a3b78419abc..c335fe0f2846c1ea791650c37ac10398b1a8de88 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 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' */ +/* @@? 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: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 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' */ +/* @@? 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..679bc167bba7eab61aa615a498bfb4e53ad0b137 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 @@ -19,6 +19,4 @@ 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 +/* @@? 19:22 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_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_param07.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets index b18eb027e59f66305ce32e828c742187dcb39834..4904fabba8dc0563e96c421d11cf98646aecb271 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty1: /* @@ label */1, testProperty2: /* @@ label1 */""}) function foo(){} -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'double' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'Double' */ 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 ef17b83b2b280d6c7e7f8f6867e5f9192561edfe..09bee29a1d203e45cb26694b97b25261d2408a33 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} @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 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 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' */ +/* @@? 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 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 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_type_alias.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.ets index 304ebbb8d48adec515b630a353deb175ba5b188a..318d48b7e876925cdeeb4d81968474c91f0036a2 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.ets @@ -29,5 +29,6 @@ function main() : void { type t2 = Array } -/* @@? 28:6 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. */ +/* @@? 29:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 29:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ 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..7dcd2ce4b267fd5e268e10ea7a88f77503795c0a 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 @@ -21,5 +21,4 @@ let a = new A(); 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. */ +/* @@? 21:34 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_type_alias.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.ets index d2d80f9dadedec7a129af132729342ad5ba33474..b8246ab8f008ab81bbcd1abfc1e3f8f5f6184deb 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.ets @@ -27,5 +27,6 @@ function main() : void { type t2 = Array } -/* @@? 26:6 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. */ +/* @@? 27:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 27:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ 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_AT_for_type_alias.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.ets index 446356df276bf4eb91ef9a9bafe61858ed14a320..c982341bff8d803ae9a8aff184fecbd7418c7087 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.ets @@ -29,3 +29,4 @@ function main() : void { /* @@? 19:1 Error TypeError: This expression is not callable. */ /* @@? 23:5 Error TypeError: Annotation missing '@' symbol before annotation name. */ /* @@? 23:5 Error TypeError: This expression is not callable. */ +/* @@? 24:5 Error SyntaxError: Illegal start of Type Alias expression. */ 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_type_alias.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.ets index 8f2c3cdf9fb0629b2b9fa28cb3aee77d2d7d5f95..0889f68c3eaa1a4fe448bf9a706a1643d78eb5d8 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.ets @@ -27,5 +27,6 @@ function main() : void { type t2 = Array } -/* @@? 26:6 Error TypeError: The required field 'testProperty2' 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. */ +/* @@? 27:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 27:5 Error SyntaxError: Annotations are not allowed on this type of declaration. */ 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/annotationUsage_unordered_params.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets index 065c6baad198e7dc00525cb95c58e981f090216d..a61fa5db89ba7c8fdc995bfa8a46a71a38382d95 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty2: /* @@ label */"Bob", testProperty1: /* @@ label1 */1}) class A{} -/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'double' */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'Double' */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_and_class_with_same_name.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_and_class_with_same_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..28d6784792ee058afcb2e5e01cb887efc981acf4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_and_class_with_same_name.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 {} + +@interface A { } + +/* @@? 18:12 Error TypeError: Variable 'A' has already been declared. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets index e358f9440ee1426b4e3206cb8d8c2dae1e415b36..3de515f15a42261ebafdcfc39ea78be12b5a0e54 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets @@ -20,6 +20,6 @@ class A {} } -/* @@? 18:18 Error TypeError: Cannot cast type 'int' to 'String' */ -/* @@? 19:15 Error TypeError: Cannot cast type 'int' to 'A' */ -/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 18:18 Error TypeError: Cannot cast type 'Int' to 'String' */ +/* @@? 19:15 Error TypeError: Cannot cast type 'Int' to 'A' */ +/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'Int' */ \ No newline at end of file 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..a6857d8207acf7996053fcbcdc131577e4000459 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 +/* @@? 22:23 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/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_bad_target.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_bad_target.ets new file mode 100644 index 0000000000000000000000000000000000000000..e3deff1d62d3ad1055db607884d901f6d128a532 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_bad_target.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 +this.context; + +/* @@? 17:1 Error SyntaxError: Identifier expected. */ +/* @@? 17:1 Error SyntaxError: Invalid annotation name. */ +/* @@? 17:1 Error SyntaxError: Expected '{', got 'this'. */ +/* @@? 17:5 Error SyntaxError: Identifier expected, got '.'. */ +/* @@? 17:13 Error SyntaxError: Missing type annotation for property 'context'. */ 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..86cf1c35907347104d3aa79dbcd03f23c507edde 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets @@ -12,28 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@interface Anno{} +@Retention("SOURCE") +@interface Anno{ } -let array1: Array<@Anno() Int> = new Array<@Anno() Int>() +let array1: Array<@Anno() Int > = new Array < @Anno() Int > () -class A{ - foo(){} - bar(){ - foo<@Anno T>() - this.foo<@Anno T>() - } +class A { + foo() { } + bar() { + foo < @Anno number > () + this.foo < @Anno number > () + } } -function foo(){} -foo<@Anno T>() +function foo() { } +foo < @Anno string > () -/* @@? 17:27 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 17:52 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 22:17 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 22:17 Error 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'. */ -/* @@? 22:17 Error TypeError: Cannot find type 'T'. */ -/* @@? 23:22 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/ast/compiler/ets/annotation_tests/broken_annotation.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/broken_annotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..c0c0a3d0d64d82a0e32aa57b8de1cdd39a3b2a6c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/broken_annotation.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 MyValue {[1,2,3]} + +class A{ + @MyValue([1,2,3]) + foo(){} +} + +/* @@? 16:22 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:22 Error SyntaxError: Number, string or computed value property name '1' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:22 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:22 Error SyntaxError: Number, string or computed value property name '1' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:22 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 16:23 Error SyntaxError: Identifier expected, got ','. */ +/* @@? 16:24 Error SyntaxError: Number, string or computed value property name '2' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:24 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:24 Error SyntaxError: Number, string or computed value property name '2' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:24 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:25 Error SyntaxError: Identifier expected, got ','. */ +/* @@? 16:26 Error SyntaxError: Number, string or computed value property name '3' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:26 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:26 Error SyntaxError: Number, string or computed value property name '3' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:26 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:27 Error SyntaxError: Identifier expected, got ']'. */ +/* @@? 16:28 Error SyntaxError: Identifier expected, got '}'. */ +/* @@? 19:6 Error TypeError: Annotation 'MyValue' requires multiple fields to be specified. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/broken_annotation_usage.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/broken_annotation_usage.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9828b1b8e2e82ccf0d4a43c1296f149cf07863f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/broken_annotation_usage.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. + */ + +@ns.Anno<()=>void> +class A{} + +/* @@? 16:2 Error TypeError: Cannot find type 'ns'. */ +/* @@? 16:5 Error TypeError: 'Anno' type does not exist. */ +/* @@? 16:5 Error TypeError: 'Anno' is not an annotation. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/array_index.ets b/ets2panda/test/ast/compiler/ets/array_index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b56d97710ad4fcb598a55d88d864b79e8e98cb23 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/array_index.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: Char[] = new Char[n = 10]; + +/* @@? 16:28 Error TypeError: Unresolved reference n */ diff --git a/ets2panda/test/ast/compiler/ets/array_type_test.ets b/ets2panda/test/ast/compiler/ets/array_type_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..c9d5e6de74a2a78ac3481c6952467ba89fb72af4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/array_type_test.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 Options { + menuList?: [string, number, boolean]; +} + +function hee(opt: Options): [string, number, boolean] { + let menuList: [string, number, boolean] = opt.menuList ?? []; + return menuList; +} + +/* @@? 21:63 Error TypeError: Initializer has 0 elements, but tuple requires 3 */ diff --git a/ets2panda/test/ast/compiler/ets/array_with_type_parameter.ets b/ets2panda/test/ast/compiler/ets/array_with_type_parameter.ets index 467c6c8d203f2232ead8caa835b8e47abf6fa8dc..418b425ebfe305b4e5b4ed0ecbd39feb10607890 100644 --- a/ets2panda/test/ast/compiler/ets/array_with_type_parameter.ets +++ b/ets2panda/test/ast/compiler/ets/array_with_type_parameter.ets @@ -88,8 +88,10 @@ function foo6() { /* @@? 23:5 Error TypeError: Cannot use array creation expression with type parameter. */ /* @@? 31:5 Error TypeError: Cannot use array creation expression with type parameter. */ /* @@? 35:5 Error TypeError: Cannot use array creation expression with type parameter. */ +/* @@? 40:5 Error SyntaxError: Illegal start of Type Alias expression. */ /* @@? 41:5 Error TypeError: Cannot use array creation expression with type parameter. */ -/* @@? 42:5 Error TypeError: Cannot use array creation expression with type parameter. */ +/* @@? 42:5 Error TypeError: Cannot use array creation expression with non-constructable element type which is non-assignable from undefined. */ +/* @@? 42:9 Error TypeError: Cannot find type 'U'. */ /* @@? 64:9 Error TypeError: Cannot use array creation expression with type parameter. */ /* @@? 70:5 Error TypeError: Cannot use array creation expression with type parameter. */ /* @@? 76:9 Error TypeError: Cannot use array creation expression with non-constructable element type which is non-assignable from undefined. */ diff --git a/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets b/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets new file mode 100644 index 0000000000000000000000000000000000000000..80a265b50a267828ce0057daf79d4496e4347999 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/arrow_function_call_as_record_property_key.ets @@ -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. + */ + +const a: Record = { + [((): number => 2)()]: '1' +} + +const b: Record number> = { + [(():number => +("foo"))()]: function (y: string): number { + return y.length; + }, + [(():number => +("bar"))()]: (y: string):number => y.length +}; + +/* @@? 16:35 Error TypeError: need to specify target type for class composite */ +/* @@? 17:5 Error SyntaxError: Unexpected token. */ +/* @@? 17:6 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token. */ +/* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:26 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:28 Error SyntaxError: Unexpected token '1'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 20:50 Error TypeError: need to specify target type for class composite */ +/* @@? 21:5 Error SyntaxError: Unexpected token. */ +/* @@? 21:6 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 21:20 Error TypeError: Wrong operand type for unary expression */ +/* @@? 21:28 Error SyntaxError: Unexpected token. */ +/* @@? 21:31 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:34 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 21:43 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 23:6 Error SyntaxError: Unexpected token ','. */ +/* @@? 23:6 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 24:20 Error TypeError: Wrong operand type for unary expression */ +/* @@? 24:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:32 Error TypeError: This expression is not callable. */ +/* @@? 24:36 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:36 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 24:38 Error SyntaxError: Unexpected token 'string'. */ +/* @@? 24:38 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 24:44 Error SyntaxError: Unexpected token ')'. */ +/* @@? 24:45 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:46 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 24:46 Error TypeError: The type of parameter 'number' cannot be inferred */ +/* @@? 24:56 Error TypeError: Unresolved reference y */ +/* @@? 25:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/arrow_function_mismatch.ets b/ets2panda/test/ast/compiler/ets/arrow_function_mismatch.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ada0b3f4a16f33d233f126163a51cccf8c45000 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/arrow_function_mismatch.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 foo: (P: string, Q: string) => void + +foo((value: Object): void => { }, (err: Error): void => { }) + +/* @@? 18:1 Error TypeError: No matching call signature for ((value: Object) => void, (err: Error) => void) */ +/* @@? 18:5 Error TypeError: Type '(value: Object) => void' is not compatible with type 'String' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/assertInTopLevelStatement.ets b/ets2panda/test/ast/compiler/ets/assertInTopLevelStatement.ets index fce937db3e692566db891006bceb35e60f6a4401..6d8a31721c9bc96d2874ed926040d1f725bd20f3 100644 --- a/ets2panda/test/ast/compiler/ets/assertInTopLevelStatement.ets +++ b/ets2panda/test/ast/compiler/ets/assertInTopLevelStatement.ets @@ -24,7 +24,7 @@ let promise1 = new Promise((_reject: PromiseFunction): void => { let promise2 = promise1.catch((value: string): string => { result = value; - assertEQ(result, "hello"); + arktest.assertEQ(result, "hello"); return "bye"; }) diff --git a/ets2panda/test/ast/compiler/ets/assert_bad.ets b/ets2panda/test/ast/compiler/ets/assert_bad.ets index 0e9743b4bd2e4055a8278fc59ea1ce13604b10d5..d22c1d7fabf1463493e59a51c2d8370f9739df30 100644 --- a/ets2panda/test/ast/compiler/ets/assert_bad.ets +++ b/ets2panda/test/ast/compiler/ets/assert_bad.ets @@ -15,9 +15,9 @@ function main(): int { let n: int = 2 - /* @@ label1 */assertEQ(n, 5, /* @@ label2 */42); + /* @@ label1 */arktest.assertEQ(n, 5, /* @@ label2 */42); return 0; } -/* @@@ label1 Error TypeError: No matching call signature for assertEQ(int, int, int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file +/* @@@ label1 Error TypeError: No matching call signature for assertEQ(Int, Int, Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/launch_non_callable.ets b/ets2panda/test/ast/compiler/ets/assign_const.ets similarity index 83% rename from ets2panda/test/ast/parser/ets/launch_non_callable.ets rename to ets2panda/test/ast/compiler/ets/assign_const.ets index 748a265f7a03e6f5275e4cedc2b65f598f6cc481..150e93078fba6d138db5456d9106038e3519a10a 100644 --- a/ets2panda/test/ast/parser/ets/launch_non_callable.ets +++ b/ets2panda/test/ast/compiler/ets/assign_const.ets @@ -14,8 +14,8 @@ */ function main(): void { - let x = 5; - launch /* @@ label */x; + const c = 0; + /* @@ label */c = c + 1; } -/* @@@ label Error SyntaxError: Only call expressions are allowed after 'launch'. */ +/* @@@ label Error TypeError: Cannot assign to a constant variable c */ diff --git a/ets2panda/test/ast/compiler/ets/async-function-expression1.ets b/ets2panda/test/ast/compiler/ets/async-function-expression1.ets new file mode 100644 index 0000000000000000000000000000000000000000..de02a742451ceee41853731115e253ec22a218be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/async-function-expression1.ets @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function relationalStoreCustomDirTest() { + it(async function () {}) + + it(async function () { + let storestore = null; + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) + + it(async function () { + const STORE_CONFIG = { + name: "", + securityLevel: data_Rdb.SecurityLevel.S1, + customDir: "" + } + let storestore = await data_Rdb.getRdbStore(context, STORE_CONFIG); + await storestore.executeSql(CREATE_TABLE_TEST, null); + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) +} +/* @@? 17:5 Error TypeError: Unresolved reference it */ +/* @@? 17:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:5 Error TypeError: This expression is not callable. */ +/* @@? 19:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 31:5 Error TypeError: This expression is not callable. */ +/* @@? 31:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ diff --git a/ets2panda/test/ast/compiler/ets/async-function-expression2.ets b/ets2panda/test/ast/compiler/ets/async-function-expression2.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4fef79dcf25a122cf68f790e788854816ff7fc9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/async-function-expression2.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function relationalStoreCustomDirTest() { + it(async function function() {}) + + it(async function function() { + let storestore = null; + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) + + it(async function function() { + const STORE_CONFIG = { + name: "", + securityLevel: data_Rdb.SecurityLevel.S1, + customDir: "" + } + let storestore = await data_Rdb.getRdbStore(context, STORE_CONFIG); + await storestore.executeSql(CREATE_TABLE_TEST, null); + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) +} +/* @@? 17:5 Error TypeError: Unresolved reference it */ +/* @@? 17:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:5 Error TypeError: This expression is not callable. */ +/* @@? 19:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 19:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 19:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 31:5 Error TypeError: This expression is not callable. */ +/* @@? 31:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 31:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 31:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 31:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 31:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/async_import_3.ets b/ets2panda/test/ast/compiler/ets/async_import_3.ets index 3622080a97b6f74692ea817eba28510819d18ae2..165c0f7649eae9371dcacc8dcc7727cab09fdee8 100644 --- a/ets2panda/test/ast/compiler/ets/async_import_3.ets +++ b/ets2panda/test/ast/compiler/ets/async_import_3.ets @@ -16,4 +16,4 @@ import {foo} from './async_import_4' let prop: int = foo() /* @@? 16:17 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/async_with_lambda.ets b/ets2panda/test/ast/compiler/ets/async_with_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4dadb97d1d493aea22860f47b173b7202055a90 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/async_with_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: (arg: T) => Promise): Promise { + return (async (): Promise => { + const result = await Promise.resolve(undefined); + if (result !== undefined) { + await a(result); + } else { + await a(undefined as T); + } + return undefined; + })(); +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_1.ets b/ets2panda/test/ast/compiler/ets/awaited_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ea926e1b413ac07602b2112de6a55613d8d7711 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_1.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. + */ + +interface User { + age: Promise +} +class Myuser implements User { + age: Promise = delay(1) +} +const delay = (value: number): Promise => { + return Promise.resolve(value) +} +async function identity(arg: Type): Promise { + return Promise.resolve(arg); +} + +let user = new Myuser() +type user_name = Promise + +async function main() { + let awaited_user: number = await user.age + let aw: number = await identity(user.age) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_2.ets b/ets2panda/test/ast/compiler/ets/awaited_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..99fc80034e60d2e5933818bd7f942c757872d8f1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_2.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 f(x: Awaited) {} + +async function ff(x: Promise) { + f(await x) +} + +const asyncfunc = async() => { + return Promise.resolve(1.0) +} + +function main() { + let x = ff(asyncfunc()) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_3.ets b/ets2panda/test/ast/compiler/ets/awaited_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..34bdb6b7aa0673bcf374d7a3ec3188f79f434064 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_3.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. + */ + +type PromisesArray = Promise[]; +type AwaitedArray = Awaited; + +async function B(a: T) : Promise> { + return await a +} + +async function main() { + let a: Promise = Promise.resolve("1") + let b: PromisesArray = [a] + console.log(b) + let c: AwaitedArray = await B(b) + console.log(c) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_4.ets b/ets2panda/test/ast/compiler/ets/awaited_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..122bb725e963b5a3db9f91e5366b1c51cf02bdde --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_4.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 { + method_1(): Awaited { + console.log("1") + return "1" as Awaited + } +} + +class B extends A { + method_1(): Awaited { + return "1" as Awaited + } +} + +function ff1() { + let a: Awaited = "1" as Awaited +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_assignability_2_neg.ets b/ets2panda/test/ast/compiler/ets/awaited_assignability_2_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..eba08ed8791b144bc13f774734dae19ff0345c85 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_assignability_2_neg.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. + */ + +async function aw(p: Promise, cb: (v: T) => void) { + let x: T = await p + cb(x) +} + +/* @@? 17:16 Error TypeError: Type 'Awaited' cannot be assigned to type 'T' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_assignability_neg.ets b/ets2panda/test/ast/compiler/ets/awaited_assignability_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..680c93f3280b78250ba89fb295247f77cdca67f9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_assignability_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. + */ + +async function aw(p: Promise, cb: (v: T) => void) { + let x: Awaited = await p + cb(x) +} + +/* @@? 18:5 Error TypeError: No matching call signature for (Awaited) */ +/* @@? 18:8 Error TypeError: Type 'Awaited' is not compatible with type 'T' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_utility_type.ets b/ets2panda/test/ast/compiler/ets/awaited_utility_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9f5bc86dd9b0fcbd0810f91440e3667424daeab --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_utility_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. + */ + +type A = Awaited // string +type B = Awaited>>> // number | boolean +type C = Awaited | boolean> // number | boolean +type D = Awaited // number | string + +type E = Awaited|Promise>>> +const results: E = [Promise.resolve(1.0)] // OK +let results_2 : E = [1.0] +let a: A = "a" +let valueB: B = true +let valueD: D = 123 + +/* @@? 23:22 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Promise|Promise' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/awaited_with_array.ets b/ets2panda/test/ast/compiler/ets/awaited_with_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..644cf02a40d41dfa4f113c7fd4f7874e5a2d38f0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/awaited_with_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. + */ + +type PromisesArray = Promise[] +type AwaitedArray = Awaited + +const results: AwaitedArray = ["hello"] + +/* @@? 19:32 Error TypeError: Array element at index 0 with type '"hello"' is not compatible with the target array element type 'Promise' */ diff --git a/ets2panda/test/ast/compiler/ets/bad_call_setter.ets b/ets2panda/test/ast/compiler/ets/bad_call_setter.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e68c90948a0b0e4020b1ba1fc04c6a4ea1b623b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bad_call_setter.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 { + set text(s: string) +} + +class B implements I { + text: string = "" + s : string + this.text = s; +} + +function main() { + let ins: I = new B(); + ins.text = "He"; +} + +/* @@? 23:5 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 23:9 Error SyntaxError: Unexpected token '.'. */ +/* @@? 23:10 Error TypeError: Variable 'text' has already been declared. */ +/* @@? 23:17 Error TypeError: Property 's' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets b/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..5ea74fcbfbb52378b2eb73e17770394c9f01cea3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const v0 = 1516532564n; +const vStr = "Weens" +for (const v2 of vStr) { + for (let v3 = 0; v3< 93; v3++) { + const v4 = [-3.0, -921192.1546513135, -1000000.0, 0.21581641635431563, NaN, 1e-15, -1e-15, -28.514616541534]; + } + const v1 = 545314157; + const gtTest = v1 > v0; + const ltTest = v1 < v0; + const gteTest = v1 >= v0; + const lteTest = v1 <= v0; + const eqTest = v1 == v0; + const neqTest = v1 != v0; + const addTest = v1 + v0; + const subTest = v1 - v0; + const mulTest = v1 * v0; + const divTest = v1 / v0; + const modTest = v1 % v0; + const bitOrTest = v1 | v0; + const bitAndTest = v1 & v0; + const bitXorTest = v1 ^ v0; + const rightTest = v1 >> v0; + const leftTest = v1 << v0; +} + +/* @@? 29:21 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ +/* @@? 30:21 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ +/* @@? 31:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 32:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 33:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 34:23 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 35:24 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 36:24 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 37:23 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 38:22 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ diff --git a/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets b/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets new file mode 100644 index 0000000000000000000000000000000000000000..b5b4c1be3a94209089afa3681d64d43364a562f9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const v0 = 1516532564n; +const v1 = 213n; + +let v2 = v0 >>> v1; + +/* @@? 19:10 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ diff --git a/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets b/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets index ee4c76c29c6417bd9ab87822f613085e9f4bc595..4bee69637bc0a64837cb1169e070ffe61136a56f 100644 --- a/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets +++ b/ets2panda/test/ast/compiler/ets/binary_operator_neg.ets @@ -15,7 +15,8 @@ /* @@ label1 */@@/@ -/* @@@ label1 Error SyntaxError: Unexpected token '@@'. */ -/* @@? 21:93 Error SyntaxError: Identifier expected, got 'eos'. */ -/* @@? 21:93 Error SyntaxError: Unexpected token 'eos'. */ -/* @@? 21:93 Error SyntaxError: Annotations are not allowed on this type of declaration. */ \ No newline at end of file +/* @@@ label1 Error SyntaxError: Unexpected token '@@'. */ +/* @@? 23:1 Error SyntaxError: Identifier expected, got 'end of stream'. */ +/* @@? 23:1 Error SyntaxError: Invalid annotation name. */ +/* @@? 23:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 23:1 Error SyntaxError: Annotations are not allowed on this type of declaration. */ diff --git a/ets2panda/test/ast/compiler/ets/bit_wise_expr.ets b/ets2panda/test/ast/compiler/ets/bit_wise_expr.ets new file mode 100644 index 0000000000000000000000000000000000000000..06330f44ea82f42d2cf03ba182961b3349d62dbd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bit_wise_expr.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. + */ + +let tup : [['arkTs' | boolean, 1 | true]] = [['arkTs', 1]]; + +/* @@? 16:32 Error SyntaxError: Invalid Type. */ +/* @@? 16:32 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 16:32 Error SyntaxError: Unexpected token '1'. */ +/* @@? 16:32 Error TypeError: Wrong type of operands for binary expression */ +/* @@? 16:32 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 16:40 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:41 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/block_namespace_interface_name_conflict.ets b/ets2panda/test/ast/compiler/ets/block_namespace_interface_name_conflict.ets new file mode 100644 index 0000000000000000000000000000000000000000..b0a58f1f5848d181784d5697817b2975b65171df --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/block_namespace_interface_name_conflict.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 A { + } + namespace A { + } +} + +/* @@? 18:5 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@? 20:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ diff --git a/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts new file mode 100644 index 0000000000000000000000000000000000000000..8e8a1ea0ffc5814e408e89f0d656a682d3a06159 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts @@ -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 A { + func(a: Double): String { return a.toExponential() } + func(a: Float): String { return a.toString() } + func(a: Int): String { return a.toString() } +} + +function main(): int{ + let c1: A = new A(); + let helpbyte: Byte = new Byte(1 as byte); + let helpdouble: Double = new Double(1 as double); + if (c1.func(helpbyte) != helpdouble.toExponential()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets index c4d703e4a25f9c17408d978147e9471016b71002..10aaa0dbfca960daa74accd9eec73a8bfe7bc307 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets @@ -15,7 +15,5 @@ function main() : void { let a: Byte = 2; - let b: Byte = /* @@ label */new Byte(2); + let b: Byte = new Byte(2); } - -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets index 219921314be7d2169d4de6cd525622a94fefc1ed..4b463095b76371a963337ddb9cdfc57b6faf4dd8 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets @@ -16,13 +16,12 @@ function refInt(a: Int): void {} function main() : void { - let a: Short = /* @@ label */new Short(3); // 3 is int, invocation context won't allow primitive narrowing + let a: Short = new Short(3); // 3 is of type short in this context let b: short = 2; let c: short = /* @@ label1 */-b; // due to unary operator promotion, '-b' will be int, which is not assignable let d: short = /* @@ label2 */b | b; // due to binary operator promotion, 'b | b' will be int, which is not assignable - refInt(b); // primitive widening before boxing is not allowed + refInt(b); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Short(int) */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'short' */ -/* @@@ label2 Error TypeError: Type 'int' cannot be assigned to type 'short' */ +/* @@@ 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/broken_getter.ets b/ets2panda/test/ast/compiler/ets/broken_getter.ets new file mode 100644 index 0000000000000000000000000000000000000000..3651757ed87afe7bb557c1d93c8ba7e07ff27afe --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/broken_getter.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 { + is.$_get(this.length = 1).toDouble() +} + +/* @@? 17:7 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:7 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:13 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:18 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:18 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:29 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:30 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:39 Error TypeError: Only abstract or native methods can't have body. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/broken_partial_type.ets b/ets2panda/test/ast/compiler/ets/broken_partial_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f43faf7fa2438620fa8866acd2acf3eaf43f2231 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/broken_partial_type.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. + */ + +enum Kind { + A = "A", + B = "B" +} + +interface Entity { + kind: () => Kind +} + +interface EntityA extends Entity { + kind: () => Kind.A +} + +interface EntityB extends Entity { + kind: () => Kind.B +} + +type EntityUnion = EntityA | EntityB + +function createEntityA(): EntityUnion { + const entity: Partial = {} + return entity as EntityUnion +} + + +/* @@? 26:3 Error TypeError: kind(): () => *ERROR_TYPE*|undefined in Partial cannot override kind(): () => Kind|undefined in Partial because overriding return type is not compatible with the other return type. */ +/* @@? 26:3 Error TypeError: Method kind(): () => *ERROR_TYPE*|undefined in Partial not overriding any method */ +/* @@? 26:3 Error TypeError: kind(): () => *ERROR_TYPE* in EntityA cannot override kind(): () => Kind in Entity because overriding return type is not compatible with the other return type. */ +/* @@? 26:3 Error TypeError: Method kind(): () => *ERROR_TYPE* in EntityA not overriding any method */ +/* @@? 26:20 Error TypeError: 'A' type does not exist. */ +/* @@? 30:3 Error TypeError: kind(): () => *ERROR_TYPE* in EntityB cannot override kind(): () => Kind in Entity because overriding return type is not compatible with the other return type. */ +/* @@? 30:3 Error TypeError: Method kind(): () => *ERROR_TYPE* in EntityB not overriding any method */ +/* @@? 30:20 Error TypeError: 'B' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/broken_setter.ets b/ets2panda/test/ast/compiler/ets/broken_setter.ets new file mode 100644 index 0000000000000000000000000000000000000000..9330afc1737c32002ffde4b3079d3823fd1548f3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/broken_setter.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 i = 0 + +class A{ + set p(){ + i+=1 + } + + get p():number { + return this.p + } +} + +function foo(p:Partial){} + +/* @@? 23:5 Error SyntaxError: Setter must have exactly one formal parameter. */ +/* @@? 23:5 Error TypeError: Function p is already declared. */ +/* @@? 24:21 Warning Warning: Reading the value of the property inside its getter may lead to an endless loop. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/builtin_thisArgs.ets b/ets2panda/test/ast/compiler/ets/builtin_thisArgs.ets new file mode 100755 index 0000000000000000000000000000000000000000..9c4ec53ad739e45888b7d93afc7c2439e82cf254 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/builtin_thisArgs.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 MyClass { + compare((value: number, index:number, arr: Array)) {} +} + +/* @@? 16:1 Error SyntaxError: Class cannot be used as object. */ +/* @@? 16:7 Error SyntaxError: Unexpected token 'MyClass'. */ +/* @@? 16:7 Error TypeError: Unresolved reference MyClass */ +/* @@? 16:15 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:3 Error TypeError: Unresolved reference compare */ +/* @@? 17:17 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 17:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:19 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 17:19 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:25 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:27 Error SyntaxError: Unexpected token 'index'. */ +/* @@? 17:33 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:33 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:39 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:41 Error SyntaxError: Unexpected token 'arr'. */ +/* @@? 17:46 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:46 Error TypeError: No matching call signature with trailing lambda */ +/* @@? 17:59 Error SyntaxError: Unexpected token, expected '('. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/call_signature.ets b/ets2panda/test/ast/compiler/ets/call_signature.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae2f208c22f3b429eb7e17cfb0dc4ca80c823e59 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/call_signature.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 Proxy { + private foo(target: T) {} + private bar( + getter:Method: void { + const result = getter.getType() + const Create = new MethodCreate(getter.getName()).addResult(resultType + Create.AddBody(new AbortController((): Byte => { + const handle = Reflect.get() + return (this.foo(handle) as Numeric).toByte.) + } + } + ) +} + +/* @@? 17:25 Error TypeError: Cannot find type 'T'. */ +/* @@? 19:22 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 21:28 Error TypeError: Cannot find type 'MethodCreate'. */ +/* @@? 22:13 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 22:32 Error TypeError: Cannot find type 'AbortController'. */ +/* @@? 24:61 Error SyntaxError: Identifier expected, got ')'. */ +/* @@? 26:9 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 27:5 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/call_signature_error.ets b/ets2panda/test/ast/compiler/ets/call_signature_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ec272c4893662db5f0d5284f7fbe4089092332a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/call_signature_error.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. + */ + +type DescribableFunction = /* @@ label1 */{ + /* @@ label2 */(someArg: number): string +} + +/* @@@ label1 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@@ label2 Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets index a19a44352a9b97470e54b0e29138dd7b7a820c82..020e690781cad37f9ee3954729d88aa5b5e983f7 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as boolean } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets index 1494ec034e28b737cb68cf2e9e2772e311199b33..e2f0327a04c916b5f01c617504dd08287e2bc03f 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets index 5a6a68e66b7c31b4e376dbbab0378a25f9d79314..235ac7461a87ed860eafc57c6d261daa1fb660f1 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data! as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets index a2c9561af576d18dc9f67b5e5f92b31b833c3c11..41fa96e0b972a191ce8db252290a426c280b41c9 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as boolean } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets index 6ee459478d6d679d26a1834fc0e28f66f459cd78..7b3d28faf85ba08dffa8d0e7a8fb5954f05c6f54 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as int } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets index c07d310c30a64138cfb17f83c8636b1ef76d12fb..89bcb6c6108a830fdd17aa960d456abd5f72fd1f 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets index 55d610c6b96cddc9cb45e7ff00c4a90840e28f8a..252c90bce1427f95a690d4bb686dca65fce17d19 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data: T | boolean | null): void { let aNumber = data as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'T|Boolean|null' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets index 8a088bee5ffdea20255fe087f585bc844f24d7b1..54003819499bc62708314cd182cc3a466368a103 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets @@ -19,4 +19,3 @@ function foo(data: T | A): void { let aNumber = data as int } -/* @@? 19:19 Error TypeError: Cannot cast type 'T|A' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets index 5c261ef099dd9793dfd3be7acc127129f1660f26..9c91b473e799738e44f425bcd1ca2e50d93b66f2 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets @@ -18,4 +18,3 @@ function foo(data: T, x: boolean): void { let aNumber = data2 as int } -/* @@? 18:19 Error TypeError: Cannot cast type 'Boolean|NonNullable' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts new file mode 100644 index 0000000000000000000000000000000000000000..bbb82aee67ab2cbe54fe2697b00cc6411c3f7855 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.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. + */ + +class A {} + +function foo(a: Float): Float { + return a; +} + +function main(): int { + let c: A | Double = new Double(10.0); + let b: Int = new Int(9); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/catch_error.ets b/ets2panda/test/ast/compiler/ets/catch_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..069c1025280929585ebe4af8412736ba171cf42e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/catch_error.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. + */ + +const asyncFunction = async () => { + return new Promise((resolve, reject) => { + setTimeout(() => { + reject(new Error()) + }, 1000) + }) +} + +async function main() { + const result : number = await asyncFunction() + .then((result) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(result + 1) + }, 500) + }) + }) + .then((result) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(result + 4) + }, 500) + }) + }).catch((): number => { + console.log("PromiseMultiAsyncOperationTest0300 test error") + return 0 + }) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/check_spreadElement.ets b/ets2panda/test/ast/compiler/ets/check_spreadElement.ets new file mode 100644 index 0000000000000000000000000000000000000000..69f13c49a7233439470f4d94ed06dcb94a10e042 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/check_spreadElement.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. + */ + +[a, b, ...rest] = [1, 2, 3, 4, 5]; + +/* @@? 16:1 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:2 Error TypeError: Unresolved reference a */ +/* @@? 16:5 Error TypeError: Unresolved reference b */ +/* @@? 16:11 Error TypeError: Unresolved reference rest */ diff --git a/ets2panda/test/ast/compiler/ets/check_variance_crash.ets b/ets2panda/test/ast/compiler/ets/check_variance_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..f5bfa6f4682b1990f5da896ba55be3b2b898e6dd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/check_variance_crash.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type BreakpointType = 'xs' | 'sm' +class BreakPointState { + public update(type: BreakpointType):void { + } +} diff --git a/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets b/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..5315c5449bd9fa267cfa1d3add030a94c393eb66 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo() { + let s = "2".concat(s).concat("4"); +} + +/* @@? 17:13 Error TypeError: Circular call function */ +/* @@? 17:24 Error TypeError: Variable 's' is accessed before it's initialization. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets b/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7bb4cc136be5cf3d8292fc2a3adf98291cbeb08 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.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 D{ + f7(x: string, y: D.f7){} +} + +/* @@? 16:8 Error TypeError: Circular dependency detected for identifier: D */ +/* @@? 17:22 Error TypeError: 'f7' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/circular_unfold.ets b/ets2panda/test/ast/compiler/ets/circular_unfold.ets new file mode 100644 index 0000000000000000000000000000000000000000..6fabd26be970ccdd8a3f6a791be482626d9d6c39 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_unfold.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() { + const a = a + const b = b + return b - a +} + +/* @@? 17:11 Error TypeError: Circular dependency detected for identifier: a */ +/* @@? 17:15 Error TypeError: Variable 'a' is accessed before it's initialization. */ +/* @@? 18:11 Error TypeError: Circular dependency detected for identifier: b */ +/* @@? 18:15 Error TypeError: Variable 'b' is accessed before it's initialization. */ diff --git a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets index af59760eb594df83e7d67056e00a8ef05a348a7c..106ae6f38c818d601bdcd1f7bf051cdb7cf83397 100644 --- a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets +++ b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets @@ -43,10 +43,12 @@ function main() { let maind = mainc; } +/* @@? 17:16 Warning Warning: The instance field initializer expression cannot use the this. */ /* @@? 18:12 Error TypeError: Circular dependency detected for identifier: b */ +/* @@? 18:16 Warning Warning: The instance field initializer expression cannot use the this. */ /* @@? 23:19 Error TypeError: Circular dependency detected for identifier: b */ /* @@? 31:15 Error TypeError: Unresolved reference globalb */ -/* @@? 33:5 Error TypeError: Circular dependency detected for identifier: globalc */ +/* @@? 34:5 Error TypeError: Circular dependency detected for identifier: globald */ /* @@? 37:7 Error TypeError: Circular dependency detected for identifier: constb */ /* @@? 40:17 Error TypeError: Unresolved reference mainb */ /* @@? 42:17 Error TypeError: Variable 'maind' is accessed before it's initialization. */ diff --git a/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets b/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..89afebb59c28b0d63991ab1418a38b63acca1d11 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_cyclic_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. + */ + +class A { + public x : int; + + public constructor() { + this(5); + } + + public constructor( + let tuple: {{c.to_type}} = {{caches.value}}; + let a : A = new A(...tuple); + let method_result = A.bar(...tuple); + ) { + this.x = a; + } +} + +/* @@? 23:23 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 24:9 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 24:9 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 24:9 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 24:9 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:20 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 24:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 24:23 Error SyntaxError: Field type annotation expected. */ +/* @@? 24:23 Error SyntaxError: Unexpected token '.'. */ +/* @@? 24:31 Error SyntaxError: Field type annotation expected. */ +/* @@? 24:34 Error SyntaxError: Unexpected token '='. */ +/* @@? 24:36 Error SyntaxError: Unexpected token '{'. */ +/* @@? 24:38 Error TypeError: Unresolved reference caches */ +/* @@? 25:21 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@? 25:21 Error TypeError: No matching construct signature for class_cyclic_constructor.A(...tuple) */ +/* @@? 25:30 Error TypeError: Unresolved reference tuple */ +/* @@? 26:31 Error TypeError: Property 'bar' does not exist on type 'A' */ +/* @@? 27:5 Error SyntaxError: Unexpected token ')'. */ +/* @@? 27:7 Error SyntaxError: Unexpected token '{'. */ +/* @@? 28:9 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 28:14 Error TypeError: Property 'x' does not exist on type 'ETSGLOBAL' */ +/* @@? 30:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/class_inheritance.ets b/ets2panda/test/ast/compiler/ets/class_inheritance.ets new file mode 100644 index 0000000000000000000000000000000000000000..78e049e51ac5a9b226a4d896a97546d51ebd127e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_inheritance.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class AAA { + objectProp = {name: 'Jone', age: 30}; +} + +class BBB extends AAA { + objectProp = {name: 'Jone', age: 30}; +} + +/* @@? 17:5 Error TypeError: Cannot infer type for objectProp because class composite needs an explicit target type */ +/* @@? 21:5 Error TypeError: Cannot infer type for objectProp because class composite needs an explicit target type */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/class_literal.ets b/ets2panda/test/ast/compiler/ets/class_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..6162acc11169e5bab28a982fc4ae3a2e44a22601 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_literal.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let rectangle = class { + constructor(height: number, width: number) { + this.height = height + this.width = width + } + height: number; + width: number; +} + +/* @@? 26:1 Error TypeError: Class literal is not yet supported. */ diff --git a/ets2panda/test/ast/compiler/ets/class_return_as_object.ets b/ets2panda/test/ast/compiler/ets/class_return_as_object.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4b77979fb43c6281000e9ec05d01fff847a6730 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_return_as_object.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Example {} + +function getExampleClass() { + return Example; +} + +const exampleClassReference = getExampleClass; +exampleClassReference().toString(); + +/* @@? 19:12 Error SyntaxError: Class cannot be used as object. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets b/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.ets new file mode 100644 index 0000000000000000000000000000000000000000..2926286b817fccaa6a16213dcdb5454341873c23 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_without_closing_parentheses.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. + */ + +export default class TreeMap implements ReadonlyTreeMap { + + private mappedIterator(fn: (e: TreeMapEntry) => R): IterableIterator { + export default namespace buffer{ } + + const buffer = new ArrayBuffer(length); + let offset = 0; + for (let i = 0; i < length; i++) { + buffer.set(offset, length[i]); + } + return new buffer(buffer); + } +} + +/* @@? 16:47 Error TypeError: Cannot find type 'ReadonlyTreeMap'. */ +/* @@? 16:47 Error TypeError: Interface expected here. */ +/* @@? 18:39 Error TypeError: Cannot find type 'TreeMapEntry'. */ +/* @@? 19:9 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token 'default'. */ +/* @@? 19:24 Error SyntaxError: Unexpected token 'namespace'. */ +/* @@? 19:24 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 21:15 Error TypeError: Variable 'buffer' has already been declared. */ +/* @@? 21:15 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ +/* @@? 24:32 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 26:20 Error TypeError: Namespace 'buffer' cannot be used as a type. */ diff --git a/ets2panda/test/ast/compiler/ets/classproperty_init_neg.ets b/ets2panda/test/ast/compiler/ets/classproperty_init_neg.ets index 65fa3f5ea6928280df37aa218cf0baa3ff0c0a35..4f419d33d4438b4b395457fc8365a9d31fd174ef 100644 --- a/ets2panda/test/ast/compiler/ets/classproperty_init_neg.ets +++ b/ets2panda/test/ast/compiler/ets/classproperty_init_neg.ets @@ -15,4 +15,4 @@ class A {b5 : boolean = /* @@ label1 */7;} -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'boolean' */ \ No newline at end of file +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'Boolean' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/conditional-type-alias.ets b/ets2panda/test/ast/compiler/ets/conditional-type-alias.ets new file mode 100644 index 0000000000000000000000000000000000000000..d852f652917f4b46fc2edd7d7a331cfb3038dd20 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/conditional-type-alias.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. + */ + +// (arkts-no-conditional-types) +type X = T extends number ? T : string + +/* @@? 17:15 Error SyntaxError: Unexpected token 'extends'. */ +/* @@? 17:15 Error TypeError: Conditional type aliases are not supported. Introduce a new type with constraints explicitly, or rewrite logic using Object! */ +/* @@? 17:23 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 17:23 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:32 Error TypeError: Unresolved reference T */ +/* @@? 17:36 Error TypeError: Type name 'string' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference.ets b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference.ets new file mode 100644 index 0000000000000000000000000000000000000000..ece14278ce1e0ea0ce2eb5cc1836602e5dc6e2fe --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const constExpr = "123" +let variable: constExpr = 42 + +/* @@? 17:15 Error TypeError: Cannot find type 'constExpr'. */ diff --git a/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference1.ets b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference1.ets new file mode 100644 index 0000000000000000000000000000000000000000..60cb72873ec79bf0374872f317c91ea67f254a95 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference1.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 NestedClass { + readonly constField: string = "123" +} + +class A { + readonly constClass: NestedClass + + constructor() { + this.constClass = new NestedClass + } +} + +const constExpr = new A +let variable: constExpr.constClass.constField = 42 + +/* @@? 29:15 Error TypeError: Cannot find type 'constExpr'. */ +/* @@? 29:25 Error TypeError: 'constClass' type does not exist. */ +/* @@? 29:36 Error TypeError: 'constField' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference2.ets b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba90d65351785c6f913951fcc97bb6ccce6730b7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constExpressionAsTypeReference2.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 { + readonly constField: string = "123" +} + +const constExpr = new A +let variable: constExpr.constField = 42 + +/* @@? 21:15 Error TypeError: Cannot find type 'constExpr'. */ +/* @@? 21:25 Error TypeError: 'constField' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence01.ets b/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence01.ets new file mode 100644 index 0000000000000000000000000000000000000000..7317988cd7d970e2846351140271eb6c7c544d00 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence01.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 = a + 1; + +/* @@? 16:7 Error TypeError: Circular dependency detected for identifier: a */ diff --git a/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence02.ets b/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence02.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d9c74857504829127a03ba2d85370ab7158fd8e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/const_unfold_self_dependence02.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const b = c + 1; +const c = d + 1; +const d = e + 1; +const e = f + 1; +const f = g + 1; +const g = b + 1; + +/* @@? 17:7 Error TypeError: Circular dependency detected for identifier: c */ diff --git a/ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets b/ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c11d04fe1e14a98d804b7adc948ac2816871b47 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constantExpressionLowering.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. + */ + +// 1. +const tmpl = `` + +// 2. +const flag = true +const a = +(flag) +const b = -(flag) +const c = ~(flag) + +/* @@? 21:11 Error TypeError: Wrong operand type for unary expression */ +/* @@? 21:12 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@? 22:11 Error TypeError: Wrong operand type for unary expression */ +/* @@? 22:12 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@? 23:11 Error TypeError: Wrong operand type for unary expression */ +/* @@? 23:12 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ diff --git a/ets2panda/test/ast/compiler/ets/constantExpressionLowering_2.ets b/ets2panda/test/ast/compiler/ets/constantExpressionLowering_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a2315963a7e7b8eb1af5ce0349a3e4be1699e15 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constantExpressionLowering_2.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. + */ + +enum CCCCCCCCC {} + +CCCCCCCCC[foo()].foo(); + +/* @@? 18:11 Error TypeError: Unresolved reference foo */ +/* @@? 18:18 Error TypeError: Property 'foo' does not exist on type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/constant_expression_test/constant_expression_test.ets b/ets2panda/test/ast/compiler/ets/constant_expression_test/constant_expression_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a8a7fa5113cdb10df07fcb38928d96cfd8d1a19 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constant_expression_test/constant_expression_test.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(): int { + let tuple: [number, number] = [0,5]; + tuple[/* @@ label */MathPartialSums.g_flag = 0] = 12; + return 0; +} + +/* @@@ label Error TypeError: Unresolved reference MathPartialSums */ +/* @@@ label Error TypeError: Only constant expression allowed for element access on tuples. */ 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/conversion_call-context_Int-to-Double_typeerror.ets b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets index 8be10405f5a6463214649ab42f76f5b50545568b..49d13737727d30b8999a7433f098dc98006b333c 100644 --- a/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets +++ b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets @@ -17,9 +17,7 @@ function foo(x: Double) {} function main(): void { let a : Int = new Int(2); - /* @@ label */foo(/* @@ label1 */a); + foo(a); return; } -/* @@@ label1 Error TypeError: Type 'Int' is not compatible with type 'Double' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/runtime/ets/constant_char_asexpression.ets b/ets2panda/test/ast/compiler/ets/conversion_double_to_float.ets similarity index 47% rename from ets2panda/test/runtime/ets/constant_char_asexpression.ets rename to ets2panda/test/ast/compiler/ets/conversion_double_to_float.ets index 6b12b15f07ccb3b11c7c9dd721237b54a6a8d70c..18a14085dc15282e037ca0e0892f9833c732c931 100644 --- a/ets2panda/test/runtime/ets/constant_char_asexpression.ets +++ b/ets2panda/test/ast/compiler/ets/conversion_double_to_float.ets @@ -13,26 +13,26 @@ * limitations under the License. */ -const constchar: char = c'p' - -function main() { - const constcharToByte = constchar as byte - assertEQ(constcharToByte ,112) - enum TestEnum1 { One = constcharToByte } - assertEQ(TestEnum1.One.valueOf(),112) +function foo(a: float) : Int { + return 0; +} - const constcharToShort = constchar as short - assertEQ(constcharToShort ,112) - enum TestEnum2 { One = constcharToShort } - assertEQ(TestEnum2.One.valueOf(),112) +export const f1: float = 1.0; - const constcharToInt = constchar as int - assertEQ(constcharToInt ,112) - enum TestEnum3 { One = constcharToInt } - assertEQ(TestEnum3.One.valueOf(),112) +function main() { + const f2: float = 2.0; - const constcharToLong = constchar as long - assertEQ(constcharToLong ,112) - enum TestEnum4 { One = constcharToLong } - assertEQ(TestEnum4.One.valueOf(),112) + foo(3.0); + foo(4.0); + + foo(1.0/0.0); + foo(Infinity); + foo(NaN); } + +/* @@? 28:5 Error TypeError: No matching call signature for foo(Double) */ +/* @@? 28:9 Error TypeError: Type 'Double' is not compatible with type 'Float' at index 1 */ +/* @@? 29:5 Error TypeError: No matching call signature for foo(Double) */ +/* @@? 29:9 Error TypeError: Type 'Double' is not compatible with type 'Float' at index 1 */ +/* @@? 30:5 Error TypeError: No matching call signature for foo(Double) */ +/* @@? 30:9 Error TypeError: Type 'Double' is not compatible with type 'Float' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/conversions/implicit/float_literal_implicit_conversion.ets b/ets2panda/test/ast/compiler/ets/conversions/implicit/float_literal_implicit_conversion.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b5e3b529a48f9bf65736c6a6fc6ec8053461d24 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/conversions/implicit/float_literal_implicit_conversion.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. + */ + + +let i : int = -5 +i = /* @@ label_i1 */-5.0 +i = /* @@ label_i2 */-5.f + +i = 0 +i = /* @@ label_i3 */0.0 +i = /* @@ label_i4 */0.f + +i = 5 +i = /* @@ label_i5 */5.0 +i = /* @@ label_i6 */5.f + +let d : double = -5 +d = -5.0 +d = -5.f + +d = 0 +d = 0.0 +d = 0.f + +d = 5 +d = 5.0 +d = 5.f + +/* @@@ label_i1 Error TypeError: Type 'Double' cannot be assigned to type 'Int' */ +/* @@@ label_i2 Error TypeError: Type 'Float' cannot be assigned to type 'Int' */ +/* @@@ label_i3 Error TypeError: Type 'Double' cannot be assigned to type 'Int' */ +/* @@@ label_i4 Error TypeError: Type 'Float' cannot be assigned to type 'Int' */ +/* @@@ label_i5 Error TypeError: Type 'Double' cannot be assigned to type 'Int' */ +/* @@@ label_i6 Error TypeError: Type 'Float' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/debugger-statement.ets b/ets2panda/test/ast/compiler/ets/debugger-statement.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f2f52cc71b62cdcaa15bba42ed472a4e2832de4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/debugger-statement.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. + */ + +// (arkts-no-debugger-stmt) +function main(): void { + for (let i = 0; i < 10; i++) + { + debugger; + console.log(i); + } +} + +/* @@? 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 index ad56d9aa62741d2a70350484509799af72e881ea..3ba2dfbb74eb2fb78e457e85c01bc1a5dfee7b5d 100644 --- a/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets @@ -15,11 +15,7 @@ declare const type typeA = int; -/* @@? 16:20 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 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'. */ -/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 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 index 2a64b2993b798f8eb67ec9c00adf5d859d8cea94..ba03a78da1d25d035ed1071fe7ca7f1039c75d69 100644 --- a/ets2panda/test/ast/compiler/ets/declareType_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_2.ets @@ -21,5 +21,4 @@ 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' */ - +/* @@? 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_4.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_4.ets index 08f526f7634d58ef3ed44c6b07468bd990da4c7b..76fdc63e58a654c1e154b920bab032e16ce05c35 100644 --- a/ets2panda/test/ast/compiler/ets/declareType_neg_4.ets +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_4.ets @@ -21,5 +21,5 @@ let a : int[] = [1,2,3] let b : type_array_alias = a; -/* @@? 21:37 Error TypeError: Type 'int[]' cannot be assigned to type 'Array>|String[]' */ +/* @@? 21:37 Error TypeError: Type 'Array' cannot be assigned to type 'Array>|Array' */ diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets index d98c0d56f3b4d482d866f1e3752e63dc671018a4..0b54a5df0f2ab504e466b38470ddcd6e2707e4ae 100644 --- a/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets @@ -16,5 +16,5 @@ import typeA from './declareType_neg_export' let a : typeA = new Array() -/* @@? 16:22 Error TypeError: Type 'Array' cannot be assigned to type 'Int[]|Array' */ +/* @@? 16:22 Error TypeError: Type 'Array' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/compiler/ets/default_param_declare.ets b/ets2panda/test/ast/compiler/ets/default_param_declare.ets new file mode 100644 index 0000000000000000000000000000000000000000..491faa15e8776f434ca3093296d3895001dfa6aa --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/default_param_declare.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare class A{ + foo(/* @@ label1 */a:number = 1, /* @@ label2 */b:int = 2):void +} + +/* @@@ label1 Error SyntaxError: A parameter initializer is only allowed in a function or constructor implementation. */ +/* @@@ label2 Error SyntaxError: A parameter initializer is only allowed in a function or constructor implementation. */ diff --git a/ets2panda/test/ast/compiler/ets/default_test/export_default.ets b/ets2panda/test/ast/compiler/ets/default_test/export_default.ets new file mode 100644 index 0000000000000000000000000000000000000000..6bc32fae02eba6627bd2f4189efe545c620c0f2d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/default_test/export_default.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. + */ + +const val = 100; +export { val as default }; + +export { default } from '.'; + +/* @@? 19:8 Error TypeError: Only one default export is allowed in a module */ +/* @@? 19:18 Error SyntaxError: Unexpected token, expected 'as'. */ +/* @@? 19:18 Error SyntaxError: Unexpected token '}'. */ +/* @@? 19:20 Error SyntaxError: Cannot find name 'from' to export. */ +/* @@? 19:20 Error SyntaxError: Cannot find name 'gensym%%_anonymous_const' to export. */ +/* @@? 19:25 Error SyntaxError: Unexpected token, expected ',' or '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/default_type_circular_dependency.ets b/ets2panda/test/ast/compiler/ets/default_type_circular_dependency.ets new file mode 100644 index 0000000000000000000000000000000000000000..973142e608fa841101956aa3d71627bd596646eb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/default_type_circular_dependency.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 Racer { + stat; +} + +/* @@? 17:9 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:16 Error TypeError: Default type of type parameter has circular dependency. */ +/* @@? 17:22 Error TypeError: 'f' type does not exist. */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 17:24 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 17:25 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:25 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:25 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:25 Error SyntaxError: Unexpected token '>'. */ diff --git a/ets2panda/test/ast/compiler/ets/deleteOperator_n.ets b/ets2panda/test/ast/compiler/ets/deleteOperator_n.ets new file mode 100644 index 0000000000000000000000000000000000000000..b426389b4b18e33ae46f4ff9f69ac2657cad1b2b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/deleteOperator_n.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 Point { + x?: number = 0.0 + y?: number = 0.0 +} +let p = new Point() +delete p.y + +/* @@? 21:1 Error TypeError: Types cannot be modified at runtime with 'delete'. */ +/* @@? 21:8 Error SyntaxError: Unexpected token 'p'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/division-by-zero.ets b/ets2panda/test/ast/compiler/ets/division-by-zero.ets new file mode 100644 index 0000000000000000000000000000000000000000..85b5646d7379a7b59dfce0302410fec31e18c792 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/division-by-zero.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 main() : void { + let div_int : int = /* @@ label1 */1 / 0; + let div_long: long = /* @@ label2 */1 / 0; + let mod_int : int = /* @@ label3 */1 % 0; + let mod_long: long = /* @@ label4 */1 % 0; +} + +/* @@@ label1 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label2 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label3 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label4 Error SyntaxError: Division by zero is not allowed. */ diff --git a/ets2panda/test/ast/compiler/ets/double_then.ets b/ets2panda/test/ast/compiler/ets/double_then.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f5ee761e87d49676d7d8d757542a533a768493d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/double_then.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. + */ + +const asyncFunction = async () => { + return Promise.resolve(1.0) +}; + +async function main() { + const result : number = await asyncFunction() + .then((result) => { + return Promise.resolve(result + 2.0) + }) + .then((result) => { + return Promise.resolve(result + 3.0) + }) +} \ No newline at end of file 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..ad2a27ac6c01065f51dfdc606850ad286339e0cc --- /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: Object type doesn't have proper index access method. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/emptyOptionalTypeAnnotation.ets b/ets2panda/test/ast/compiler/ets/emptyOptionalTypeAnnotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..09828e793277d00ece590dd6d438a2dd971ec0b9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/emptyOptionalTypeAnnotation.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 Dep { + someMethod?; +} + +class Src implements Dep { + someMethod? +} + +/* @@? 17:14 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 18:1 Error SyntaxError: Invalid Type. */ +/* @@? 21:14 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/compiler/ets/empty_array_expression.ets b/ets2panda/test/ast/compiler/ets/empty_array_expression.ets new file mode 100644 index 0000000000000000000000000000000000000000..ea4da1ee58457a7dcc19febe4c36a1db766ecc03 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/empty_array_expression.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. + */ + +let var1 = /* @@ label1 */[]; +const con1 = /* @@ label2 */[]; + +function foo(){ + let var2 = /* @@ label3 */[]; + const con2 = /* @@ label4 */[]; +} + +class A{ + prop1 = /* @@ label5 */[]; + static prop1 = /* @@ label6 */[]; + foo(){ + let var3 = /* @@ label7 */[]; + const con3 = /* @@ label8 */[]; + } +} + +/* @@@ label1 Error TypeError: Can't resolve array type */ +/* @@@ label2 Error TypeError: Can't resolve array type */ +/* @@@ label3 Error TypeError: Can't resolve array type */ +/* @@@ label4 Error TypeError: Can't resolve array type */ +/* @@@ label5 Error TypeError: Can't resolve array type */ +/* @@@ label6 Error TypeError: Can't resolve array type */ +/* @@@ label7 Error TypeError: Can't resolve array type */ +/* @@@ label8 Error TypeError: Can't resolve array type */ diff --git a/ets2panda/test/ast/compiler/ets/empty_tuple_assignmemt.ets b/ets2panda/test/ast/compiler/ets/empty_tuple_assignmemt.ets new file mode 100644 index 0000000000000000000000000000000000000000..80163182816856e82a7c3e58a536d9d9e106ee05 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/empty_tuple_assignmemt.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 tuple: [string,number] = /* @@ label */[] + +/* @@@ label Error TypeError: Initializer has 0 elements, but tuple requires 2 */ 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-to-int-conversion.ets b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets index ace31b83f7dc7eeafb143d67e0ae082d75b6e275..6ee37e69b89d0af965dc5812b0b605d05995ce22 100644 --- a/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets +++ b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets @@ -18,6 +18,6 @@ SECOND = 12345678910 } - let a: int = /* @@ label */E.FIRST + let a: int = E.FIRST - /* @@@ label Error TypeError: Type 'long' cannot be assigned to type 'int' */ \ No newline at end of file + /* @@? 16:2 Error TypeError: Type 'Long' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/enumConversions.ets b/ets2panda/test/ast/compiler/ets/enumConversions.ets new file mode 100644 index 0000000000000000000000000000000000000000..353ca83e8fccc42181af47b2b18dd800dfbe3530 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/enumConversions.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum E { + a, b, c +} + +enum EE { + a, b, c, d, e +} + +function foo(e: E, i: int) { +// i = e // OK if widening, otherwise - CTE + i = e as int // CTE +// e = i // CTE + e = 1 as E // CTE +// e = E.fromValue(i) // RTE, if i is not equal to one of enum constants, otherwise OK +// e = 1 // OK, 1 can be E.b +// e = 10 // CTE, 10 is out of range +} + +/* @@? 26:7 Warning Warning: Enum cast is deprecated. Cast support from 'E' to 'Int' will be removed. */ +/* @@? 28:7 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'E' will be removed. */ diff --git a/ets2panda/test/ast/compiler/ets/enum_as_type_alias.ets b/ets2panda/test/ast/compiler/ets/enum_as_type_alias.ets index cf2e08b678751dc449e0f00f831fad06f3a351a0..a8c78814b9f73d79044686165f9e77f8c45a8f0b 100644 --- a/ets2panda/test/ast/compiler/ets/enum_as_type_alias.ets +++ b/ets2panda/test/ast/compiler/ets/enum_as_type_alias.ets @@ -19,6 +19,6 @@ type BaseColor = Color; function main(): void { let a: Color = Color.Red; // OK let v: int = BaseColor.Red; - assertEQ(v, 0); + arktest.assertEQ(v, 0); } diff --git a/ets2panda/test/runtime/ets/constant_char.ets b/ets2panda/test/ast/compiler/ets/enum_expressions/constant_char.ets similarity index 76% rename from ets2panda/test/runtime/ets/constant_char.ets rename to ets2panda/test/ast/compiler/ets/enum_expressions/constant_char.ets index 0fcb260555b8bd97fab6d20cfe787cdd4f19640d..ad4d7a36a4e3dfab9b142fbec3163170befd38d7 100644 --- a/ets2panda/test/runtime/ets/constant_char.ets +++ b/ets2panda/test/ast/compiler/ets/enum_expressions/constant_char.ets @@ -18,6 +18,9 @@ const constchar: char = constbyte function main() { enum TestEnum { One = constchar } - assertEQ(constchar,101) - assertEQ(TestEnum.One.valueOf(),101) + arktest.assertEQ(constchar,101) + arktest.assertEQ(TestEnum.One.valueOf(),101) } + +/* @@? 20:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 22:22 Error TypeError: Unresolved reference TestEnum */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/enum_expressions/constant_char_asexpression.ets b/ets2panda/test/ast/compiler/ets/enum_expressions/constant_char_asexpression.ets new file mode 100644 index 0000000000000000000000000000000000000000..13c418b307e5541398772a9259df1b25c0b6b96c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/enum_expressions/constant_char_asexpression.ets @@ -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. + */ + +const constchar: char = c'p' + +function main() { + const constcharToByte = constchar as byte + arktest.assertEQ(constcharToByte ,112) + enum TestEnum1 { One = constcharToByte } + arktest.assertEQ(TestEnum1.One.valueOf(),112) + + const constcharToShort = constchar as short + arktest.assertEQ(constcharToShort ,112) + enum TestEnum2 { One = constcharToShort } + arktest.assertEQ(TestEnum2.One.valueOf(),112) + + const constcharToInt = constchar as int + arktest.assertEQ(constcharToInt ,112) + enum TestEnum3 { One = constcharToInt } + arktest.assertEQ(TestEnum3.One.valueOf(),112) + + const constcharToLong = constchar as long + arktest.assertEQ(constcharToLong ,112) + enum TestEnum4 { One = constcharToLong } + arktest.assertEQ(TestEnum4.One.valueOf(),112) +} + + +/* @@? 19:29 Error TypeError: Cannot cast type 'Char' to 'Byte' */ +/* @@? 21:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 22:22 Error TypeError: Unresolved reference TestEnum1 */ +/* @@? 24:30 Error TypeError: Cannot cast type 'Char' to 'Short' */ +/* @@? 26:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 27:22 Error TypeError: Unresolved reference TestEnum2 */ +/* @@? 29:28 Error TypeError: Cannot cast type 'Char' to 'Int' */ +/* @@? 31:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 32:22 Error TypeError: Unresolved reference TestEnum3 */ +/* @@? 34:29 Error TypeError: Cannot cast type 'Char' to 'Long' */ +/* @@? 36:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 37:22 Error TypeError: Unresolved reference TestEnum4 */ diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-enum1.ets b/ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum1.ets similarity index 89% rename from ets2panda/test/runtime/ets/enum-initialize-with-enum1.ets rename to ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum1.ets index 9334c5a9582e574f34d8186401b824f5c08c01a2..66635871aa243ffd00fb095376139ebb1b930a2d 100644 --- a/ets2panda/test/runtime/ets/enum-initialize-with-enum1.ets +++ b/ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum1.ets @@ -16,5 +16,5 @@ enum Color { Red, Green = 3, Blue } enum Color2 { a = Color.Red, b = Color.Green} -assertEQ(Color2.a.valueOf(), 0) -assertEQ(Color2.b.valueOf(), 3) \ No newline at end of file +arktest.assertEQ(Color2.a.valueOf(), 0) +arktest.assertEQ(Color2.b.valueOf(), 3) diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-enum2.ets b/ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum2.ets similarity index 85% rename from ets2panda/test/runtime/ets/enum-initialize-with-enum2.ets rename to ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum2.ets index 16af540515eff9f94ac304860bb52b4e5d17ee66..3871cb9f5dafd0690455d357c2fe5a7be82d3967 100644 --- a/ets2panda/test/runtime/ets/enum-initialize-with-enum2.ets +++ b/ets2panda/test/ast/compiler/ets/enum_expressions/enum-initialize-with-enum2.ets @@ -18,6 +18,6 @@ enum Color2 { Red = Color.Red } enum Color3 { Red = Color2.Red } enum Color4 { Red = Color3.Red } -assertEQ(Color2.Red.valueOf(), 0) -assertEQ(Color3.Red.valueOf(), 0) -assertEQ(Color4.Red.valueOf(), 0) +arktest.assertEQ(Color2.Red.valueOf(), 0) +arktest.assertEQ(Color3.Red.valueOf(), 0) +arktest.assertEQ(Color4.Red.valueOf(), 0) 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/etsObjectToString0.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets index a04bb52e2b0fa9094531ab65ceafca4b9340460f..724f1b214d7440fb7cb51be7ce9d6102d2e0641b 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets @@ -20,4 +20,4 @@ function test(): int{ return /* @@ label */a; } -/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets index e5873018c872a9f1a2c8afdffb4fac0bd273c62d..d46422e571e83bd1d6a6a6335152a6ef889af3e1 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets @@ -17,4 +17,4 @@ class A{} let f: (() => int) | null = /* @@ label */5; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int|null' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int|null' */ diff --git a/ets2panda/test/ast/compiler/ets/explicit_cast_boxed_expressions.ets b/ets2panda/test/ast/compiler/ets/explicit_cast_boxed_expressions.ets index 45197e365f80ad1988b6fc601eff33d772cf3e6a..52fee19f867d7d415f954443a1d2ca41b962055b 100644 --- a/ets2panda/test/ast/compiler/ets/explicit_cast_boxed_expressions.ets +++ b/ets2panda/test/ast/compiler/ets/explicit_cast_boxed_expressions.ets @@ -25,12 +25,12 @@ let testLongValue: Long = 9223372036854775807; function byte_test(): boolean { let Byte_: Byte = new Byte(42 as byte); // ? - let byte_short = Byte_ as Short; // ? - let byte_int = Byte_ as Int; // ? - let byte_long = Byte_ as Long; // ok - let byte_float = Byte_ as Float; // ok - let byte_double = Byte_ as Double; // ok - let byte_char = Byte_ as Char; // ok + let byte_short = Byte.toShort(Byte_); // ? + let byte_int = Byte.toInt(Byte_); // ? + let byte_long = Byte.toLong(Byte_); // ok + let byte_float = Byte.toFloat(Byte_); // ok + let byte_double = Byte.toDouble(Byte_); // ok + let byte_char = Byte.toChar(Byte_); // ok // true test Type speciefic operations { @@ -57,13 +57,13 @@ function short_test(): boolean { let Short_: Short = new Short(42 as short); - let short_byte = Short_ as Byte; - let short_short = Short_ as Short; - let short_char = Short_ as Char; - let short_int = Short_ as Int; - let short_long = Short_ as Long; - let short_float = Short_ as Float; - let short_double = Short_ as Double; + let short_byte = Short.toByte(Short_); + let short_short = Short.toShort(Short_); + let short_char = Short.toChar(Short_); + let short_int = Short.toInt(Short_); + let short_long = Short.toLong(Short_); + let short_float = Short.toFloat(Short_); + let short_double = Short.toDouble(Short_); // true test Type speciefic operations @@ -90,13 +90,13 @@ function short_test(): boolean { function char_test(): boolean { let Char_: Char = new Char(42 as char); - let char_byte = Char_ as Byte; - let char_short = Char_ as Short; - let char_char = Char_ as Char; - let char_int = Char_ as Int; - let char_long = Char_ as Long; - let char_float = Char_ as Float; - let char_double = Char_ as Double; + let char_byte = Char.toByte(Char_); + let char_short = Char.toShort(Char_); + let char_char = Char.toChar(Char_); + let char_int = Char.toInt(Char_); + let char_long = Char.toLong(Char_); + let char_float = Char.toFloat(Char_); + let char_double = Char.toDouble(Char_); // true test Type speciefic operations { @@ -123,13 +123,13 @@ function int_test(): boolean { let Int_: Int = new Int(42 as int); - let int_byte = Int_ as Byte; - let int_short = Int_ as Short; - let int_char = Int_ as Char; - let int_int = Int_ as Int; - let int_long = Int_ as Long; - let int_float = Int_ as Float; - let int_double = Int_ as Double; + let int_byte = Int.toByte(Int_); + let int_short = Int.toShort(Int_); + let int_char = Int.toChar(Int_); + let int_int = Int.toInt(Int_); + let int_long = Int.toLong(Int_); + let int_float = Int.toFloat(Int_); + let int_double = Int.toDouble(Int_); // true test Type speciefic operations { @@ -155,13 +155,13 @@ function int_test(): boolean { function long_test(): boolean { let Long_: Long = new Long(42 as long); - let long_byte = Long_ as Byte; - let long_short = Long_ as Short; - let long_char = Long_ as Char; - let long_int = Long_ as Int; - let long_long = Long_ as Long; - let long_float = Long_ as Float; - let long_double = Long_ as Double; + let long_byte = Long.toByte(Long_); + let long_short = Long.toShort(Long_); + let long_char = Long.toChar(Long_); + let long_int = Long.toInt(Long_); + let long_long = Long.toLong(Long_); + let long_float = Long.toFloat(Long_); + let long_double = Long.toDouble(Long_); // true test Type speciefic operations { @@ -187,21 +187,17 @@ function long_test(): boolean { function float_test(): boolean { let Float_: Float = new Float(42 as float); - let float_byte = Float_ as Byte; - let float_short = Float_ as Short; - let float_char = Float_ as Char; - let float_int = Float_ as Int; - let float_long = Float_ as Long; - let float_float = Float_ as Float; - let float_double = Float_ as Double; + let float_byte = Float.toByte(Float_); + let float_short = Float.toShort(Float_); + let float_int = Float.toInt(Float_); + let float_long = Float.toLong(Float_); + let float_float = Float.toFloat(Float_); + let float_double = Float.toDouble(Float_); // true test Type speciefic operations { if (float_double.toExponential() != testDouble.toExponential()) { return false; } - if (float_char != testChar || float_char.isBinDigit() != testChar.isBinDigit()) { - return false; - } if (float_float != testFloat || float_float.isNaN() != testFloat.isNaN()) { // better to find another way of checking return false; } @@ -218,21 +214,17 @@ function float_test(): boolean { function double_test(): boolean { let Double_: Double = new Double(42 as double); - let double_byte = Double_ as Byte; - let double_short = Double_ as Short; - let double_char = Double_ as Char; - let double_int = Double_ as Int; - let double_long = Double_ as Long; - let double_float = Double_ as Float; - let double_double = Double_ as Double; + let double_byte = Double.toByte(Double_); + let double_short = Double.toShort(Double_); + let double_int = Double.toInt(Double_); + let double_long = Double.toLong(Double_); + let double_float = Double.toFloat(Double_); + let double_double = Double.toDouble(Double_); // true test Type speciefic operations { if (double_double.toExponential() != testDouble.toExponential()) { return false; } - if (double_char != testChar || double_char.isBinDigit() != testChar.isBinDigit()) { - return false; - } if (double_float != testFloat || double_float.isNaN() != testFloat.isNaN()) { // better to find another way of checking return false; } 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..ba28d7a7b82c333c15592100bf24415f65acfd2e 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 @@ -15,5 +15,3 @@ export class A {} export type {/* @@ label */A} - -/* @@@ label Error SyntaxError: Name 'A' cannot be exported and type exported at the same time. */ 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..201b28a8dde1d91067b5c91d203a8a1ea6e5c548 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 @@ -15,5 +15,3 @@ export interface I {} export type {/* @@ label */I} - -/* @@@ label Error SyntaxError: Name 'I' cannot be exported and type exported at the same time. */ 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..206cbcabbfdbe33e05b1b534c2dc0b1caa60e063 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 @@ -15,6 +15,3 @@ export type class A {} export type {/* @@ label */A} - - -/* @@@ label Error SyntaxError: Cannot export the same 'A' type twice. */ 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..4a2147118c7545d83f849190cc7f84a2319c0ff6 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,6 @@ 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. */ +/* @@? 16:1 Warning Warning: Duplicated export aliases for 'MyA'. */ 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..c714b60e24ca21ee91891a307510645039df3154 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,4 @@ interface I {} export type {I} export type MyI = I -export type {/* @@ label */MyI} - -/* @@@ label Error SyntaxError: Cannot export the same 'MyI' type twice. */ +export type {MyI} 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..c97f4b9e8bd55821c387088c424708f347e28755 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ 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. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label 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..c97f4b9e8bd55821c387088c424708f347e28755 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ 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. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label 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_crash.ets b/ets2panda/test/ast/compiler/ets/extension_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..4cea736a025dceffd04c645e0d6f52efe5ac0157 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/extension_crash.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(this.data); +} + +function foo(this: A) { +} + +/* @@? 17:8 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:13 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:13 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:13 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:18 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:18 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_class_lambda_member.ets b/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_class_lambda_member.ets new file mode 100644 index 0000000000000000000000000000000000000000..1b1404916bb6b4cb2d3cf0efdd11b001a5fdc74c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_class_lambda_member.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{ + b : String = "b" + foo : () => String +}; + +function foo(this:A)/* @@ label */{ + return this.b; +} + +let a = new A; +a.foo = foo; +console.log(a.foo()) + +/* @@@ label Error TypeError: The extension accessor or extension function 'foo' has the same name with field of class A */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_interface_lambda_member.ets b/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_interface_lambda_member.ets new file mode 100644 index 0000000000000000000000000000000000000000..266caefbf3f1dad8948360cf5b2f97befc7f9cf1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/extension_function_duplicated_with_interface_lambda_member.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. + */ + +interface A{ + b : String + foo : () => String +}; + +function foo(this:A)/* @@ label */{ + return this.b; +} + +let a:A = { + b: "a", + foo : /* @@ label1 */foo +}; +console.log(a.foo()) + +/* @@@ label Error TypeError: The extension function 'foo' has the same name with public method in class A */ +/* @@@ label1 Error TypeError: Type '(=t: A) => String' is not compatible with type '() => String' at property 'foo' */ 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_access_protected_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets index c3060b1928af65d338bcbc7cf40031eb5bdff8ca..6e0fe6102ba6c100c9cc404be687b10ab0229f5a 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets @@ -28,5 +28,5 @@ function main() { console.println(banana.name()); } -/* @@@ label Error TypeError: Signature price(): int is not visible here. */ +/* @@@ label Error TypeError: Signature price(): Int is not visible here. */ /* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets index cdfab182246da5b8a31cb9442d719e9ecfe4c4ff..fb813f1d3110289c1581766bc3c9c27474136d26 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets @@ -27,4 +27,12 @@ function main() { console.println(A./* @@ label */price(1)); } -/* @@@ label Error TypeError: Property 'price' does not exist on type 'A' */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Boolean): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Byte): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Short): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Char): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Int): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Long): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Float): void` */ +/* @@? 27:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Double): void` */ +/* @@@ label Error TypeError: Property 'price' does not exist on type 'A' */ 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..ab7af4dedc648f10e40eeb7470aa87f5893db382 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,12 @@ function main() { console.println(/* @@label */banana.name(2)); } -/* @@@ label Error TypeError: No matching call signature for name(int) */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Boolean): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Byte): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Short): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Char): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Int): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Long): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Float): void` */ +/* @@? 28:5 Error TypeError: Call to `println` is ambiguous as `2` versions of `println` are available: `println(i: String): void` and `println(i: Double): void` */ +/* @@? 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..2e8df50de75c6d2e9be2a1cf3f35aeb6928983a3 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 @@ -40,5 +40,5 @@ function main() { } /* @@? 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: 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_primitive.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_primitive.ets index 131c49af3d2f73bab1c5e2b7011f1a3ee3996575..ec9bcf5d7502b27c66571371980efc212a35a015 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_primitive.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_primitive.ets @@ -17,4 +17,4 @@ return 1.2; } -/* @@@ label Error TypeError: Extension function can only defined for class, interface or array. */ +/* @@? 16:52 Error TypeError: The extension accessor or extension function 'value' has the same name with field of class Double */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets index b41dbe9f8833c9924f26be2313e38262baa0cc7a..1c4439bcc7136a7c2c98de302d7c8cc9dc7e5163 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets @@ -21,4 +21,4 @@ function foo(this: B): this { return /* @@ label */2; } -/* @@@ label Error TypeError: Type 'int' is not compatible with the enclosing method's return type 'B' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with the enclosing method's return type 'B' */ 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 b3862bbc5b40a61ebf6aa81c99749ab49c50be92..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,5 +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. */ -/* @@? 19:37 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 '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/first_match/abstract_method.ets b/ets2panda/test/ast/compiler/ets/first_match/abstract_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..2178322e65317b0220380a30f75519977a86a9a3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/abstract_method.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. + */ + +abstract class Base { + abstract fooNumber(a: number): string; + abstract fooString(a: string): string; + overload foo {fooNumber,fooString } +} diff --git a/ets2panda/test/ast/compiler/ets/first_match/access_modifiers.ets b/ets2panda/test/ast/compiler/ets/first_match/access_modifiers.ets new file mode 100644 index 0000000000000000000000000000000000000000..c816d682626151701aeac2501698df44ec97e12b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/access_modifiers.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. + */ + +class Base { + private fooPrivate(x: string) {} + protected fooProtected(x: number) {} + public fooPublic(x: boolean) {} + + overload foo{ fooPrivate, fooProtected, fooPublic } + + bar(){ + this.foo("abc"); + this.foo(1); + this.foo(true); + } +} + +class Sub extends Base { + bar() { + /* @@ label */this.foo(/* @@ label1 */"abc"); + this.foo(1); + this.foo(true); + } +} + +function main() { + let a = new Base(); + /* @@ label2 */a.foo("abc"); + /* @@ label3 */a.foo(1); + a.foo(true); +} + +/* @@@ label Error TypeError: Signature fooPrivate(x: String): void is not visible here. */ +/* @@@ label Error TypeError: No matching call signature for foo("abc") */ +/* @@@ label2 Error TypeError: Signature fooPrivate(x: String): void is not visible here. */ +/* @@@ label2 Error TypeError: No matching call signature for foo("abc") */ +/* @@@ label3 Error TypeError: Signature fooProtected(x: Double): void is not visible here. */ +/* @@@ label3 Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/access_modifiers_2.ets b/ets2panda/test/ast/compiler/ets/first_match/access_modifiers_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c7362de2245e6567c2d738861290c1a56f1483f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/access_modifiers_2.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 Test1 { + foo1(a: number) { } + foo2(a: string) { } + native overload foo{ foo1, foo2 } +} + +class Test2 { + foo1(a: number) { } + foo2(a: string) { } + readonly overload foo{ foo1, foo2 } +} + +class Test3 { + foo1(a: number) { } + foo2(a: string) { } + abstract overload foo{ foo1, foo2 } +} + +/* @@? 19:21 Error SyntaxError: Overload Declaration only allow use modifier 'static' | 'async'. */ +/* @@? 25:23 Error SyntaxError: Overload Declaration only allow use modifier 'static' | 'async'. */ +/* @@? 31:23 Error SyntaxError: Overload Declaration only allow use modifier 'static' | 'async'. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/arrayliteral.ets b/ets2panda/test/ast/compiler/ets/first_match/arrayliteral.ets new file mode 100644 index 0000000000000000000000000000000000000000..7e8ca5089a1f6d1ff8b825c7f5fd432b68120dad --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/arrayliteral.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 Test{ + foo1(a:[string,string,string]){ + console.log("invoke1") + } + foo2(a:[number,string,boolean]){ + console.log("invoke2") + } + foo3(a:number[]){ + console.log("invoke3") + } + + overload foo111{foo1,foo2,foo3} +} + +function main(){ + let a:Test = new Test(); + a.foo111(["abc","abc",1]); + a.foo111(["abc","abc",true]); + a.foo111([123,"abc",true]); + a.foo111([123,123,123]); +} + +/* @@? 32:5 Error TypeError: No matching call signature for foo111(Array) */ +/* @@? 33:5 Error TypeError: No matching call signature for foo111(Array) */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/constructor.ets b/ets2panda/test/ast/compiler/ets/first_match/constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..db1517374ca74696a0a2f24ee0220c9095ff0a55 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/constructor.ets @@ -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. + */ + +class Test1{ + constructor(a?:number,b?:number){} + constructor con1(){} + overload constructor{con1} +} + +class Test2{ + constructor(a:number,b:number){} + constructor con1(){} + overload constructor{con1} +} + +class Test3{ + constructor(a:number,...args:[string,number]){} + constructor con1(){} + overload constructor{con1} +} + +class Test4{ + constructor(a?:number,b?:number){} + constructor(a:string){} + constructor con1(){} + /* @@ label1 */constructor con1(){} + /* @@ label2 */overload constructor{con1} +} + +class Test5{ + constructor(a:number,...args:[string,number]){} + constructor(a:string){} + constructor con1(){} + /* @@ label3 */overload constructor{con1} +} + +/* @@@ label1 Error TypeError: Function con1 is already declared. */ +/* @@@ label2 Error TypeError: The overloaded name 'constructor' can't refer to a function with overload signatures. */ +/* @@@ label2 Error TypeError: The overloaded name 'con1' can't refer to a function with overload signatures. */ +/* @@@ label3 Error TypeError: The overloaded name 'constructor' can't refer to a function with overload signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/declare_class.ets b/ets2panda/test/ast/compiler/ets/first_match/declare_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..fa5734b298d462a38e3a908e206699a4b7377410 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/declare_class.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 { + overload on{ on1, on2 } + on1(a: string): void + on2(a: number): void +} diff --git a/ets2panda/test/ast/compiler/ets/first_match/function_same_name.ets b/ets2panda/test/ast/compiler/ets/first_match/function_same_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5face17f5371fa11faa01e0cd196a3f7e2095c3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/function_same_name.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. + */ + +namespace NS{ + export function foo(a:number){} + export function foo2(a:string){} + export overload /* @@ label */foo{foo2} +} + +function foo(a:number){} +function foo2(a:string){} +overload /* @@ label2 */foo{foo2} + +/* @@@ label Error TypeError: Method with the same name as overload declaration 'foo', overloadlist must list this medhod. */ +/* @@@ label2 Error TypeError: Method with the same name as overload declaration 'foo', overloadlist must list this medhod. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f7d7c607a85577679c28294c606616c275fd2bf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration.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 Test { + foo1(a: number) { } + foo2(a: string) { } + overload: foo{ foo1, foo2 } +} + +/* @@? 19:13 Error SyntaxError: Identifier expected, got ':'. */ +/* @@? 19:15 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 19:15 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:15 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 19:18 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 19:18 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:20 Error TypeError: Variable 'foo1' has already been declared. */ +/* @@? 19:24 Error SyntaxError: Field type annotation expected. */ +/* @@? 19:24 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:26 Error TypeError: Variable 'foo2' has already been declared. */ +/* @@? 19:30 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_2.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..63be2fcf48790b11a0eb23f8056c5cee1ca5c633 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_2.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 { + foo1(a: number) { } + foo2(a: string) { } + overload foo(foo1, foo2) +} + +/* @@? 19:17 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 19:17 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:17 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 19:18 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 19:18 Error TypeError: Variable 'foo1' has already been declared. */ +/* @@? 19:22 Error SyntaxError: Field type annotation expected. */ +/* @@? 19:22 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:24 Error TypeError: Variable 'foo2' has already been declared. */ +/* @@? 19:28 Error SyntaxError: Field type annotation expected. */ +/* @@? 19:28 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_3.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..c6e43822e8d77df970144d830f523080f05d6f14 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_3.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Base { + foo1(a: number) { } + foo2(a: string) { } + overload { foo1, foo2 } +} + +/* @@? 19:14 Error SyntaxError: Identifier expected, got '{'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:16 Error TypeError: overloaded name must refer to an accessible method. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_4.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..a3d50ec7214d0ffbb10cea7b76db16d26ad94391 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_4.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 Base { + foo1(a: number) { } + foo2(a: string) { } + overload foo{ fo, fo2 } +} + +/* @@? 19:19 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 19:23 Error TypeError: overloaded name must refer to an accessible method. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..c7a80816f02fbb0dec419f0ca02691fb0e1239bb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declaration_5.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. + */ + +overload foo{ foo.,T,} + +/* @@? 16:19 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:19 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 16:20 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 16:20 Error TypeError: Unresolved reference T */ +/* @@? 16:21 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:22 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.ets new file mode 100644 index 0000000000000000000000000000000000000000..090aa4c25a1bed2ae8e7fdd14100942d82869e32 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare.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. + */ + +overload * you thMMMMMMMMdSTICKER, + +/* @@? 16:10 Error SyntaxError: Identifier expected, got '*'. */ +/* @@? 16:12 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 16:12 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:12 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 16:16 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 16:16 Error TypeError: Unresolved reference thMMMMMMMMdSTICKER */ +/* @@? 16:34 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_declare2.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a9f652b9de1bfb071691c24e84caf55b313d6842 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_declare2.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{ + overload * you thMMMMMMMMdSTICKER, +} + +/* @@? 17:14 Error SyntaxError: Identifier expected, got '*'. */ +/* @@? 17:16 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 17:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:16 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 17:38 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:38 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..597ad29e1a5d28de16e8d6f818b30dbc7bc1b145 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_identifier.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. + */ + +class Test{ + foo1(a:[string,string,string]){ + console.log("invoke1") + } + + overload foo111(foo1,foo2,foo3){} //syntaxError, do not crash + overload foo112(foo1,foo2) //syntaxError, do not crash +} + +function main(){ + let a:Test = new Test(); + a.foo111(["abc","abc",1]); +} + +/* @@? 21:20 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 21:20 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 21:20 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 21:21 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 21:21 Error TypeError: Variable 'foo1' has already been declared. */ +/* @@? 21:25 Error SyntaxError: Unexpected token ','. */ +/* @@? 21:25 Error SyntaxError: Field type annotation expected. */ +/* @@? 21:30 Error SyntaxError: Field type annotation expected. */ +/* @@? 21:30 Error SyntaxError: Unexpected token ','. */ +/* @@? 21:35 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:35 Error SyntaxError: Field type annotation expected. */ +/* @@? 21:36 Error SyntaxError: Unexpected token '{'. */ +/* @@? 22:20 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 22:20 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 22:20 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 22:21 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 22:21 Error TypeError: Unresolved reference foo1 */ +/* @@? 22:25 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:26 Error SyntaxError: Unexpected token 'foo2'. */ +/* @@? 22:26 Error TypeError: Unresolved reference foo2 */ +/* @@? 22:30 Error SyntaxError: Unexpected token ')'. */ +/* @@? 23:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/invalid_paramter.ets b/ets2panda/test/ast/compiler/ets/first_match/invalid_paramter.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e6faafbe0955c7fe3ed9eeb4ce616870c9db287 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/invalid_paramter.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 {} +class B {} + +class Test { + foo1(a?: A,) { + console.log("invoke1") + } + foo2(a?: A, b?: B) { + console.log("invoke2") + } + + overload foo111{ foo1, foo2, foo3, foo4 } +} + +function main() { + let a: Test = new Test(); + a.foo111(new A(), new A()) + a.foo111(new A(), new A(), new A()) +} + +/* @@? 27:34 Error TypeError: overloaded name must refer to an accessible method. */ +/* @@? 27:40 Error TypeError: overloaded name must refer to an accessible method. */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/modifier_async.ets b/ets2panda/test/ast/compiler/ets/first_match/modifier_async.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c3ba11c80c11863e6ae394b6dba3be9ffcb303f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/modifier_async.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 Base1 { + async fooNumber(a: number): Promise {} + fooString(a: string): void {} + overload foo {/* @@ label1 */fooNumber, fooString } +} + +class Base2 { + async fooNumber(a: number): Promise {} + fooString(a: string): void {} + async overload foo {fooNumber, /* @@ label2 */fooString } +} + +/* @@@ label1 Error TypeError: Overload alias and overloaded method name must have exactly the same modifiers (static, async). */ +/* @@@ label2 Error TypeError: Overload alias and overloaded method name must have exactly the same modifiers (static, async). */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/modifier_static.ets b/ets2panda/test/ast/compiler/ets/first_match/modifier_static.ets new file mode 100644 index 0000000000000000000000000000000000000000..28ab388f03bf34d17247229e6183ef07e8f07fa6 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/modifier_static.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 Base1 { + static fooNumber(a: number): void {} + fooString(a: string): void {} + overload foo {/* @@ label1 */fooNumber, fooString } +} + +class Base2 { + static fooNumber(a: number): void {} + fooString(a: string): void {} + static overload foo {fooNumber, /* @@ label2 */fooString } +} + +/* @@@ label1 Error TypeError: Overload alias and overloaded method name must have exactly the same modifiers (static, async). */ +/* @@@ label1 Error TypeError: Static property 'fooNumber' must be accessed through it's class 'Base1' */ +/* @@@ label2 Error TypeError: Overload alias and overloaded method name must have exactly the same modifiers (static, async). */ +/* @@@ label2 Error TypeError: Property 'fooString' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/namespace.ets b/ets2panda/test/ast/compiler/ets/first_match/namespace.ets new file mode 100644 index 0000000000000000000000000000000000000000..562555e43fd2f058a7686cb22849741a9e8b7c6c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/namespace.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. + */ + +namespace NS { + function foo1(a: number) { + console.log("invoke foo1"); + } + + function foo2(a: string) { + console.log("invoke foo2"); + } + + export overload overloadfoo{ foo1, foo2 } + + export function foo3(a: number) { + console.log("invoke foo1"); + } + + function foo4(a: string) { + console.log("invoke foo2"); + } + + export overload overloadfoo2{ foo3, foo4 } + + export function foo5(a: number) { + console.log("invoke foo1"); + } + + function foo6(a: string) { + console.log("invoke foo2"); + } + + overload overloadfoo3{ foo5, foo6 } +} + +function main(){ + NS.foo1(1); + NS.foo2("abc"); + NS.foo3(1); + NS.foo4("abc"); + + NS.overloadfoo(1); + NS.overloadfoo("abc"); + + NS.overloadfoo2(1); + NS.overloadfoo2("abc"); + + NS.overloadfoo3(1); + NS.overloadfoo3("abc"); +} + +/* @@? 49:8 Error TypeError: 'foo1' is not exported in 'NS' */ +/* @@? 50:8 Error TypeError: 'foo2' is not exported in 'NS' */ +/* @@? 52:8 Error TypeError: 'foo4' is not exported in 'NS' */ +/* @@? 54:5 Error TypeError: 'foo1' is not exported in 'NS' */ +/* @@? 55:5 Error TypeError: 'foo2' is not exported in 'NS' */ +/* @@? 58:5 Error TypeError: 'foo4' is not exported in 'NS' */ +/* @@? 60:8 Error TypeError: 'overloadfoo3' is not exported in 'NS' */ +/* @@? 61:5 Error TypeError: 'foo6' is not exported in 'NS' */ +/* @@? 61:8 Error TypeError: 'overloadfoo3' is not exported in 'NS' */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/override.ets b/ets2panda/test/ast/compiler/ets/first_match/override.ets new file mode 100644 index 0000000000000000000000000000000000000000..2bb8873b99c8a87f93037886e0143eae01387a02 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/override.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 Base{ + overload foo {fooNumber,fooString} + fooNumber(a:number):string{ + return "invoke1"; + } + fooString(a:string):string{ + return "invoke2"; + } +} + +class Sub1 extends Base{ + override fooNumber(a:number):string{ + return "invoke3"; + } +} + +class Sub2 extends Base{ + fooInt(a:int):string{ + return "invoke4"; + } + overload foo{fooInt,fooNumber} +} + +/* @@? 32:20 Error TypeError: Cannot inherit from class Base, because overload foo is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/first_match/same_name.ets b/ets2panda/test/ast/compiler/ets/first_match/same_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..22a1f98fa777f615d63f25ca9ba53a77e5afcc65 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/first_match/same_name.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 C{ + foo(n:number){} + fooString(n:string){} + fooBoolean(n:boolean){} + + overload foo{foo,fooString,fooBoolean} +} + +class D{ + foo(n:number){} + fooString(n:string){} + fooBoolean(n:boolean){} + + overload foo{fooString,fooBoolean} +} + +/* @@? 29:5 Error TypeError: Method with the same name as overload declaration 'foo', overloadlist must list this medhod. */ diff --git a/ets2panda/test/ast/compiler/ets/forof_iterator_doesnt_return_iteartor.ets b/ets2panda/test/ast/compiler/ets/forof_iterator_doesnt_return_iteartor.ets new file mode 100644 index 0000000000000000000000000000000000000000..e340e0579b0de0ac364512cdacfe3c67a47909db --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/forof_iterator_doesnt_return_iteartor.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. + */ + +class A { + data: FixedArray = [1,2,3]; + $_iterator() : CIterator | undefined { + return new CIterator(this); + } +} + +class CIterator implements Iterator { + index = 0; + base: A; + constructor (base: A) { + this.base = base; + } + next(): IteratorResult { + if (this.index >= this.base.data.length) { + return { + done: true, + value: undefined + } + } + return { + done: this.index >= this.base.data.length, + value: this.base.data[this.index++] + } + } +} + +function main(): void { + let res = 0; + let a = new A(); + for (let x of a) res += x; + arktest.assertEQ(res, 6); +} + + +/* @@? 18:15 Error TypeError: The return type of '$_iterator' must be a type that implements Iterator interface.*/ +/* @@? 46:19 Error TypeError: Iterator method must return an object which implements Iterator */ +/* @@? 46:19 Error TypeError: 'For-of' statement source expression is not of iterable type. */ + diff --git a/ets2panda/test/ast/compiler/ets/forof_iterator_missing_next.ets b/ets2panda/test/ast/compiler/ets/forof_iterator_missing_next.ets new file mode 100644 index 0000000000000000000000000000000000000000..f513a77c6e85deebbe8b98aa645ed8d95c84e15f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/forof_iterator_missing_next.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 { + data: FixedArray = [1,2,3]; + $_iterator() : CIterator | undefined { + return new CIterator(this); + } +} + +class CIterator { + index = 0; + base: A; + constructor (base: A) { + this.base = base; + } +} + +function main(): void { + let res = 0; + let a = new A(); + for (let x of a) res += x; + arktest.assertEQ(res, 6); +} + +/* @@? 18:15 Error TypeError: The return type of '$_iterator' must be a type that implements Iterator interface.*/ +/* @@? 34:19 Error TypeError: Iterator method must return an object which implements Iterator */ +/* @@? 34:19 Error TypeError: 'For-of' statement source expression is not of iterable type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method.ets b/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..8952030938ed9e0299fe4d66d42505ead97d20d6 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method.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 C { + index = 0 +} + +function main(): int { + let c = new C() + let res = '' + for (let x of c) { + res += x + } + if (res != '6') return 1 + return 0 +} + +/* @@? 23:17 Error TypeError: Object type doesn't have proper iterator method. */ +/* @@? 23:17 Error TypeError: 'For-of' statement source expression is not of iterable type. */ diff --git a/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method_with_sig.ets b/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method_with_sig.ets new file mode 100644 index 0000000000000000000000000000000000000000..0adcb03bf1eb9a1fae580c5187ba574b6aa21732 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/forof_missing_iterator_method_with_sig.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 C { + $_iterator(param: int): string { + return "notAnIterator"; + } +} + +function main(): int { + let c = new C(); + let res = ""; + + for (let x of c) { + res += x; + } + + if (res != "6") return 1; + return 0; +} + +/* @@? 17:3 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ +/* @@? 17:13 Error TypeError: The return type of '$_iterator' must be a type that implements Iterator interface. */ +/* @@? 26:17 Error TypeError: Cannot find iterator method with the required signature. */ +/* @@? 26:17 Error TypeError: 'For-of' statement source expression is not of iterable type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/forof_prop_is_static.ets b/ets2panda/test/ast/compiler/ets/forof_prop_is_static.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff9986cb413d7253e4be1848410181fa7fe88526 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/forof_prop_is_static.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. + */ + +class C { + data: int[] = [1,2,3] + static $_iterator() { + return new CIterator(new C()) + } +} +class CIterator implements Iterator { + index = 0 + base: C + constructor (base: C) { + this.base = base + } + next(): IteratorResult { + return { + done: this.index >= this.base.data.length, + value: this.index >= this.base.data.length ? undefined : this.base.data[this.index++] + } + } +} + +function main(): int { + let c = new C() + let res = '' + for (let x of c) { + res += x + } + if (res != '6') return 1 + return 0 +} + +/* @@? 39:17 Error TypeError: '$_iterator' is a static property of 'C' */ +/* @@? 39:17 Error TypeError: 'For-of' statement source expression is not of iterable type. */ diff --git a/ets2panda/test/ast/compiler/ets/func_as_param.ets b/ets2panda/test/ast/compiler/ets/func_as_param.ets index 7d03377605808363ee9d614305db7f37aed9a5fc..38e38baccd5ec7f7b56fe9e57f7d5a681d76b505 100644 --- a/ets2panda/test/ast/compiler/ets/func_as_param.ets +++ b/ets2panda/test/ast/compiler/ets/func_as_param.ets @@ -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 } @@ -55,7 +56,7 @@ async function testAsyncGetFuncWithArgsZeroSafe() { } catch (e) { success = false; } - assertEQ(success, true, "getFuncWithArgsZero with async should not throw"); + arktest.assertEQ(success, true, "getFuncWithArgsZero with async should not throw"); } function testGetFuncWithArgsZeroSafe() { @@ -66,7 +67,7 @@ function testGetFuncWithArgsZeroSafe() { } catch (e) { success = false; } - assertEQ(success, true, "getFuncWithArgsZero should not throw"); + arktest.assertEQ(success, true, "getFuncWithArgsZero should not throw"); } function main(): void { @@ -88,22 +89,22 @@ function main(): void { 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"); + arktest.assertEQ(funcStr1, "(1: std.core.Double, 2: std.core.Double): std.core.Double", "func1 literal check"); + arktest.assertEQ(funcStr2, "(): std.core.Promise", "func2 literal check"); + arktest.assertEQ(funcStr3, "(): std.core.Double", "func3 literal check"); + arktest.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"); + arktest.assertEQ(getFunctionArgumentsCount(funcStr1), 2, "func1 should have 2 arguments"); + arktest.assertEQ(getFunctionArgumentsCount(funcStr2), 0, "func2 should have 0 arguments"); + arktest.assertEQ(getFunctionArgumentsCount(funcStr3), 0, "func3 should have 0 arguments"); + arktest.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"); + arktest.assertEQ(checkIsAsyncFunction(funcStr1), false, "func1 should not be async"); + arktest.assertEQ(checkIsAsyncFunction(funcStr2), true, "func2 should be async"); + arktest.assertEQ(checkIsAsyncFunction(funcStr3), false, "func3 should not be async"); + arktest.assertEQ(checkIsAsyncFunction(funcStr4), true, "func4 should be async"); // execute getFuncWithArgsZero with async testAsyncGetFuncWithArgsZeroSafe() diff --git a/ets2panda/test/ast/compiler/ets/function_namespace.ets b/ets2panda/test/ast/compiler/ets/function_namespace.ets new file mode 100644 index 0000000000000000000000000000000000000000..218177cc0576f25a40a0bc47a2be2213941a7d5f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_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. + */ + +function main () { +export namespace taskpool { + function taskfinished(task:Task) : boolean {} + +/* @@? 17:1 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 17:8 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 18:32 Error TypeError: Cannot find type 'Task'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token. */ +/* @@? 25:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/function_property.ets b/ets2panda/test/ast/compiler/ets/function_property.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0ca9949621a5f30e7c3afb54435133470626f1d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_property.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 readImage(path: string) { } + readImage./* @@ label */sync = (path: string) => { + let contents = 1; + return contents; +} + +/* @@@ label Error TypeError: Property 'sync' does not exist on type 'Function' */ diff --git a/ets2panda/test/ast/compiler/ets/function_signature.ets b/ets2panda/test/ast/compiler/ets/function_signature.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a516601825d7ffa8052117ce023a471493a9ce0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_signature.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. + */ + +final class TypeCreateCtx { + internal static native getObjectArrayForCCtor(ctxPtr: long): FixedArray must have only one type parameter. */ +/* @@? 17:88 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 17:88 Error SyntaxError: Unexpected token '>'. */ +/* @@? 17:97 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:120 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:138 Error TypeError: Cannot find type 'RuntimeTypeDescriptor'. */ diff --git a/ets2panda/test/ast/compiler/ets/function_signature_mismatch.ets b/ets2panda/test/ast/compiler/ets/function_signature_mismatch.ets new file mode 100644 index 0000000000000000000000000000000000000000..60e656cd74978369d1aae53f85b65ad2acd49cd9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_signature_mismatch.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 returnThisMember(this: { member: string }) { + return this.member; +} + +interface Container { + member: string; + returnThisMember: () => string; +} + +let container: Container; +container = { + member: "sample", + returnThisMember: returnThisMember, +}; + +function main() { + container.returnThisMember(); +} + +/* @@? 16:33 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 28:23 Error TypeError: Function name 'returnThisMember' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/function_typeerror.ets b/ets2panda/test/ast/compiler/ets/function_typeerror.ets new file mode 100644 index 0000000000000000000000000000000000000000..969d9217bec1a4d83e9ad8686bc2e71a6b3ebe39 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_typeerror.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Base { + methodOne(this.ownerType!, this.name): Base { + return p; + } +} + +class Derived extends Base { + override methodOne(p: Derived): Base { + return p; + } +} + +function main(): void { + let a = new Base(); + let b = new Derived() + + let resultA = a.methodOne(a); + let resultB = b.methodOne(b); + + arktest.assertEQ(resultA, resultB); +} + +/* @@? 17:14 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:19 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:19 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:30 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:30 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:32 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 17:36 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:41 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:41 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:42 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:48 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:49 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'return'. */ +/* @@? 18:17 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 23:23 Error TypeError: Method methodOne(p: Derived): Base in Derived not overriding any method */ +/* @@? 32:21 Error TypeError: Property 'methodOne' does not exist on type 'Base' */ diff --git a/ets2panda/test/ast/compiler/ets/fuzz_invalid_method.ets b/ets2panda/test/ast/compiler/ets/fuzz_invalid_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..c85cff638a433b70fc6ea49c2c22a3176c708d76 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzz_invalid_method.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 foo(this:A, p: T): T { + return this.data; +} + +class A { + data: T + goo + return this./* @@ label */classVal; + + (): T { + return foo(this, this.data); + } + +} + +/* @@? 22:8 Error SyntaxError: Field type annotation expected. */ +/* @@? 23:9 Error SyntaxError: Unexpected token 'return'. */ +/* @@? 23:16 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 23:20 Error SyntaxError: Unexpected token '.'. */ +/* @@? 23:43 Error SyntaxError: Field type annotation expected. */ +/* @@? 25:5 Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets b/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets new file mode 100644 index 0000000000000000000000000000000000000000..39746c2c669e9fcf75817c5b03e4fdc2845bf62d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class D{ + strB = (new StringBuilder).append('{ ').append(strB.toString()).append(' }') +} + +/* @@? 17:12 Error TypeError: Circular call function */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Boolean): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Byte): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Short): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Char): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Int): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Long): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Float): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Double): StringBuilder` */ +/* @@? 17:52 Error TypeError: Property 'strB' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets index 2a395eb89b60faa9598e4942c7820436f1e037d1..63fb0322b11fe1da063d382c4195d76a4e7a4ca2 100644 --- a/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest0.ets @@ -21,5 +21,5 @@ let callback = () => {for /* @@ label1 */aa !== /* @@ label2 */arr[idx]/* @@ lab /* @@@ label2 Error TypeError: Unresolved reference arr */ /* @@@ label2 Error TypeError: Indexed access is not supported for such expression type. */ /* @@@ label3 Error SyntaxError: Invalid left-hand side in 'For[In/Of]Statement'. */ -/* @@? 26:1 Error SyntaxError: Unexpected token 'eos'. */ -/* @@? 26:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 26:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 26:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets index 32a58853e998c5da757dd44aa0905a3cf9a08223..08bf93ddf630f27c5accb8a58f2d0d4cbd8ba160 100644 --- a/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest1.ets @@ -16,7 +16,7 @@ // the test case is from fuzzer. /* @@ label */fuzzz./* @@ label2 */@@/* @@ label3 */@@ -/* @@@ label Error TypeError: Unresolved reference fuzzz */ -/* @@@ label2 Error SyntaxError: There is no any node to insert at the placeholder position. */ -/* @@@ label2 Error SyntaxError: Identifier expected, got '@@'. */ -/* @@@ label3 Error SyntaxError: Unexpected token '@@'. */ \ No newline at end of file +/* @@? 17:15 Error TypeError: Unresolved reference fuzzz */ +/* @@? 17:36 Error SyntaxError: There is no any node to insert at the placeholder position. */ +/* @@? 17:36 Error SyntaxError: Unexpected token '@@'. */ +/* @@? 17:53 Error SyntaxError: Unexpected token '@@'. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets new file mode 100644 index 0000000000000000000000000000000000000000..93c9fbf39d51b2a8ed6d010a84b565cf64134b3e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo() { + new CC. +} + +/* @@? 17:9 Error TypeError: Cannot find type 'CC'. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ +/* @@? 18:1 Error TypeError: Invalid type reference. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets new file mode 100644 index 0000000000000000000000000000000000000000..34e6e9c60d71edc9c69a3b76d6277f57cdeb45c7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + f() { + f = 300 + } +} + +/* @@? 18:9 Error TypeError: Property 'f' must be accessed through 'this' */ +/* @@? 18:13 Error TypeError: Type 'Int' cannot be assigned to type '() => void' */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets new file mode 100644 index 0000000000000000000000000000000000000000..79c7af6977e643e5033a498f04f1560735c5f29a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface inter { } + +class B extends A implements inter { +} + +function foo1(b: Partial>) { +} + +/* @@? 18:20 Error TypeError: Cannot find type 'A'. */ +/* @@? 18:20 Error TypeError: The super type of 'B' class is not extensible. */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets index fe797887873ce85ba7de91ee18cbc6ee819e44c7..11b245f328fa6e74d25d02acdd8746d4cf4c3955 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person ={name: /* @@ label */42, age:25} } -/* @@@ label Error TypeError: Type 'int' is not compatible with type 'String' at property 'name' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with type 'String' at property 'name' */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets index 0980e0579ba368eb9be5e1ac7995fe9961c1e318..d12d67284b5a12d1a2967e8f79e05e205b429e4e 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:25} } -/* @@@ label Error TypeError: Type String is not assignable to constraint type Double */ +/* @@@ label Error TypeError: Type argument 'String' should be a subtype of 'Double'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets index 87ee60730287f0902ae428f4b178c1aac889bccb..fd7eed0b9edf505a81a665ea8fc1c3afe705f05a 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets @@ -22,5 +22,5 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:/* @@ label1 */"25"} } -/* @@@ label Error TypeError: Type Double is not assignable to constraint type String */ +/* @@@ label Error TypeError: Type argument 'Double' should be a subtype of 'String'-constraint */ /* @@@ label1 Error TypeError: Type '"25"' is not compatible with type 'Double' at property 'age' */ diff --git a/ets2panda/test/ast/compiler/ets/generic_callback.ets b/ets2panda/test/ast/compiler/ets/generic_callback.ets new file mode 100644 index 0000000000000000000000000000000000000000..92c4b7ad7e8c7186666911d3e4c1f5ee1faa81f4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/generic_callback.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 identity(a: A): A { + return a; +} +let x = [1, 2, 3].map(identity)[0]; + +/* @@? 19:9 Error TypeError: No matching call signature for map((a: A) => A) */ +/* @@? 19:9 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 19:9 Error TypeError: No matching call signature for map((a: A) => A) */ +/* @@? 19:9 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 19:23 Error TypeError: Type '(a: A) => A' is not compatible with type '(value: Int, index: Double, array: Array) => A' at index 1 */ +/* @@? 19:23 Error TypeError: Type '(a: A) => A' is not compatible with type '(value: Int, index: Double, array: ReadonlyArray) => A' at index 1 */ +/* @@? 19:23 Error TypeError: Type '(a: A) => A' is not compatible with type '(value: Int, index: Double, array: Array) => A' at index 1 */ +/* @@? 19:23 Error TypeError: Type '(a: A) => A' is not compatible with type '(value: Int, index: Double, array: ReadonlyArray) => A' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/generic_casting.ets b/ets2panda/test/ast/compiler/ets/generic_casting.ets index d023b8a5644c37ad7c472a0fa47d18144710e27d..c88818208f615ac361c4e29058e46f6737bcdae1 100644 --- a/ets2panda/test/ast/compiler/ets/generic_casting.ets +++ b/ets2panda/test/ast/compiler/ets/generic_casting.ets @@ -28,5 +28,5 @@ class Foo { class Bar extends Foo { } Foo.s_instance = new Bar(); Foo.foo(); -assertTrue(Foo.s_instance?.value == true); -assertTrue((Foo.s_instance as Bar).value); +arktest.assertTrue(Foo.s_instance?.value == true); +arktest.assertTrue((Foo.s_instance as Bar).value); diff --git a/ets2panda/test/ast/compiler/ets/generic_class_without_type_arg_2.ets b/ets2panda/test/ast/compiler/ets/generic_class_without_type_arg_2.ets index ad7adc8ec4230878b166dddf30b8601ec7fcee9b..049b1c7a37f4d32fc444fd2baf2b5b899e538b87 100644 --- a/ets2panda/test/ast/compiler/ets/generic_class_without_type_arg_2.ets +++ b/ets2panda/test/ast/compiler/ets/generic_class_without_type_arg_2.ets @@ -17,7 +17,7 @@ class A {} function main(): void { let i: /* @@ label */A|undefined = undefined; - assertEQ(i, undefined); + arktest.assertEQ(i, undefined); } /* @@@ label Error TypeError: Type 'A' is generic but type argument were not provided. */ diff --git a/ets2panda/test/ast/compiler/ets/generic_method_with_default_short_neg.ets b/ets2panda/test/ast/compiler/ets/generic_method_with_default_short_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee7b46aabf12ce6f2b615ef62edc6067333cf5d8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/generic_method_with_default_short_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. + */ + +class Point { + foo(i:X = 0 as X): X { + return i; + } +} + +function main(): void { + let p: Point = new Point(); + let result: short = p.foo(); + arktest.assertEQ(result, 0 as short); +} + +/* @@? 17:32 Error TypeError: Cannot cast type 'Int' to 'X' */ diff --git a/ets2panda/test/ast/compiler/ets/generic_method_with_promise_return_neg.ets b/ets2panda/test/ast/compiler/ets/generic_method_with_promise_return_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..5676324ca1bd8a50b06d652ccbd11136630673ca --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/generic_method_with_promise_return_neg.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 Point { + foo(): Promise { + return Promise.resolve(1 as X); + } +} + +function main(): void { + const p = new Point(); + p.foo().then((value: short) => { + arktest.assertEQ(value, 1 as short); + }); +} + +/* @@? 18:15 Error TypeError: Type 'Promise<*ERROR_TYPE*>' is not compatible with the enclosing method's return type 'Promise' */ +/* @@? 18:31 Error TypeError: Cannot cast type 'Int' to 'X' */ diff --git a/ets2panda/test/ast/compiler/ets/generic_typealias_2_neg.ets b/ets2panda/test/ast/compiler/ets/generic_typealias_2_neg.ets index d8f74a0d2bc6ab2ee6ad83b096b96afef7c4549e..2ce7f0e30f105ea1619d16cd28d95a3e80b60edf 100644 --- a/ets2panda/test/ast/compiler/ets/generic_typealias_2_neg.ets +++ b/ets2panda/test/ast/compiler/ets/generic_typealias_2_neg.ets @@ -17,7 +17,7 @@ type my_type = T; function main(): void { - let a: /* @@ label */my_type = new Int(); + let a: my_type = new Int(); } -/* @@@ label Error TypeError: Type alias declaration is generic, but no type parameters were provided */ +/* @@? 20:12 Error TypeError: Type alias declaration is generic, but too few type arguments were provided */ diff --git a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets index 0bfcb0ae7dd31fcedea54ed66fa937048425b6f7..1905464507069943fd44d75f80a28c7a7da25588 100644 --- a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets @@ -22,4 +22,4 @@ function main(): void { let a: A/* @@ label */; } -/* @@@ label Error TypeError: Type B is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets index a698d21b0fa19b52b8012fdb1aeb4edb5b711937..c8f046fedf8411f27f2f55d2a9fb84bad6e45592 100644 --- a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets @@ -22,10 +22,9 @@ function main(): void { let prim_int = 5; switch(prim_int) { - /* @@ label */case /* @@ label1 */a_int.value: // not allowed, because type of a_int.value is Int + /* @@ label */case a_int.value: // not allowed, because type of a_int.value is Int default: } } -/* @@@ label1 Error TypeError: Switch case type 'Int' is not comparable to discriminant type 'int' */ /* @@@ label Error TypeError: Constant expression required */ diff --git a/ets2panda/test/ast/compiler/ets/getType.ets b/ets2panda/test/ast/compiler/ets/getType.ets new file mode 100644 index 0000000000000000000000000000000000000000..beeb87771d0ba08a2148838851a2bbb4bcd54c39 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/getType.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: * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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_tuple_union = [string, boolean, number] | (this.mnum === other.mnum && this.mden === other.mden +)[] + +/* @@? 15:62 Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ +/* @@? 15:66 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 15:67 Error TypeError: Unresolved reference mnum */ +/* @@? 15:76 Error TypeError: Unresolved reference other */ +/* @@? 15:90 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 15:95 Error TypeError: Property 'mden' does not exist on type 'ETSGLOBAL' */ +/* @@? 16:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:1 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:3 Error SyntaxError: Unexpected token ']'. */ +/* @@? 28:1 Error SyntaxError: Unexpected token, expected ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/greater_than_neg.ets b/ets2panda/test/ast/compiler/ets/greater_than_neg.ets index 172e7b937cd566178ca0730096ceed0779f8271e..f5dea30ef16a64a5319578985f633e47b29c8704 100644 --- a/ets2panda/test/ast/compiler/ets/greater_than_neg.ets +++ b/ets2panda/test/ast/compiler/ets/greater_than_neg.ets @@ -17,8 +17,6 @@ let a: Array>>=2 let b: Array>=2 /* @@? 16:21 Error SyntaxError: Unexpected token '>>='. */ -/* @@? 16:21 Error SyntaxError: Unexpected token '>>='. */ -/* @@? 17:21 Error SyntaxError: Unexpected token '>='. */ +/* @@? 16:24 Error SyntaxError: Unexpected token '2'. */ /* @@? 17:21 Error SyntaxError: Unexpected token '>='. */ -/* @@? 17:21 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ - +/* @@? 17:23 Error SyntaxError: Unexpected token '2'. */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference10.ets b/ets2panda/test/ast/compiler/ets/identifierReference10.ets index 161213981bb7ab32be097777858635d1a9b5c791..bb75765d532f7330f56161213ea840dcb21813f6 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference10.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference10.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference12.ets b/ets2panda/test/ast/compiler/ets/identifierReference12.ets index 6b2358f878ef0c8020a48837ffe553f27b708016..1c34cf4214e39791ff58b24b218d0d53505ab981 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference12.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference12.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference16.ets b/ets2panda/test/ast/compiler/ets/identifierReference16.ets index e21f0887722ff83679eca47a24b8b8caf2f7e723..aefc534f96224ee5e6560910e73b0cef63d5c7c9 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference16.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference16.ets @@ -45,4 +45,4 @@ class A extends B { /* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 41:7 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 41:7 Error TypeError: No matching call signature for foo(int) */ +/* @@? 41:7 Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference3.ets b/ets2panda/test/ast/compiler/ets/identifierReference3.ets index 69a7d28c11d4a40dbed37eab95dda9c02a43149b..ddc353921b26c4b613eb7e4677dcf07b414af3f2 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference3.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference3.ets @@ -21,4 +21,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference9.ets b/ets2panda/test/ast/compiler/ets/identifierReference9.ets index 6303c2f318f1df4bd9ea6a3020e59c8681495476..3021ebf7a1953f57ccd1e53d8ba2ba11c4805025 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference9.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference9.ets @@ -25,4 +25,4 @@ class A { } } -/* @@? 24:16 Error TypeError: Type 'int' cannot be assigned to type '() => void' */ +/* @@? 24:5 Error TypeError: Class methods cannot be overwritten. */ diff --git a/ets2panda/test/ast/compiler/ets/illegal_exponentiation_1.ets b/ets2panda/test/ast/compiler/ets/illegal_exponentiation_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..a8329c7756d674f08a196560055221e9742f9ed4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/illegal_exponentiation_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 main() { + let x = -1 ** 1.0; +} + +/* @@? 17:11 Error TypeError: Exponent must be an integer if base is less than 0. */ 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_6/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets index 35ac4831a4aedc21cb17de54bba5340f14cff376..810b288169035ab9584040656568878648fc8849 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets @@ -17,4 +17,4 @@ package mypackage; let myvar: number = exist_but_checker_fails_in_file; -/* @@? package_module_2.ets:19:39 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? package_module_2.ets:19:39 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets index ba854d07c801ed57c2fca81c2b95aa8d9874e75b..cf77170f19624360a6ea8102c4ef4e8bf55f7595 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets @@ -18,4 +18,4 @@ package mypackage; let exist_but_checker_fails_in_file: number = 8; let wong_type: string = /* @@ label */9; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ 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 a0e59061b587eeab94a4c350ca25591aae86a627..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,6 +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. */ /* @@? 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..3eaf30089d8abe7967f6bb633895bf2fe5b8d3c0 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 @@ -17,13 +17,12 @@ package mypack; // That is the main file, from which we will compile full package -/* @@? 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_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..ecb87c42d0f24147e053be1de3a7bdc9873ed1d8 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..18341d2998d6555b2cd8a8a9e4ff41841ba6ea57 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 @@ -17,15 +17,14 @@ 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_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? 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..bab0e7b0a57cec997f15aba779f719f39e7cae3c 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 @@ -21,15 +21,14 @@ function foo(): Day { return new good 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_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_export/eitest_dup_import/decl/eitest_import.d.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/decl/eitest_import.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..73a59d89fb13760d47857b2eb767f7192ec304ba --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/decl/eitest_import.d.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 declare namespace ns{} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_import.ets similarity index 96% rename from ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets rename to ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_import.ets index 5aad017834822967ec7249e5db93b39b94750059..f83c0ec334719e43a769d0e14d8cf8eed7443634 100644 --- a/ets2panda/linter/test/interop/test_files/dummy_arkts1_file.ets +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_import.ets @@ -13,4 +13,4 @@ * limitations under the License. */ -export module arkts {} +export namespace ns{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_test.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..9140ddbb0eaf8b656111908be89f967f70ea08ab --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_dup_import/eitest_test.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 {ns} from "./decl/eitest_import" +import {ns} from "./eitest_import" diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6780a05eb125ffb46efbcb927506f856a62a9db9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_1.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 class A{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a12a108de334af7b040d080b400ef850ac9bfd38 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_A_2.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{} + +export A; \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e94062d2468c5af0e7f24a41c9a2dd6d8f272bea --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_1.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 class B{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_as_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_as_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..2e2d5ca5aa5e2f26dc20ac7903f3df383c8dc2a9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_B_as_A_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. + */ + +class B{} + +export {B as A} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7d776f8edd6f53a0af03e05684e25c46a9699b8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_1.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 default class A{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..e3948e3dfbfd343992d6b618daac5496260c7361 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_A_2.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{} + +export default A; \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3d22a7b651b21acd81af0c740fc42400cda1a76 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_1.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 default class B{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..85a9380fbf31ea659eff83d90c81edeb667c04bb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_B_2.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 B{} + +export default B; \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_import_default_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_import_default_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ed966ae30762fe203505e0582e847a6c555d04a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_default_import_default_A_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. + */ + +import A from "./eitest_export_default_A_1" + +export default A \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..472711f075fbc259fdb11a102207e3f14f2fb772 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_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. + */ + +import {A} from "./eitest_export_A_1" + +export A \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b81574296182104106b3e6c9152839aeb3801a23 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_2.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 {B} from "./eitest_export_B_1" + +export {B as A} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_3.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d1da0fa43de2dc868ab7713133aee21f628eba4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_A_3.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 as B} from "./eitest_export_A_1" + +export {B as A} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b30c26cbbef76ead30261ea44ea212d11043aad2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_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. + */ + +import A from "./eitest_export_default_A_1" + +export A \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_B_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_B_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6fccdc60dab6ba6f95cbdd24de6f456ffc3b5f02 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_import_default_A_B_1.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 "./eitest_export_default_A_1" +import B from "./eitest_export_default_B_1" + +export {A,B} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_export_type_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_type_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..efebe3f5c003522a3d8f94772f77e9a6d0bfa833 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_export_type_A_1.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 {} + +export default type CLASS_A = A; \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..16412b6e62b02e1d63413dca3d63dd3fc42d0237 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_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. + */ + +import {A} from "./eitest_export_A_1" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_1_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_1_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..3fed30fb928713556c742877448e04e52530511d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_1_ne.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 "./eitest_export_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..4eb9ea3c1eab50568ca5fa13d55886b8f2c904b4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2.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 "./eitest_export_A_2" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1da533413588dc4e365d98dd45f4a702099b030 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_2_ne.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 "./eitest_export_A_2" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/esobject_with_string_key_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3.ets similarity index 87% rename from ets2panda/test/ast/compiler/ets/esobject_with_string_key_1.ets rename to ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3.ets index 925373191271ff263e939dfc9d5c2b58e5e4e6c9..d17ac7f13b3758c2a131f3b61c6153aaf99cbba8 100644 --- a/ets2panda/test/ast/compiler/ets/esobject_with_string_key_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3.ets @@ -13,7 +13,8 @@ * limitations under the License. */ -function foo (es: JSValue): string { - let str = 'Ekk' + 'o'; - return es[str]; +import {A} from "./eitest_export_B_as_A_1" + +function main(){ + let a :A = new A() } \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..5b0fa101622e9a9e8ca48a9b0c91ae82e6c92517 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_3_ne.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 "./eitest_export_B_as_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..48563cfcfb9fec6863a23f3015b43d08bbeb52ec --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4.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 "./eitest_export_import_A_1" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa8c172b1fc2789a4651b9a2d62913e45bb38d77 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_4_ne.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 "./eitest_export_import_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..036f643c19f10c5f8097d978956c2fd4f3020a08 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5.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 "./eitest_export_import_A_2" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..38e266873e042dca44e8ef7ceba7bd730943e7e7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_5_ne.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 "./eitest_export_import_A_2" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ad8f1ce3172560b13802d13db298036e105a775 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6.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 "./eitest_export_import_A_3" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..06251d99394b889ece26ea66b66029d854a17326 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_6_ne.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 "./eitest_export_import_A_3" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7.ets new file mode 100644 index 0000000000000000000000000000000000000000..43b3cbfb6ee912f1cadcb9918a8d39873ffc982e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7.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 "./eitest_export_import_default_A_1" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..2aa03a66a4ade9939d13e2c681d3e736d44fc848 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_7_ne.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 "./eitest_export_import_default_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad032143e5742c84943dc68d71c1e7f527687c08 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_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. + */ + +import {A,B} from "./eitest_export_import_default_A_B_1" + +function main(){ + let a :A = new A() + let b :B = new B() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_1_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_1_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..259a491d0a744327bbb2afb04cca9e1d683f66db --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_A_B_1_ne.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 "./eitest_export_import_default_A_B_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:15 Error TypeError: Cannot find default imported element in the target */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..569fa53b4dd472ebefa698402a7ea487ee26a5c1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_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. + */ + +import * as ns from "./eitest_import_all_2" +const f: ns.qw.Root.Foo = new ns.qw.Root.Foo() \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_1_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_1_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..8350e64f9112d6920edac99072e60f4d6b6a3258 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_1_ne.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 * as ns from "./eitest_import_all_2_ne" +const f: ns.qw.Root.Foo = {x:10} + +/* @@? eitest_import_all_1_ne.ets:17:13 Error TypeError: 'qw' type does not exist. */ +/* @@? eitest_import_all_1_ne.ets:17:16 Error TypeError: 'Root' type does not exist. */ +/* @@? eitest_import_all_1_ne.ets:17:21 Error TypeError: 'Foo' type does not exist. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..831223c23953eca24ab809a859f490ef758b3e5b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_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. + */ + +import * as qw from "./eitest_import_all_3" +export {qw} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_2_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_2_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..8035ef478c3a0121593b5c91afe7331888d37519 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_2_ne.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 * as qw from "./eitest_import_all_3" \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_3.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..2327e442364fbe5998b075926efb0d0c3e557297 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_3.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 namespace Root{ + export class Foo{ + x:number=1 + } +} +export class B{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff520593414d86d3d70a089601e03dbdf1864700 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4.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 ns from "./eitest_import_all_5" +const t: ns.B = new ns.B() \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..22fc4900fc5427570af2a78e3533a0056a1839cf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_4_ne.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 * as ns from "./eitest_import_all_5_ne" +const t: ns.B = new ns.B() + +/* @@? eitest_import_all_4_ne.ets:17:13 Error TypeError: 'B' type does not exist. */ +/* @@? eitest_import_all_4_ne.ets:17:24 Error TypeError: 'B' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..a2b2bca713b192ab65963211687d26d575083f0d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5.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 {B} from "./eitest_import_all_3" +export {B} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c9624c5faf7a4f8c604fc8c82a122d94b012fa --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_all_5_ne.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 {B} from "./eitest_import_all_3" \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..5fa1751e6b6fa561e2bea5ad6a1e3be0af1b6e5b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_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. + */ + +import A from "./eitest_export_default_A_1" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_1_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_1_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..da65463362abc626fdc61908e514ec5646f9691c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_1_ne.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. + */ + +import {A} from "./eitest_export_default_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:17 Error TypeError: Use the default import syntax to import a default exported element */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..47bcf30f29e2a2a7d43deeaf327ad1f20ca9b54a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2.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 B from "./eitest_export_default_A_2" + +function main(){ + let a :B = new B() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..6758e4fdde85322ba1387f33e1efb3b9910bbb42 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_2_ne.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 {B} from "./eitest_export_default_A_2" + +function main(){ + let a :B = new B() +} + +/* @@? 16:17 Error TypeError: Cannot find imported element 'B' */ +/* @@? 19:12 Error TypeError: Cannot find type 'B'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'B'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..988105af2c3295fcc5eddbcfa2f54771d6ba22be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3.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 "./eitest_export_default_import_default_A_1" + +function main(){ + let a :A = new A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..95df0589cc4dbf3e84837bbebb749b660f871d6d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_default_A_3_ne.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. + */ + +import {A} from "./eitest_export_default_import_default_A_1" + +function main(){ + let a :A = new A() +} + +/* @@? 16:17 Error TypeError: Use the default import syntax to import a default exported element */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_1.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..2de45482eac95c3eecfbca31a067ef9cd3002c9e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_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. + */ + +import CLASS_A from "./eitest_export_type_A_1" + +function main(){ + let a :CLASS_A = new CLASS_A() +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_1_ne.ets b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_1_ne.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5e1725a38e9997b18267ef86f67f8825ffb52af --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/eitest_import_type_A_1_ne.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. + */ + +import {CLASS_A} from "./eitest_export_type_A_1" + +function main(){ + let a :CLASS_A = new CLASS_A() +} + +/* @@? 16:23 Error TypeError: Use the default import syntax to import a default exported element */ diff --git a/ets2panda/test/ast/compiler/ets/import_export/export.ets b/ets2panda/test/ast/compiler/ets/import_export/export.ets new file mode 100644 index 0000000000000000000000000000000000000000..4f5df369815445a55e3d23b98d27cb57251a87a9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/export.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 class A { + a : int + constructor(a : int) { + this.a = a + } +} + +export type CallBack = () => int diff --git a/ets2panda/test/ast/compiler/ets/import_export/export_default_1.ets b/ets2panda/test/ast/compiler/ets/import_export/export_default_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..87fc2e6180deea127fb2ea64334521b3ca47ee26 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/export_default_1.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 default class A { + a : int + constructor(a : int) { + this.a = a + } +} + +export A diff --git a/ets2panda/test/ast/compiler/ets/import_export/export_default_2.ets b/ets2panda/test/ast/compiler/ets/import_export/export_default_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b0774f0286cdebe65f2f4615d0bc2b90c7aeaf7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/export_default_2.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 class A { + a : int + constructor(a : int) { + this.a = a + } +} + +export default A diff --git a/ets2panda/test/ast/compiler/ets/import_export/external_export.ets b/ets2panda/test/ast/compiler/ets/import_export/external_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..01ac01d4e9a6003686865a751fcffe6988e1ad67 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/external_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. + */ + +import {TT} from "./test1_1" diff --git a/ets2panda/test/ast/compiler/ets/import_export/import_default_1.ets b/ets2panda/test/ast/compiler/ets/import_export/import_default_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e160b8734c90daa48add696096a82665a82f509 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/import_default_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. + */ + +import { A } from "./export_default_1" + +let a = new A(1) \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/import_default_2.ets b/ets2panda/test/ast/compiler/ets/import_export/import_default_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b56ff98d87a064921a633dddf248bfbed2b1e736 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/import_default_2.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 C from "./export_default_1" + +let a = new C(1) \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/import_default_3.ets b/ets2panda/test/ast/compiler/ets/import_export/import_default_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..403cfd549cca55154d7a9ce39329181a4434fe2c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/import_default_3.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 "./export_default_2" + +let a = new A(1) diff --git a/ets2panda/test/ast/compiler/ets/import_export/import_default_4.ets b/ets2panda/test/ast/compiler/ets/import_export/import_default_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..ef312b9d2c110fefeedd05c9b52f209fbf963e14 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/import_default_4.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 C from "./export_default_2" + +let a = new C(1) \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/import_type_star.ets b/ets2panda/test/ast/compiler/ets/import_export/import_type_star.ets new file mode 100644 index 0000000000000000000000000000000000000000..048b83604535d472b7f359bdca1563334566154b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/import_type_star.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 type * as TEST from './export' + +let bad1 : TEST.CallBack = () => { + return "A"; +} +let bad2 : TEST.A = new TEST.A() + +/* @@? 19:12 Error TypeError: Type '"A"' is not compatible with the enclosing method's return type 'Int' */ +/* @@? 21:21 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 21:21 Error TypeError: No matching construct signature */ diff --git a/ets2panda/test/ast/compiler/ets/import_export/re_export.ets b/ets2panda/test/ast/compiler/ets/import_export/re_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..7988832afb1f655cb3e409aa39f3cfab95434aa9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/re_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. + */ + +export { A, A as B } from "./eitest_export_A_1" \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/test1_1.ets b/ets2panda/test/ast/compiler/ets/import_export/test1_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1fb57059d787caca53bdd2f6a4c5668f6bd1f334 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/test1_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. + */ + +import VAR_t from "./test2_1" +export class TT{} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/test2_1.ets b/ets2panda/test/ast/compiler/ets/import_export/test2_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcfbd1fa619fcdf2fe18d8c3b5333e1ba91a335d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/test2_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. + */ + +import {VAR_i as VAR_o} from "./test3_1" +export default VAR_o +export type VAR_j = string; \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_export/test3_1.ets b/ets2panda/test/ast/compiler/ets/import_export/test3_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ce9d1c5bef3a925f9c9d115a72b86e04a3d7a47 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_export/test3_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. + */ + +export {VAR_j as VAR_xj} from "./test2_1" +export type VAR_i = int; \ No newline at end of file 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..1bcecf5a368b19c18e591af97df0c7138912a6c6 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,40 @@ 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: Cannot export two different names with the same export alias name 'foo2'. */ +/* @@? 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..fbf91a5f6d272d0dcd6f0843c43bd9be41dab74e 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 @@ -24,9 +24,10 @@ export class A { let 1: number // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? import_1.ets:24:5 Error SyntaxError: Number, string or computed value property name '1' is not allowed, use classes to access data by property names that are identifiers */ // 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:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 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..ce4e0f07042c02f31af6209e52948cc0af03a73c 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 @@ -20,7 +20,6 @@ export class B { 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:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 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..c7b79fc31dc88b8dd9c755538d3f57985f899b0f 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 @@ -18,15 +18,16 @@ import {A, B} from "./import_1.ets" let b = new B(10); // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? import_1.ets:24:5 Error SyntaxError: Number, string or computed value property name '1' is not allowed, use classes to access data by property names that are identifiers */ // 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:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 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: 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 +/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(Int) */ 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..47707baa9fc2b8f74afc422f020b42de8f29e1f8 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,18 @@ 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 SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ /* @@? 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..417776eca0f51ca7b33f730512d41d0df9dfddd1 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,11 @@ 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. */ - +/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'Double' */ +/* @@? 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 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' */ -/* @@? 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/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..cb95afc31ae8eefb69bf155351d49e1c6f400200 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,11 @@ 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 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..58ca5496f158e7f60cf2fed3ec0ccbd14da31485 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,11 @@ 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 ')'. */ - -/* @@? 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_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'Double' */ /* @@? 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/import_within_scope/export_file.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/export_file.ets new file mode 100644 index 0000000000000000000000000000000000000000..e5c45ec62b539666b5ab58d44666a02d16fab571 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/export_file.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 class Host {} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7628a6a7050e85f4cba2a350b55735ecfc3e17e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_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. + */ + +namespace ns { + import * as nsi from './export_file'; +} + +/* @@? 17:5 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..e5dbc4c1f517123bb55f636e2cdd5ab72f676817 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_2.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 main() { + { + import * as sci from './export_file'; + } +} + +/* @@? 18:9 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_3.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..b57db803922961286b25b776ce62bdd26c10b8da --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_within_scope/scope_import_3.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 main() { + if (true) { + import * as ici from './export_file'; + } +} + +/* @@? 18:9 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3262d1a8397c9f94e46088aded27755baab15a52 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_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. + */ + +export function foo(): void {} +export class A {} + +export { + foo as f1, + foo as f2, + A as a1, + A as a2 +} diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..54f88f12e3d075c93af321b165798e14331e755c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/export_type_several_times_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. + */ + +function foo(): void {} +class A {} +let a = new A() + +export { + foo as f1, + foo as f2, + A as a1, + A as a2, + a as a3, + a as a4 +} diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3d2d5d4dce9f50757031609c6b892db8e539ee0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_1.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 { foo, f1, f2, A, a1, a2 } from "./export_type_several_times_1.ets" + +foo() +f1() +f2() +let c: A = new A() +let c1: A = new a1() +let c2: A = new a2() \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..91be1a73dbe8f87fd4b7b6696793289ce2f3f1bf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_2.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 { f1, f2, a1, a2, a3, a4 } from "./export_type_several_times_2.ets" + +f1() +f2() +let c1: a1 = new a1() +let c2: a2 = new a2() +c1 = a3 +c2 = a4 \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_3.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..fec071802f9ed657b099cc121f7fced934488fd2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/import_same_type_form_alias_3.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 { foo, f1, f2, A, a1, a2 } from "./export_type_several_times_2.ets" + +f1() +f2() +let c1: a1 = new a1() +let c2: a2 = new a2() + +/* @@? 16:10 Error TypeError: Cannot find imported element 'foo' */ +/* @@? 16:23 Error TypeError: Cannot find imported element 'A' */ 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_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets index 453e606be33f02190dd29f0fd3abf2417c1936cf..bddda705c6dc2175b3fe368d4a3614e59d69c395 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets @@ -16,7 +16,5 @@ export function foo(): void {} export { - foo as /* @@ label */bar + foo as bar } - -/* @@@ label Error SyntaxError: Cannot export 'foo', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets index b5eeab80f63d56146b1a930950285600f5b22ed5..a75a5dbac45bf1d154c2f08e209dc9db626f0e2e 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets @@ -16,7 +16,5 @@ export default function foo(): void {} export { - foo as /* @@ label */bar + foo as bar } - -/* @@@ label Error SyntaxError: Cannot export 'foo', it was already exported. */ 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_with_invalid_syntax.ets b/ets2panda/test/ast/compiler/ets/import_type_with_invalid_syntax.ets index fbfe9a986adcb906b3c7f064c73099e55d0d398d..9b7ecfe360a18d95e8519b7a0e057be0f14136be 100644 --- a/ets2panda/test/ast/compiler/ets/import_type_with_invalid_syntax.ets +++ b/ets2panda/test/ast/compiler/ets/import_type_with_invalid_syntax.ets @@ -13,13 +13,12 @@ * limitations under the License. */ -import type /* @@ label */* /* @@ label1 */from './export_type.ets' +import type * /* @@ label1 */from './export_type.ets' let a = new A(); class C implements B {}; let c = new C() -/* @@@ label Error SyntaxError: Type import requires selective binding to define the required imported elements. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected 'as'. */ -/* @@? 16:49 Error TypeError: Class 'C' is already defined. */ +/* @@? 16:35 Error TypeError: Class 'C' is already defined. */ /* @@? export_type.ets:1:1 Error TypeError: Function main is already declared. */ 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/incorrect_call_getter.ets b/ets2panda/test/ast/compiler/ets/incorrect_call_getter.ets new file mode 100644 index 0000000000000000000000000000000000000000..5b4c4d31db21beb97a50f7bd84b2f17621ac65be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/incorrect_call_getter.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 inter { + gett(k: number): number; +} + +class Getter { + $_get(index:number) {} +} + +export class ConM implements inter { + private buckets: Getter = new Getter(); + + private getBucket(k: int) { + this.buckets[this.gett](k) + } +} + +/* @@? 22:10 Error TypeError: 'The special predefined method '$_get' shouldn't have void return type. */ +/* @@? 25:36 Error TypeError: ConM is not abstract and does not override abstract method gett(k: Double): Double in inter */ +/* @@? 29:9 Error TypeError: No matching indexing signature for $_get((k: Double) => Double) */ +/* @@? 29:22 Error TypeError: Type '(k: Double) => Double' is not compatible with type 'Double' at index 1 */ +/* @@? 29:22 Error TypeError: Cannot find index access method with the required signature. */ diff --git a/ets2panda/test/ast/compiler/ets/index_callExpression.ets b/ets2panda/test/ast/compiler/ets/index_callExpression.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ce5b1325db51497b41e08d9934b3cd8bae8d1e5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/index_callExpression.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 testInfo() { + DataView => ""[main]() +} + +/* @@? 17:5 Error TypeError: The type of parameter 'DataView' cannot be inferred */ +/* @@? 17:17 Error TypeError: Type 'String' has no call signatures. */ +/* @@? 17:20 Error TypeError: Function name 'main' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets index 6abcf73491b7c19261f3ef18a8291aa6783fe638..c4664c65f9cf5e0a697f63f35e31d162ac6309ce 100644 --- a/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets +++ b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets @@ -13,11 +13,11 @@ * limitations under the License. */ -function foo(arr:Array, f:(a:Array)=>string){ +function foo(arr:T[], f:(a:T[])=>string){ return f(arr[0]) // CTE } -function bar(arr:Array){ +function bar(arr:number[]){ return foo(arr, (a):string=>{ let res = a.toString(); return res diff --git a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets index 948c1c93fe83cf3e5c75dfa81084b35169ee393c..d886e32944bab02a919a0cb54c1b1d8a5d69a69d 100644 --- a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets +++ b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets @@ -18,5 +18,8 @@ a[0] = 1 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. */ +/* @@? 16:9 Error TypeError: Can't resolve array type */ +/* @@? 17:1 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 18:1 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 19:9 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 19:16 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets index 4a568f118d26826ea71cea35b777fd30d07a562f..c8400f2b115b5afbbb436508b24fe92ad03769ad 100644 --- a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets +++ b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets @@ -16,4 +16,6 @@ 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: 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/infinityNarrowing.ets b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets index 821efecc9a7377a833f7cce6341c335aa3e8ccf2..ee3013210a45448f54f1288f7cd96621377b6810 100644 --- a/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets +++ b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets @@ -13,9 +13,15 @@ * limitations under the License. */ -export const floatInf: float = 1.0 / 0.0 -export const byteInf: byte = /* @@ label */1.0 / 0.0 -export const shortInf: short = /* @@ label1 */1.0 / 0.0 +export const floatInf: /* @@ dst_type1 */float = /* @@ value1 */1.0 / 0.0 +export const byteInf: /* @@ dst_type2 */byte = /* @@ value2 */1.0 / 0.0 +export const shortInf: /* @@ dst_type3 */short = /* @@ value3 */1.0 / 0.0 + + +/* @@? 16:42 Error TypeError: Invalid destination type for floating-point constant value */ +/* @@? 16:65 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ +/* @@? 17:42 Error TypeError: Invalid destination type for floating-point constant value */ +/* @@? 17:64 Error TypeError: Type 'Double' cannot be assigned to type 'Byte' */ +/* @@? 18:42 Error TypeError: Invalid destination type for floating-point constant value */ +/* @@? 18:65 Error TypeError: Type 'Double' cannot be assigned to type 'Short' */ -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'byte' */ -/* @@@ label1 Error TypeError: Type 'double' cannot be assigned to type 'short' */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.ets new file mode 100644 index 0000000000000000000000000000000000000000..683b62432d78c2310e478d5163f7119738a2ecf2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative1.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() { + /* @@ label */initModule('./module_to_init.ets') +} + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.ets new file mode 100644 index 0000000000000000000000000000000000000000..7887e38abf24d0f0ba6795abf5924fb16e7a7d04 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative2.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 A { +} + +/* @@ label */initModule('./module_to_init.ets') + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.ets new file mode 100644 index 0000000000000000000000000000000000000000..18a7108e9362871bd65fdae78bc7f8fe837237c5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative3.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 b = 1 +/* @@ label */initModule('./module_to_init.ets') + +/* @@@ label Error SyntaxError: initModule() must only be called immediately after the import statement, and before any other declarations or statements. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9d9ffd119ac1d841104d0a2410b52432eeed989 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative4.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. + */ + +/* @@ label */initModule(1) + +/* @@@ label Error SyntaxError: initModule() only accept string literal as argument. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.ets new file mode 100644 index 0000000000000000000000000000000000000000..5bf4e846f0e26c47d2ea2dec71a63e188425878b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative5.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. + */ + +initModule( + +/* @@? 16:1 Error SyntaxError: initModule() only accept string literal as argument. */ +/* @@? 20:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bc35e5a51645f08e146a6df47374a86ebd24a1e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative6.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. + */ + +initModule) + +/* @@? 16:11 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 21:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 21:1 Error SyntaxError: Unexpected token, expected ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.ets new file mode 100644 index 0000000000000000000000000000000000000000..f91b70836f001ed2914c4084a54783c66d405b02 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative7.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. + */ + +/* @@ label */initmodule('./module_to_init.ets') + +/* @@@ label Error TypeError: Unresolved reference initmodule */ diff --git a/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.ets b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.ets new file mode 100644 index 0000000000000000000000000000000000000000..20adc6d8ff0fe764e5008a6caa7ac6a1ba22f2c4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/init_module_negative8.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. + */ + +initModule() + +/* @@? 16:1 Error SyntaxError: initModule() only accept string literal as argument. */ diff --git a/ets2panda/linter/test/interop/test_files/dummy_js_file.js b/ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets similarity index 98% rename from ets2panda/linter/test/interop/test_files/dummy_js_file.js rename to ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets index fa09fbb12c4a5fa47c104c1173cb88dafe4b78b0..98cc750cb772d154734be771ffbc91e8ae72f062 100644 --- a/ets2panda/linter/test/interop/test_files/dummy_js_file.js +++ b/ets2panda/test/ast/compiler/ets/init_module_tests/module_to_init.ets @@ -13,4 +13,4 @@ * limitations under the License. */ -export {} +let a = 10 diff --git a/ets2panda/test/ast/compiler/ets/initializer_block_namesapce04.ets b/ets2panda/test/ast/compiler/ets/initializer_block_namesapce04.ets new file mode 100644 index 0000000000000000000000000000000000000000..630cd8cdfcbf54c2ed70e538bf17b5be3ae95718 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/initializer_block_namesapce04.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 namespace xml { + static a: number = 1; + + static { + } + + static { + } +} + +/* @@? 17:3 Error SyntaxError: Unexpected token 'static'. */ +/* @@? 17:10 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 17:13 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:13 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 20:3 Error SyntaxError: Only one static block is allowed in one namespace or class. */ diff --git a/ets2panda/test/ast/compiler/ets/interface-constructor-signatures.ets b/ets2panda/test/ast/compiler/ets/interface-constructor-signatures.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d2fef2044422f716fa5e9d5d606f9ae3f04f37f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface-constructor-signatures.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. + */ + +//arkts-no-ctor-signatures-iface + +interface I { + new (s: string): I +} + +function fn(i: I) { + return new i("hello") +} + +/* @@? 19:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 19:5 Error SyntaxError: Constructor signatures are not supported in interfaces, use methods instead! */ +/* @@? 19:10 Error TypeError: Cannot find type 's'. */ +/* @@? 19:11 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 19:11 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 19:19 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 19:20 Error SyntaxError: Invalid Type. */ +/* @@? 19:20 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 19:20 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 20:1 Error SyntaxError: Invalid Type. */ +/* @@? 23:16 Error TypeError: Cannot find type 'i'. */ diff --git a/ets2panda/test/compiler/ets/throwingFunctionAsParameter1.ets b/ets2panda/test/ast/compiler/ets/interface_class_implement.ets similarity index 78% rename from ets2panda/test/compiler/ets/throwingFunctionAsParameter1.ets rename to ets2panda/test/ast/compiler/ets/interface_class_implement.ets index 523a7c09d068875cec1ac73a2d69eee48e7b8167..41591ce4089dd86e86832407cbfa58594684c120 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionAsParameter1.ets +++ b/ets2panda/test/ast/compiler/ets/interface_class_implement.ets @@ -13,12 +13,11 @@ * limitations under the License. */ -function RethrowingFunc(func: () => void throws): void rethrows { - func(); +interface AA { + X :int; } - -function NonThrowingFunc(func: () => void throws): void { - try { - func(); - } catch (e) {} +class A implements AA{ + static X :int=1; } + +/* @@? 19:22 Error TypeError: A is not abstract and does not implement getter for X property in AA */ diff --git a/ets2panda/test/compiler/ets/throwingFunctionCheck6.ets b/ets2panda/test/ast/compiler/ets/interface_class_implement_extend.ets similarity index 66% rename from ets2panda/test/compiler/ets/throwingFunctionCheck6.ets rename to ets2panda/test/ast/compiler/ets/interface_class_implement_extend.ets index 68e086afb3e8f065f9d7612bc7b1f389025e20ba..afa9486646466460e5f108d2f3bd33d13a6725d4 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionCheck6.ets +++ b/ets2panda/test/ast/compiler/ets/interface_class_implement_extend.ets @@ -13,21 +13,15 @@ * limitations under the License. */ -function TestFunction(): void throws { - throw new Exception(); +interface AA { + X :int; } - -class TestClass { - testMethod(): void throws { - throw new Exception(); - } +class A implements AA{ + static X :int=1; } +class extendA extends A{ -function main(): void { - let testClass = new TestClass(); - - try { - TestFunction(); - testClass.testMethod(); - } catch (e) {} } + +/* @@? 19:22 Error TypeError: A is not abstract and does not implement getter for X property in AA */ +/* @@? 22:24 Error TypeError: extendA is not abstract and does not implement getter for X property in AA */ diff --git a/ets2panda/test/ast/compiler/ets/interface_field.ets b/ets2panda/test/ast/compiler/ets/interface_field.ets new file mode 100644 index 0000000000000000000000000000000000000000..096043467c7aa7e7f7bd6921539ecab667f993ca --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_field.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. + */ + +interface Todo { + teTodo(todo1, { + description: string; + } + + function updateTodo(todo:Todo, fieldToUpdate: Partial) { + return {...todo, ...fieldToUpdate }; + } + +/* @@? 17:17 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:19 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:19 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:22 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 18:22 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 21:14 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 21:14 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 21:25 Error TypeError: Cannot find type 'todo'. */ +/* @@? 21:29 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 21:29 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 21:34 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 21:36 Error TypeError: Cannot find type 'fieldToUpdate'. */ +/* @@? 21:49 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 21:49 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 21:64 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 21:66 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 21:66 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 21:66 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 22:16 Error TypeError: need to specify target type for class composite */ +/* @@? 46:1 Error SyntaxError: Unexpected token, expected '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/interface_literal.ets b/ets2panda/test/ast/compiler/ets/interface_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..81abf38433fd699d44e761ef6cce2ef8f83c1812 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_literal.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. + */ + +interface I { + f(x: int): int; +} + +let f = (this: I, x: int): int => x; + +function main() { + let obj: I = { + /* @@ label */f: f + } + + let r: int = obj.f(5); + arktest.assertEQ(r, 5); +} + +/* @@@ label Error TypeError: Class or interface methods cannot be initialized within an object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets b/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e1f2336bc8e0e7072bd4937f46417dcdffc46c5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare function g(a: string): void; +let gg: (a: string)=>void = g; + +interface Obj { + method(value: T): void; +} + +declare const o1: Obj; + +gg = o1.method; + diff --git a/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment0.ets b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment0.ets new file mode 100644 index 0000000000000000000000000000000000000000..fb08582a043505cf12a14b95739f748eb276ae25 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment0.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 A{ + readonly name: string; +} + +function createA(): A{ + return /* @@ label */{}; +} + +/* @@@ label Error TypeError: Non-optional property 'name' in type 'A' is missing in object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment1.ets b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3dc305d1ea201da9dc2b75be86d59045fd842c20 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment1.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 {} + +interface X { + id: string; + nm: number; + a: A; +} + +function foo(x: X) {} +foo(/* @@ label */{}) + +/* @@@ label Error TypeError: Non-optional property 'a' in type 'X' is missing in object literal. */ +/* @@@ label Error TypeError: Non-optional property 'nm' in type 'X' is missing in object literal. */ +/* @@@ label Error TypeError: Non-optional property 'id' in type 'X' is missing in object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment2.ets b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ffe940d1f51460f1ff0d27041ac2037f1d2163cc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_object_literal_missing_assignment2.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 {} + +interface Y { + b: int; +} + +interface Z { + c: int; +} + +interface X extends Y, Z { + id?: string; + nm?: number; + a?: A; +} + +function foo(x: X) {} +foo(/* @@ label */{}) + +/* @@@ label Error TypeError: Non-optional property 'c' in super type 'Z' of type 'X' is missing in object literal. */ +/* @@@ label Error TypeError: Non-optional property 'b' in super type 'Y' of type 'X' is missing in object literal. */ diff --git a/ets2panda/test/ast/compiler/ets/interface_partial.ets b/ets2panda/test/ast/compiler/ets/interface_partial.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3f836c47b1a14c13b0265dba3a438f2ffd6c519 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_partial.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface I { + arr +} + +function foo (bar: Partial) { + if (bar.var_one != undefined) { + bar.var_one = "asddsf"; + } +} + +function main() { + let a : I = {var_one: "initial_var_one", var_two: "initial_var_two_a"}; + foo(a.var_one); + let a : I = {var_two: "initial_var_two_b"}; + foo(break.var_one); +} + +/* @@? 18:1 Error SyntaxError: Invalid Type. */ +/* @@? 21:13 Error TypeError: Property 'var_one' does not exist on type 'I$partial' */ +/* @@? 22:13 Error TypeError: Property 'var_one' does not exist on type 'I$partial' */ +/* @@? 27:18 Error TypeError: type I has no property named var_one */ +/* @@? 28:11 Error TypeError: Property 'var_one' does not exist on type 'I' */ +/* @@? 29:9 Error TypeError: Variable 'a' has already been declared. */ +/* @@? 29:18 Error TypeError: type I has no property named var_two */ +/* @@? 30:9 Error SyntaxError: Unexpected token 'break'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/interface_property_scope.ets b/ets2panda/test/ast/compiler/ets/interface_property_scope.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c8647af1e83986f2993a93f6fd6f0e77c54dc70 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_property_scope.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. + */ + +@Anno +interface itf0{ + @Anno(()=> {testList.subArrayList(0, 1)}, exceptionCherckEmptyContainer) +} + +/* @@? 16:2 Error TypeError: Cannot find type 'Anno'. */ +/* @@? 18:6 Error TypeError: Cannot find type 'Anno'. */ +/* @@? 18:11 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 18:45 Error SyntaxError: Expected ')', got ','. */ +/* @@? 18:45 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:76 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 19:1 Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets index 8615346ac52905f297cd38609556912d987fbc88..260287ee8be8c7b82885277472210700cc56ef59 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets @@ -31,8 +31,8 @@ class B extends /* @@ label */C { function main(): void { let instance: B = new B(); - assertEQ(instance.getX(), true); + arktest.assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets index f9dca621954df878d50e2c74d44fed6eb06ddf5f..75c6af1ac9d660e384e24d9e0cb4058ac09ecedf 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets @@ -31,8 +31,8 @@ class B extends /* @@ label */C { function main(): void { let instance: B = new B(); - assertEQ(instance.getX(), true); + arktest.assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets index 0569baa08c6615248693cf6056dcee7abac36f4e..966bca830e5d056e84a030ff4456df392c05bc50 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets @@ -28,7 +28,7 @@ class B extends /* @@ label */A { function main(): void { let instance: B = new B(); - assertEQ(instance.getX(), true); + arktest.assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class A, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets index f06ab002a2367dcffcc54d02d60bab06a2738654..c406f86f399ac7ed8345888492e85079694ff92f 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets @@ -28,7 +28,7 @@ class B implements A { function main(): void { let instance: B = new B(); - assertEQ(instance.getX(), true); + arktest.assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from interface A because field x is inherited with a different declaration type */ 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_access_modifier.ets b/ets2panda/test/ast/compiler/ets/invalid_access_modifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..14f2dbbba75c0962f18f779e8cfb20e5f98ccfb7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_access_modifier.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{ + private \\\\foo(){} +} + +/* @@? 17:13 Error SyntaxError: Invalid character. */ +/* @@? 17:13 Error SyntaxError: Access modifier must precede field and method modifiers. */ +/* @@? 17:14 Error SyntaxError: Invalid character. */ +/* @@? 17:14 Error SyntaxError: Access modifier must precede field and method modifiers. */ +/* @@? 17:15 Error SyntaxError: Invalid character. */ +/* @@? 17:15 Error SyntaxError: Access modifier must precede field and method modifiers. */ +/* @@? 17:16 Error SyntaxError: Invalid character. */ +/* @@? 17:16 Error SyntaxError: Access modifier must precede field and method modifiers. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_0.ets b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..eaf899d40ce736f4e64719fe4919d3b676c2395e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_0.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() { + let x = 1 as T; +} + +/* @@? 17:13 Error TypeError: Cannot cast type 'Int' to 'T' */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_1.ets b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..030e6da0b06a8c20bc58d7100e22d6e31199acce --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_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() { + let x = 1 as (T | U); +} + +/* @@? 17:13 Error TypeError: Cannot cast type 'Int' to 'T|U' */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_2.ets b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..728f82f7f6b29c0eec9cdb4010f5054f0447828c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_cast_generic_type_neg_2.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(v: X = 1 as (X | Y)){} + +/* @@? 16:55 Error TypeError: Cannot cast type 'Int' to 'X|Y' */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets b/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets new file mode 100644 index 0000000000000000000000000000000000000000..082a7347c6f729257514aa07347da03dc9bc3cd8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Integral {} +class Numeric {} + +/* @@? 1:3 Error TypeError: Class 'Integral' is already defined. */ +/* @@? 1:3 Error TypeError: Class 'Numeric' is already defined. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_namespace_neg.ets b/ets2panda/test/ast/compiler/ets/invalid_namespace_neg.ets index 3a3ae02f869b5bfc07333b74e406c097b888fa2a..2f3707f2acf87959d1beed916ef47f23830e600c 100644 --- a/ets2panda/test/ast/compiler/ets/invalid_namespace_neg.ets +++ b/ets2panda/test/ast/compiler/ets/invalid_namespace_neg.ets @@ -24,3 +24,4 @@ namespace C{ } /* @@@ label1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 28:1 Error SyntaxError: Unexpected token. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_object.ets b/ets2panda/test/ast/compiler/ets/invalid_object.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d2e5fb2a110538949a686b1fc8e2bd36a626bf3 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_object.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface Obj {} +const object1: Obj = {}; + +console.log(Objˆct.keys(object1)); + +/* @@? 19:13 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 19:13 Error TypeError: Class or interface 'Obj' cannot be used as object */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:16 Error SyntaxError: Unexpected token 'ˆct'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:16 Error TypeError: Unresolved reference ˆct */ +/* @@? 19:33 Error SyntaxError: Unexpected token ')'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/invalid_param_in_constructor.ets b/ets2panda/test/ast/compiler/ets/invalid_param_in_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..c24f12ba1649dff7a22b5774705262a5d6537897 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_param_in_constructor.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 { + constructor(this.b) { + } +} + +/* @@? 17:16 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:21 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:23 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:23 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:25 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_param_pack.ets b/ets2panda/test/ast/compiler/ets/invalid_param_pack.ets new file mode 100644 index 0000000000000000000000000000000000000000..0ef867033bb85c3592807d5eb5e3dc68aa48014a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_param_pack.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 Base { + constructor(...args) { + + } +} + +class Derived extends Base{ + constructor(){ + super(3); + } +} + +class Base2 { + my_func(...args) { + + } +} + +class Derived2 extends Base2{ + constructor(){ + my_func(3); + } +} + +/* @@? 17:17 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 17:24 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 29:13 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 29:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 36:3 Error TypeError: Property 'my_func' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets b/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..37691e50670c5c93f75b8ef5f610117ed00e3e9c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let a = foo() { + switch (x) { + "unreachable" + } +} + +/* @@? 16:9 Error TypeError: Unresolved reference foo */ +/* @@? 16:9 Error TypeError: This expression is not callable. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'string literal', expected 'case' or 'default'. */ +/* @@? 18:9 Error SyntaxError: Expected ':', got 'string literal'. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_token.ets b/ets2panda/test/ast/compiler/ets/invalid_token.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d30da416f29ef79a62fb6ce05896035530a5498 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_token.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + bit1: int =< 2 +} + +/* @@? 17:18 Error SyntaxError: Number, string or computed value property name '2' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 17:18 Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 17:18 Error SyntaxError: Unexpected token '2'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token, expected '>'. */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_trailing_lambda_call.ets b/ets2panda/test/ast/compiler/ets/invalid_trailing_lambda_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..809db2982bd6913f758065d709a71d777fb7df48 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_trailing_lambda_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. + */ + +function foo1(p:Any){} +function foo2(p:Required){} +function foo3(p:Partial){} +function foo4(p:Readonly){} +function foo5(p:FixedArray){} + +foo1(){} +foo2(){} +foo3(){} +foo4(){} +foo5(){} + +/* @@? 17:17 Error SyntaxError: 'Required' is reserved and cannot be used as a variable/type name */ +/* @@? 18:17 Error SyntaxError: 'Partial' is reserved and cannot be used as a variable/type name */ +/* @@? 19:17 Error SyntaxError: 'Readonly' is reserved and cannot be used as a variable/type name */ +/* @@? 20:17 Error TypeError: FixedArray must have only one type parameter. */ +/* @@? 23:1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 23:1 Error TypeError: No matching call signature */ +/* @@? 24:1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 24:1 Error TypeError: No matching call signature */ +/* @@? 25:1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 25:1 Error TypeError: No matching call signature */ +/* @@? 26:1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 26:1 Error TypeError: No matching call signature */ \ No newline at end of file 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..f4850751e54e1f9d72894560bd436e6a932569d9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_two_functions.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 () {})(); + +const a = [1]; +const b = a.map(function (e) { + return e * 2; +}); + +/* @@? 16:2 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:17 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:28 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ diff --git a/ets2panda/test/ast/compiler/ets/iterabletypes_with_protected_iterator_neg.ets b/ets2panda/test/ast/compiler/ets/iterabletypes_with_protected_iterator_neg.ets index 67afe865b4f3de727e7e69b1bf495364fad893ab..64cce0d8f4cba279e99989553bb0c93278389d2c 100644 --- a/ets2panda/test/ast/compiler/ets/iterabletypes_with_protected_iterator_neg.ets +++ b/ets2panda/test/ast/compiler/ets/iterabletypes_with_protected_iterator_neg.ets @@ -38,7 +38,7 @@ class A { function main(): int { let a = new A; for(let it of a) { - assertEQ(it, a.data[idx]); + arktest.assertEQ(it, a.data[idx]); ++idx; } return 0; diff --git a/ets2panda/test/ast/compiler/ets/keyof_invalid_argument.ets b/ets2panda/test/ast/compiler/ets/keyof_invalid_argument.ets new file mode 100644 index 0000000000000000000000000000000000000000..5edd48126e4922f1439ab8a08ec0c2294b004999 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/keyof_invalid_argument.ets @@ -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. + */ + +function foo(t: T | {}, k: keyof (T | {})) {} + +class ObservableImpl extends Observable { + extendObservable(extraProps: U) { + new ObservableImpl<{ [K in keyof (T & U)]: (T & U)[K] }>(); + } +} + +type NestedKey = T[K] extends object ? keyof T[K] : never; + +/* @@? 16:24 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 16:42 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 16:45 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 18:33 Error TypeError: Cannot find type 'Observable'. */ +/* @@? 18:33 Error TypeError: The super type of 'ObservableImpl' class is not extensible. */ +/* @@? 20:24 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 20:27 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 20:31 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:41 Error SyntaxError: Unexpected token '&'. */ +/* @@? 20:41 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 20:41 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 20:44 Error SyntaxError: Unexpected token ')'. */ +/* @@? 20:44 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:45 Error SyntaxError: Unexpected token ']'. */ +/* @@? 20:46 Error SyntaxError: Unexpected token ':'. */ +/* @@? 20:48 Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ +/* @@? 20:51 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 20:51 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 20:51 Error SyntaxError: Unexpected token '&'. */ +/* @@? 20:54 Error SyntaxError: Unexpected token ')'. */ +/* @@? 20:54 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:56 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 20:57 Error SyntaxError: Unexpected token ']'. */ +/* @@? 24:36 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 24:42 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 24:42 Error SyntaxError: Unexpected token ']'. */ +/* @@? 24:43 Error SyntaxError: Unexpected token ']'. */ +/* @@? 24:45 Error SyntaxError: Unexpected token 'extends'. */ +/* @@? 24:53 Error SyntaxError: Unexpected token 'object'. */ +/* @@? 24:53 Error TypeError: Type name 'object' used in the wrong context */ +/* @@? 24:62 Error TypeError: Unresolved reference keyof */ +/* @@? 24:68 Error SyntaxError: Unexpected token. */ +/* @@? 24:68 Error TypeError: Unresolved reference T */ +/* @@? 24:68 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 24:70 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 24:73 Error SyntaxError: Unexpected token ':'. */ +/* @@? 24:75 Error SyntaxError: Class cannot be used as object. */ +/* @@? 24:75 Error SyntaxError: Unexpected token 'never'. */ diff --git a/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_super.ets b/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_super.ets new file mode 100644 index 0000000000000000000000000000000000000000..a12fa1c5d2bd10580c3ef38e9a24c72fadeac8d7 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_super.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 namespace super { + +} + +/* @@? 16:19 Error SyntaxError: Hard keyword 'super' cannot be used as identifier */ +/* @@? 16:19 Error SyntaxError: Identifier expected, got 'super'. */ diff --git a/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_this.ets b/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_this.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6aabb12a709d01fcd38599436dbb7c76033b43 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/keywords/issue26215_restricted_this.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 namespace this { + +} + +/* @@? 16:19 Error SyntaxError: Hard keyword 'this' cannot be used as identifier */ +/* @@? 16:19 Error SyntaxError: Identifier expected, got 'this'. */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets index b9c050c4e869727ed02a74c64eb4d352a44a491c..30a62660c775183180d4244cbeb030778b1cd7f3 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets @@ -22,4 +22,4 @@ function main(): void { test1() } -/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaFunction4.ets b/ets2panda/test/ast/compiler/ets/lambdaFunction4.ets index cf2c48260b3a3d374bc8baa253bbda9c85611f40..80a0e01511a336aaef39c6ce3bdd93b9de0deb31 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaFunction4.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaFunction4.ets @@ -16,9 +16,13 @@ class A { b: String = "foo"; - a: () => void = (): void => { - /* @@ label */this.b++; + a: () => void; + + constructor() { + this.a = (): void => { + /* @@ label */this.b++; + } } } -/* @@@ label Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@@ label Error TypeError: Bad operand type, the type of the operand must be numeric type. */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets index bfd45ae78cc38b365c4b92910655798dd3185a9c..bfd7f381cf4d94025fa1d7a14600d33beb3e8e62 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets @@ -16,9 +16,7 @@ class A { c = 1; - a: (a: int, b: int) => int = (a: int, b:int): int => { - return a + b + this.c; - } + a: (a: int, b: int) => int; foo(): (b: int, c: int) => int { return this.a; @@ -27,6 +25,12 @@ class A { foo(d: int): (b: int, c: int) => int { return this.a; } + + constructor() { + this.a = (a: int, b:int): int => { + return a + b + this.c; + }; + } } function main(): void { @@ -35,5 +39,5 @@ function main(): void { /* @@ label */a.foo(1)(1, /* @@ label1 */"foo"); } -/* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ +/* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ 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_infer.ets b/ets2panda/test/ast/compiler/ets/lambda_type_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..4d36df1ca7cdaf2df4fe90853b2d24e9bbdb79b8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/lambda_type_infer.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 Config { + arr: Array; +} + +const words: string[] = ["a_"]; + +const config: Config = { + arr: words.map(k => { +        const result: string = k.replace("_", ""); +        return result; +    }), +}; diff --git a/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_type.ets b/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a449142937d531082b2386380346a1e3776f39b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_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. + */ + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T + +testRest((t1:number, t2:boolean, t3) => {}) + +/* @@? 18:10 Error TypeError: Type '(t1: Double, t2: Boolean, t3: never) => void' is not compatible with type '(t: never, t1: never, ...ts: Array) => void' at index 1 */ 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/lambda_type_param_bad.ets b/ets2panda/test/ast/compiler/ets/lambda_type_param_bad.ets new file mode 100644 index 0000000000000000000000000000000000000000..00bb1430370a58913998bc5533c15690c43b8485 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/lambda_type_param_bad.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 AA { + build() { + const classA = new A(); + classA.a<(sr: number) => void>((sr: string) => { + console.log(sr + " In Class AA" ) + }) + } +} + +class A { + a(a3: T) : void { + a3.unsafeCall("Hello"); + } +} + +/* @@? 19:40 Error TypeError: Type '(sr: String) => void' is not compatible with type '(sr: Double) => void' at index 1 */ 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/parser/ets/localTypeAlias.ets b/ets2panda/test/ast/compiler/ets/localTypeAlias.ets similarity index 46% rename from ets2panda/test/parser/ets/localTypeAlias.ets rename to ets2panda/test/ast/compiler/ets/localTypeAlias.ets index 6f166b67131a4768cb7a4044e2c7143108c54e92..406e90965e049f7f67c9fbfd6975ca9a4198ea38 100644 --- a/ets2panda/test/parser/ets/localTypeAlias.ets +++ b/ets2panda/test/ast/compiler/ets/localTypeAlias.ets @@ -75,3 +75,31 @@ function foo(){ } } + + /* @@? 17:16 Error TypeError: Cannot find type 'a'. */ + /* @@? 19:5 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 21:13 Error TypeError: Cannot find type 'a'. */ + /* @@? 30:13 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 31:23 Error TypeError: Cannot find type 'dsa'. */ + /* @@? 34:22 Error TypeError: Cannot find type 'asd'. */ + /* @@? 37:13 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 41:19 Error TypeError: Cannot find type 'asd'. */ + /* @@? 42:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 43:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 44:19 Error TypeError: Cannot find type 'dsa'. */ + /* @@? 48:19 Error TypeError: Cannot find type 'asd'. */ + /* @@? 49:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 50:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 51:19 Error TypeError: Cannot find type 'dsa'. */ + /* @@? 56:19 Error TypeError: Cannot find type 'asd'. */ + /* @@? 57:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 59:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 60:19 Error TypeError: Cannot find type 'dsa'. */ + /* @@? 64:19 Error TypeError: Cannot find type 'asd'. */ + /* @@? 65:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 67:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 68:19 Error TypeError: Cannot find type 'dsa'. */ + /* @@? 70:19 Error TypeError: Cannot find type 'asd'. */ + /* @@? 71:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 73:9 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 74:19 Error TypeError: Cannot find type 'dsa'. */ diff --git a/ets2panda/test/runtime/ets/local_enum02.ets b/ets2panda/test/ast/compiler/ets/local_enum02.ets similarity index 72% rename from ets2panda/test/runtime/ets/local_enum02.ets rename to ets2panda/test/ast/compiler/ets/local_enum02.ets index fbb512fb24772439d353f47443ee2237bbca8d8e..43b006318a74b9acfae22a330d6f9e6b6214b542 100644 --- a/ets2panda/test/runtime/ets/local_enum02.ets +++ b/ets2panda/test/ast/compiler/ets/local_enum02.ets @@ -19,8 +19,11 @@ function main() { { enum Foo {Baz, Bar} - assertEQ(Foo.Bar as int, 1) + arktest.assertEQ(Foo.Bar as int, 1) } - assertEQ(Foo.Bar as int, 0) -} \ No newline at end of file + arktest.assertEQ(Foo.Bar as int, 0) +} + +/* @@? 21:7 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 22:24 Warning Warning: Enum cast is deprecated. Cast support from 'Foo' to 'Int' will be removed. */ diff --git a/ets2panda/test/runtime/ets/local_enum03.ets b/ets2panda/test/ast/compiler/ets/local_enum03.ets similarity index 78% rename from ets2panda/test/runtime/ets/local_enum03.ets rename to ets2panda/test/ast/compiler/ets/local_enum03.ets index c72b0c2e155ef8005b1180a83c88b49be1d48b8b..0b08ef92588064ddf597463ac384112d9380b789 100644 --- a/ets2panda/test/runtime/ets/local_enum03.ets +++ b/ets2panda/test/ast/compiler/ets/local_enum03.ets @@ -17,7 +17,10 @@ function main() { const a : int = 1; const b : int = 2 + a; enum Foo {Baz = a, Bar = b} - assertEQ(Foo.Bar, 3) + arktest.assertEQ(Foo.Bar, 3) - assertEQ(Foo.Baz, 1) -} \ No newline at end of file + arktest.assertEQ(Foo.Baz, 1) +} + + /* @@? 19:5 Error SyntaxError: Illegal start of ENUM expression. */ + /* @@? 20:22 Error TypeError: Unresolved reference Foo */ 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 9c7a8b2ce24dc5bd0c788e3cd69d762b1389c544..ef222fcc9f772058479b15c4bb03e777c2d78d67 100644 --- a/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets +++ b/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets @@ -26,6 +26,6 @@ function foo1() { /* @@? 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: Hard keyword 'undefined' cannot be used as identifier */ /* @@? 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/method-assignment.ets b/ets2panda/test/ast/compiler/ets/method-assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bf46b3b8dda5d946381769cc48228a96d5c63f8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/method-assignment.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 Base { + baseFoo() {} + static staticBaseFoo() {} +} + +interface I { + interfaceFoo() {} +} + +class C extends Base implements I { + foo1() {} + static foo2() {} + + constructor() + { + this.interfaceFoo = bar; + } + + constructor(arg: () => void) + { + this.foo1 = arg; + } +} + +function bar() {} + +let c = new C(); +c = new C(bar); +c.baseFoo = bar; +C.staticBaseFoo = bar; +c.foo1 = bar; +C.foo2 = bar; +c.interfaceFoo = bar; + +/* @@? 31:9 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 36:9 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 44:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 45:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 46:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 47:1 Error TypeError: Class methods cannot be overwritten. */ +/* @@? 48:1 Error TypeError: Class methods cannot be overwritten. */ diff --git a/ets2panda/test/ast/compiler/ets/method-assignment_01.ets b/ets2panda/test/ast/compiler/ets/method-assignment_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..e572ac69815632aed7ffc03ff74b38256c06a75f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/method-assignment_01.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 { + f(): void { + console.println("OK"); + } +} + +let f = (this: A): void => { + throw new Error("Boom"); +} + +function main() { + let a: A = new A(); + + /* @@ label */a.f = f; + + try { + a.f(); + f(a); + } catch (e) { + if (e instanceof Error) { + arktest.assertEQ(e.message, "Boom"); + } + } +} + +/* @@@ label Error TypeError: Class methods cannot be overwritten. */ diff --git a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets index 0f6a071170465cd24d97af4a831c43a19eee7a7f..670b535d0dfbde90170c8bdfd09eb0d3b7271fb5 100644 --- a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets +++ b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets @@ -42,4 +42,6 @@ function main(): int { let asd5: double = /* @@ label */foo(new A(), 2.1); return 0; } -/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: double): double` and `foo(a: I, d: double): double` */ +/* @@? 38:21 Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(b: Int, a: I): Int` and `foo(d: Double, a: J): Double` */ +/* @@? 41:21 Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: I, b: Int): Int` and `foo(a: J, d: Double): Double` */ +/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: Double): Double` and `foo(a: I, d: Double): Double` */ diff --git a/ets2panda/test/ast/compiler/ets/method_call_confilict_in_union_types.ets b/ets2panda/test/ast/compiler/ets/method_call_confilict_in_union_types.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0a65edf47dc84a2349095ad711a68459f59cfa2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/method_call_confilict_in_union_types.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 { + foo under the licenses { } + foo(v: int): void {} +} + +class B { + foo(v: string): void { } +} + +function foo(x: A | B) { + x.foo("123") +} + +/* @@? 17:8 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:14 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:18 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:27 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:28 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:9 Error TypeError: Unresolved reference v */ +/* @@? 18:10 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:10 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:12 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:18 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 18:23 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/method_error_identifier.ets b/ets2panda/test/ast/compiler/ets/method_error_identifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ccc87265748fcb23d0d70e5fcd589d70efe5b7c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/method_error_identifier.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. + */ + +void function () { }; + +class BindFuncExpr { + let callback1 = function () { } + callback1 = callback1 || function () { } +} + +/* @@? 16:1 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 16:6 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:5 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 19:21 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 20:5 Error TypeError: Variable 'callback1' has already been declared. */ +/* @@? 20:17 Error TypeError: Unresolved reference callback1 */ +/* @@? 20:30 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ diff --git a/ets2panda/test/ast/compiler/ets/missing_CTE_access_private.ets b/ets2panda/test/ast/compiler/ets/missing_CTE_access_private.ets new file mode 100644 index 0000000000000000000000000000000000000000..d37040e3380b5cb6f0b29678d209f0b1a020e71c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/missing_CTE_access_private.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 A { + private static _val: number = 0; + private static get val(): number { return A._val; } + private static set val(i: number) { + A._val = i + } +} + +function main(): void { + let j: number = A.val + A.val = 1 +} + +/* @@? 25:23 Error TypeError: Signature val(): Double is not visible here. */ +/* @@? 26:7 Error TypeError: Signature val(i: Double): void is not visible here. */ diff --git a/ets2panda/test/ast/compiler/ets/missing_CTE_access_protected.ets b/ets2panda/test/ast/compiler/ets/missing_CTE_access_protected.ets new file mode 100644 index 0000000000000000000000000000000000000000..fb1fd6164735e48aad35f2fcaf14f8823c2493cd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/missing_CTE_access_protected.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 A { + protected static _val: number = 0; + protected static get val(): number { return A._val; } + protected static set val(i: number) { + A._val = i + } +} + +function main(): void { + let j: number = A.val + A.val = 1 +} + +/* @@? 25:23 Error TypeError: Signature val(): Double is not visible here. */ +/* @@? 26:7 Error TypeError: Signature val(i: Double): void is not visible here. */ 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..28f72a3b38e091de51b2ab1f7ab3cd66e6988b54 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:12 Error TypeError: Function met with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets b/ets2panda/test/ast/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets index d2cac0dc0b4062d77984a6fb8dbd69dd8feaa9a6..7650215aa64b566b915174ad7903c0cc950b19fc 100644 --- a/ets2panda/test/ast/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets +++ b/ets2panda/test/ast/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets @@ -18,7 +18,8 @@ class B {} function main(): void { let abn : A = /* @@ label */new A(); // should not work: non nullable B is the subtype of nullable B, but T has no variance mark - let ab : A = abn; // should not work: nullable B (the type of abn) is not the subtype of non nullable B + let ab : A = /* @@ label1 */abn; // should not work: nullable B (the type of abn) is not the subtype of non nullable B } /* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'A' */ +/* @@@ label1 Error TypeError: Type 'A' cannot be assigned to type 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/nagative_trailingLambda_abort.ets b/ets2panda/test/ast/compiler/ets/nagative_trailingLambda_abort.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d6b629fdcde5f67aea7e4bce2c4c0ae628d71e9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nagative_trailingLambda_abort.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. + */ + +*22Array() { + let callback = (arrElem: JSValue) => { + if (arrElem as string !== expectedArr[idx]) {} + console.log(`fasdfasdfafd:`); + console.log(`arrElem = ${arrElem}, expectedArr[${idx}] = ${expan xxxxse istribumptyArr agreed ) + itations undeectedArr[idx]}`); + result = false; + return; + } + result = true; + idx++; + 222222??222.27?22dXX2222 + +/* @@? 16:1 Error SyntaxError: Unexpected token '*'. */ +/* @@? 16:2 Error SyntaxError: Unexpected token '22'. */ +/* @@? 16:4 Error SyntaxError: Unexpected token 'Array'. */ +/* @@? 16:4 Error TypeError: No matching call signature with trailing lambda */ +/* @@? 20:74 Error SyntaxError: Expected '}', got 'identification literal'. */ +/* @@? 27:5 Error TypeError: Wrong type of operands for binary expression */ +/* @@? 27:22 Error SyntaxError: Unexpected token. */ +/* @@? 37:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/namespaceExport_neg.ets b/ets2panda/test/ast/compiler/ets/namespaceExport_neg.ets index e742a4cdc820877914a2ce0aaade1f4ab7910b05..fb3ea3bbd88e3a272e2f97495859f8006f8b68a8 100644 --- a/ets2panda/test/ast/compiler/ets/namespaceExport_neg.ets +++ b/ets2panda/test/ast/compiler/ets/namespaceExport_neg.ets @@ -30,5 +30,3 @@ declare namespace A { } export default A -/* @@? 27:20 Error SyntaxError: Cannot export 'A', it was already exported. */ - diff --git a/ets2panda/test/ast/compiler/ets/namespace_class_decl.ets b/ets2panda/test/ast/compiler/ets/namespace_class_decl.ets new file mode 100644 index 0000000000000000000000000000000000000000..2cc3edecb5c61fb2f3d33b2a400e3ac6e0ecf0fe --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/namespace_class_decl.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. + */ + +namespace testing { + export class Array { + $_get(index: number): Array {return this;} + $_set(index: number, value: Array) {} + } + export class ReadonlyArray { + $_get(index: number): ReadonlyArray {return this;} + $_set(index: number, value: ReadonlyArray) {} + } + export class ConcatArray { + this.tabInfo.recentCount--; + +} + export class ArrayLike { + $_get(index: number): ArrayLike {return this;} + $_set(index: number, value: ArrayLike) {} + } +} + +namespace testing2 { + export class Array {[x: number]: any} + export class ReadonlyArray {[x: number]: any} + export class ConcatArray {[x: number]: any} + export class ArrayLike {[x: number]: any} +} + +function retA() { + let a: Array = [1,2,3]; + let b: ReadonlyArray = [1,2,3]; + let c: ConcatArray = [1,2,3]; + let d: ArrayLike = [1,2,3]; +} + +function retB() { + let a = new testing.Array(); + let b = new testing.ReadonlyArray(); + let c = new testing.ConcatArray(); + let d = new testing.ArrayLike(); +} + +function retC() { + let a = new testing2.Array(); + let b = new testing2.ReadonlyArray(); + let c = new testing2.ConcatArray(); + let d = new testing2.ArrayLike(); +} + +/* @@? 26:13 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 26:17 Error SyntaxError: Unexpected token '.'. */ +/* @@? 26:25 Error SyntaxError: Field type annotation expected. */ +/* @@? 26:25 Error SyntaxError: Unexpected token '.'. */ +/* @@? 26:37 Error SyntaxError: Field type annotation expected. */ +/* @@? 26:37 Error SyntaxError: Unexpected token '--'. */ +/* @@? 36:29 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 37:37 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 38:35 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 39:33 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 45:34 Error TypeError: Type 'Array' cannot be assigned to type 'ConcatArray' */ +/* @@? 46:32 Error TypeError: Type 'Array' cannot be assigned to type 'ArrayLike' */ diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets b/ets2panda/test/ast/compiler/ets/namespace_import/namespace_import1.ets similarity index 85% rename from ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets rename to ets2panda/test/ast/compiler/ets/namespace_import/namespace_import1.ets index 04eeeb8969692e0bcd2becb26ad2df9437c05370..00da04ded574c1c7722cc3dc9b8b0c06915f9c40 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_import/namespace_import1.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -specialAutofixLib.debugger(); +import * as ns2 from "./namespace_import2" -function a() { - specialAutofixLib.debugger(); +export function A() { + return ns2.A() } -console.log('debugger'); \ No newline at end of file +export let a = 1 \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/namespace_import/namespace_import2.ets b/ets2panda/test/ast/compiler/ets/namespace_import/namespace_import2.ets new file mode 100644 index 0000000000000000000000000000000000000000..07c0f8d1240e845f3ff06f5f43f5e48d3835d009 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/namespace_import/namespace_import2.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 * as ns1 from "./namespace_import1" + +export function A() { + return ns1.a; +} \ No newline at end of file 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_static_block_init_neg.ets b/ets2panda/test/ast/compiler/ets/namespace_static_block_init_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..282ee1ede5c25a91d9259c0b3168feff8d80db5e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/namespace_static_block_init_neg.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. + */ + +namespace NS { + let ss: string; + static { + ss = /* @@ label */ss + "Hi! Static block init!!" + } +} + +/* @@@ label Error TypeError: Property 'ss' is used before being assigned. */ 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_import_conflicts.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets index c81755739a2c0f0ced224c74ede4f029d0bbc986..0b828cc1314b15196cbd5d573b50bf5d370f12f3 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets @@ -24,6 +24,6 @@ Space1.foo(); // CTE Space1.foo(1234); //ok /* @@? 19:31 Error TypeError: Property 'constant' does not exist on type 'Space2' */ -/* @@? 20:23 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 20:23 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? 23:1 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 23:1 Error TypeError: No matching call signature */ 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..89f6b4e6767cf39c411f58affdcda7919e680fb0 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 @@ -19,6 +19,4 @@ namespace MySpace { 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 +/* @@? 19:22 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_type11.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.ets index fdef3178fe307b3cd54768787c50cb0b0ef1adf6..eb120df6c800b66d7b563804f51d40b13b6b4ec7 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 @@ -18,5 +18,4 @@ 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 */ +/* @@@ label Error SyntaxError: Namespace cannot be used as object. */ diff --git a/ets2panda/test/ast/compiler/ets/negative_optional_constructor.ets b/ets2panda/test/ast/compiler/ets/negative_optional_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..f38f0c8d9deab4aa9c5463a0313c20dbb497607f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/negative_optional_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 A { + constructor(buffer: ArrayBuffer, byteOffset?: number, length?V number); + +/* @@? 17:3 Error TypeError: No matching call signature for constructor */ +/* @@? 17:14 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:64 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:64 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:65 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:66 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ +/* @@? 17:72 Error SyntaxError: Unexpected token ')'. */ +/* @@? 28:1 Error SyntaxError: Expected '}', got 'end of stream'. */ + diff --git a/ets2panda/test/ast/compiler/ets/negative_typo_1.ets b/ets2panda/test/ast/compiler/ets/negative_typo_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..a50b132cbe178f2847ca4e1a4703031927213d8c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/negative_typo_1.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 Anno { + e: @ring[][] = [["a", (c +ue)]] +} + +/* @@? 17:3 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ +/* @@? 17:7 Error TypeError: Cannot find type 'ring'. */ +/* @@? 17:18 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 17:19 Error TypeError: Initializer has 2 elements, but tuple requires 0 */ diff --git a/ets2panda/test/ast/compiler/ets/never_type_cast.ets b/ets2panda/test/ast/compiler/ets/never_type_cast.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe13b872f6e5cd6f397c8274a2570f0affe4b079 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/never_type_cast.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() { + let input = true; + if (input instanceof Boolean) { + console.log("This is a test function"); + } else { + let b = input as (string | number | null); + console.log("This is a test function with b: " + b); + } +} +foo(); + +/* @@? 21:17 Error TypeError: Cannot cast type 'Boolean' to 'String|Double|null' */ diff --git a/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets b/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc623f5b1a689d1c917e12b9ccc794f136cec3fa --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +importet lock1 = new ArkTSUt../main; + +/* @@? 16:1 Error TypeError: Unresolved reference importet */ +/* @@? 16:10 Error SyntaxError: Unexpected token 'lock1'. */ +/* @@? 16:10 Error TypeError: Unresolved reference lock1 */ +/* @@? 16:18 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 16:30 Error SyntaxError: Identifier expected. */ +/* @@? 16:31 Error SyntaxError: Identifier expected. */ +/* @@? 16:31 Error TypeError: Invalid type reference. */ diff --git a/ets2panda/test/ast/compiler/ets/noInOperator.ets b/ets2panda/test/ast/compiler/ets/noInOperator.ets new file mode 100644 index 0000000000000000000000000000000000000000..27aa68a1ccfc0200e99df36f86cc1f831246ce6c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/noInOperator.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 Person { + name: string = "" +} +let p = new Person() +let b = "name" /* @@ label1 */in p +let c = "name" /* @@ label2 */in {name: 1, some: 2} +let d = 2 /* @@ label3 */in [44, 55] + +/* @@@ label1 Error SyntaxError: 'in' operator is not supported. Use 'instanceof' operator to check whether an object is the instance of a class that contains the necessary class member. */ +/* @@@ label2 Error SyntaxError: 'in' operator is not supported. Use 'instanceof' operator to check whether an object is the instance of a class that contains the necessary class member. */ +/* @@@ label3 Error SyntaxError: 'in' operator is not supported. Use 'instanceof' operator to check whether an object is the instance of a class that contains the necessary class member. */ diff --git a/ets2panda/test/ast/compiler/ets/noIsOperator.ets b/ets2panda/test/ast/compiler/ets/noIsOperator.ets new file mode 100644 index 0000000000000000000000000000000000000000..01aab8be00bebc248ad84b18a2ac294668c3e25c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/noIsOperator.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 isString(test: string): test /* @@ label */is string { + return typeof test === "string"; +} + +/* @@@ label Error SyntaxError: 'is' operator is not supported. Use 'instanceof' instead to check whether a variable is instance of a given type and use 'as' operator to cast to the appropriate type! */ diff --git a/ets2panda/test/ast/compiler/ets/no_match_sig.ets b/ets2panda/test/ast/compiler/ets/no_match_sig.ets new file mode 100644 index 0000000000000000000000000000000000000000..ac70bf305df8d8abcd844b96e070bed282991a00 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/no_match_sig.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 main() { + foo() +} + +function foo1(a: number, b: number) { + return "aaaa" +} + +function foo2(a: number, ...args: number[]) { + return "bbbb" +} + +function foo3(a: number, b: number, c?: number) { + return "cccc" +} + +overload foo{ foo1, foo2, foo3 } + +/* @@? 17:5 Error TypeError: No matching call signature for foo() */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/nonNullableKeyword.ets b/ets2panda/test/ast/compiler/ets/nonNullableKeyword.ets new file mode 100644 index 0000000000000000000000000000000000000000..d58ca014b280e98992adbbea042e4c85c21be64f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullableKeyword.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{ + NonNullable = 1; +} + +class B{ + static NonNullable(param:T){} +} + +B.NonNullable(new Object()) + +class NonNullable{} + +/* @@? 27:7 Error SyntaxError: Cannot be used as user-defined type. */ diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType.ets b/ets2panda/test/ast/compiler/ets/nonNullishType.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbc688cdf6a24385c9699c278a710e2af00f08aa --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType.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 NonNullableGenericParam> { + foo(a: T):NonNullable{ + return a; + } +} + +class A{} + +type TesterUnionType = Int | A | null | undefined +type NonNullableTesterUnionType = NonNullable + +function main(){ + let a: NonNullable; + a = new A(); + let b: NonNullable> = new Object(); +} + +function foo(param:NonNullable){ + let a: Object = param +} diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType_n_1.ets b/ets2panda/test/ast/compiler/ets/nonNullishType_n_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..409f8580b8f15020283442f61ebee9e9579509d0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType_n_1.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 A { + foo(a: T):NonNullable{ + return a; + } +} + +/* @@? 18:12 Error TypeError: Type 'T' is not compatible with the enclosing method's return type 'NonNullable' */ diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType_n_2.ets b/ets2panda/test/ast/compiler/ets/nonNullishType_n_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d0f02874ff3793918c44852e41ab420097031032 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType_n_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 {} + +type unionType = Int | A | null | undefined + +function main(){ + let a: NonNullable = new A(); + a = new Int(); + a = null; + a = undefined; +} + +/* @@? 23:7 Error TypeError: Type 'null' cannot be assigned to type 'Int|A' */ +/* @@? 24:7 Error TypeError: Type 'undefined' cannot be assigned to type 'Int|A' */ + diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType_n_3.ets b/ets2panda/test/ast/compiler/ets/nonNullishType_n_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ac195de816047fc3b954cdaabe265bcf4dba36e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType_n_3.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 unionType = Object | null + +function main(){ + let a: NonNullable unionType; + a = null; +} + +/* @@? 19:22 Error SyntaxError: Expected '<', got 'identification literal'. */ +/* @@? 19:31 Error SyntaxError: Expected '>', got ';'. */ +/* @@? 20:7 Error TypeError: Type 'null' cannot be assigned to type 'Object' */ diff --git a/ets2panda/test/ast/compiler/ets/not_all_paths_return_value.ets b/ets2panda/test/ast/compiler/ets/not_all_paths_return_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb0b7a74cbae88030cfb3e9acc4ef56b4f70ae62 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/not_all_paths_return_value.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. + */ + +async function test1(isError: boolean) { + if (isError) { + return 1 + } + // error not all code paths return a value. +} + +async function test(isError: boolean): Promise { + if (isError) { + return Promise.resolve("undefined") + } + // error not all code paths return a value. +} + + +async function test2(isError: boolean): Promise { //ok + if (isError) { + return Promise.resolve(undefined) + } +} + +async function test3(isError: boolean): Promise { //ok + if (isError) { + return Promise.resolve(undefined) + } +} + + +/* @@? 16:16 Error TypeError: Not all code paths return a value. */ +/* @@? 23:16 Error TypeError: Not all code paths return a value. */ 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/null_coalescing_neg_01.ets b/ets2panda/test/ast/compiler/ets/null_coalescing_neg_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..095090df6f6f49a25ef2088ef81e755c38037c24 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/null_coalescing_neg_01.ets @@ -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. + */ + +function foo1(z: int|undefined) { + let x = z ?? /* @@ label1 */10000000000; + return x; +} + +function foo2(z: short|undefined) { + let x = z ?? /* @@ label2 */10000000; + return x; +} + +function foo3(z: byte|undefined) { + let x = z ?? /* @@ label3 */10000; + return x; +} + +function foo4(z: int|undefined) { + let x = z ?? /* @@ label4 */100.0; + return x; +} + +function foo5(z: long|undefined) { + let x = z ?? /* @@ label5 */100000.0f; + return x; +} + +function foo6(z: float|undefined) { + let x = z ?? /* @@ label6 */100000.0; + return x; +} + + +/* @@@ label1 Error TypeError: Value is out of range */ +/* @@@ label2 Error TypeError: Value is out of range */ +/* @@@ label3 Error TypeError: Value is out of range */ +/* @@@ label4 Error TypeError: Type 'Double' cannot be assigned to type 'Int' */ +/* @@@ label5 Error TypeError: Type 'Float' cannot be assigned to type 'Long' */ +/* @@@ label6 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ diff --git a/ets2panda/test/ast/compiler/ets/null_pointer_error.ets b/ets2panda/test/ast/compiler/ets/null_pointer_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..4297f3c7fee22992dee5f2dd988bfc3f17f44834 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/null_pointer_error.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 class AbstractDaoSession{ + public async queryRaw(entityClass: T,where: string, ...selectionArgs: dataRdb.ValueType[]):Promise{ + let paramUse = Type.of(entityClass) + let dao:AbstractDao = this.getDao(DbUtils.getEntityClassName(paramUse)); + return await dao.queryRaw(where, ...selectionArgs); + } +} + +/* @@? 1:3 Error TypeError: Cannot find type 'dataRdb'. */ +/* @@? 1:3 Error TypeError: 'ValueType' type does not exist. */ +/* @@? 17:62 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 19:17 Error TypeError: Cannot find type 'AbstractDao'. */ +/* @@? 20:16 Error TypeError: Type '*ERROR_TYPE*' can not be awaited, it is not a Promise. */ diff --git a/ets2panda/test/ast/compiler/ets/null_pointer_error1.ets b/ets2panda/test/ast/compiler/ets/null_pointer_error1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d700961364b0515e89ceb122086988ff1face8f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/null_pointer_error1.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. + */ + +const mustChecks: Array = new Array(); + +function mustCallArgSize() { + mustChecks.push(() => { + xf(){ + + } + }); +} + +/* @@? 19:5 Error TypeError: No matching call signature for push(() => void) */ 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/objectLiteralPrimitiveContextType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets index 44c12cb3bffe1d9b4d029a7ffeebb3451f0c41df..f703cbe4a9c5718c98a5d38183461f39dc2ac0a0 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets @@ -14,4 +14,4 @@ */ let x: int = /* @@ label */{}; -/* @@@ label Error TypeError: Target type for class composite needs to be an object type, found 'int' */ + diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets index 38d5711cf96154af6a75ee1327a63ab41c2b5260..ce025f5c2a5a4a6e93340741f3af53e9fef5650d 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets @@ -21,4 +21,4 @@ let c: C = { f: /* @@ label */"ouch" }; -/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'int' at property 'f' */ +/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'Int' at property 'f' */ diff --git a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets index 80d6e714825665db3d72c9b4b4851f9f82c88e76..876abd1349d3a2170de76a59e50f5952858f0c36 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets @@ -40,6 +40,6 @@ 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 */ +/* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'Double' at property 'field1' */ +/* @@@ 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/ast/compiler/ets/object_literal_initialization.ets b/ets2panda/test/ast/compiler/ets/object_literal_initialization.ets new file mode 100644 index 0000000000000000000000000000000000000000..de74d227c06eff032cf724aaf4bd50871a9bbe93 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/object_literal_initialization.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. + */ + +// arkts-no-untyped-obj-literals +let o: Object = /* @@ label1 */{/* @@ label2 */n: 42, s: "foo"} + +/* @@@ label1 Error TypeError: 'Object', 'object', 'any' types cannot be initialized with object literals. */ +/* @@@ label2 Error TypeError: type Object has no property named n */ diff --git a/ets2panda/test/ast/compiler/ets/optional_method.ets b/ets2panda/test/ast/compiler/ets/optional_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..5f4df228347176b9e89cd59bde2f7cbde80c8d68 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/optional_method.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 X { + classMethod?/* @@ label1 */() {} +} +interface Y { + interfaceMethod?/* @@ label2 */(): void +} + +/* @@@ label1 Error SyntaxError: Optional methods are not supported. */ +/* @@@ label2 Error SyntaxError: Optional methods are not supported. */ 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/overload/class_overloaded_name_must_ident.ets b/ets2panda/test/ast/compiler/ets/overload/class_overloaded_name_must_ident.ets new file mode 100644 index 0000000000000000000000000000000000000000..6559e6d66b2b63c401c72bc8f8e9a956aabec490 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/class_overloaded_name_must_ident.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 B { + foo1() {} +} + +class C { + overload foo { /* @@label1 */B.foo1 } +} + +/* @@@ label1 Error SyntaxError: The overloaded method name in class/interface method overload declaration must be identifier. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/constructor_overloaded_name_must_ident.ets b/ets2panda/test/ast/compiler/ets/overload/constructor_overloaded_name_must_ident.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4a9648f60ef2a4bb147d3f46ba5fc5be635664f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/constructor_overloaded_name_must_ident.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 B { + constructor foo1() {} +} + +class C { + overload constructor { /* @@label1 */B.foo1 } +} + +/* @@@ label1 Error SyntaxError: The overloaded method name in class/interface method overload declaration must be identifier. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets b/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..70eb87ba28801033a1a0e893285a0f3c51c5141e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/function_overloaded_name_must_qualified_name.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. + */ + + +namespace NS { + export function foo1() {} + export class A { + static foo2() {} + } +} + +overload foo {NS.foo1, NS.A.foo2, /* @@ label1 */NS.A.foo2} + +/* @@@ label1 Error TypeError: Duplicate overloaded method. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/interface_overloaded_name_must_ident.ets b/ets2panda/test/ast/compiler/ets/overload/interface_overloaded_name_must_ident.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d5f01eb897bf0fec1d25cc1beaa44e1f62ed5fc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/interface_overloaded_name_must_ident.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 B { + foo1() {} +} + +interface I { + overload foo { /* @@label1 */B.foo1 } +} + +/* @@@ label1 Error SyntaxError: The overloaded method name in class/interface method overload declaration must be identifier. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function.ets b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..3b4308b99f283d843e9c3b710ee2188ebf8db746 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function.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 A { } +class B { } +class C { } + +function foo111(a: A): A { + return a; +} +function foo112(a: B): B { + return a; +} + +function foo113(a: C): C { + return a; +} + +overload foo{ foo111, foo112, foo113,/* @@ label1 */foo111 } + +/* @@@ label1 Error TypeError: Duplicate overloaded method. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..fa182d50daa9913808bdd440e4bedca29bc69dac --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_function_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. + */ + +namespace NS { + export namespace NS2 { + export function foo1(a: string): string { + return "invoke1" + }; + export namespace NS3 { + export function foo2(a: number): string { + return "invoke2" + }; + } + } + + export function foo3(a: boolean): string { + return "invoke3" + }; +} + + +overload foo{ NS.NS2.foo1, NS.NS2.NS3.foo2, NS.foo3, /* @@ label1 */NS.NS2.NS3.foo2}; + +/* @@@ label1 Error TypeError: Duplicate overloaded method. */ + diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_method.ets b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d656eb4b7ba2b810e6509c2e5ead4c19803a130 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_method.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 { } +class B { } +class C { } + +class Test1 { + foo111(a: A): A { + return a; + } + foo112(a: B): B { + return a; + } + + foo113(a: C): C { + return a; + } + overload foo{ foo111, foo112, foo113,/* @@ label1 */foo111 } +} + +/* @@@ label1 Error TypeError: Duplicate overloaded method. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_overload_name_1.ets b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_overload_name_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..d5a1d45da91831f60376e7d0956a1d2e3f3607a0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_duplicate_overload_name_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. + */ + +class Base { + foo/* @@ label1 */(a: number) : string + foo(a: string) : string + overload foo {/* @@ label2 */foo, /* @@ label3 */foo} +} + +/* @@@ label1 Error TypeError: Only abstract or native methods can't have body. */ +/* @@@ label2 Error TypeError: The overloaded name 'foo' can't refer to a function with overload signatures. */ +/* @@@ label3 Error TypeError: Duplicate overloaded method. */ +/* @@@ label3 Error TypeError: The overloaded name 'foo' can't refer to a function with overload signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_from_super_class.ets b/ets2panda/test/ast/compiler/ets/overload/overload_from_super_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..81f8d0f398f5d4444cfa260f3544afe22b046d26 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_from_super_class.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 B extends A { + fooB() { + } + overload foo{fooB, fooA} +} + +class A{ + fooA() {} +} + diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_method_exported.ets b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_method_exported.ets new file mode 100644 index 0000000000000000000000000000000000000000..1510e3ff407d418b93f7ffe436fd07df66385cfd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_method_exported.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 foo1() {} +function foo2() {} +export overload foo {foo1, foo2} diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_at_most_once_1.ets b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_at_most_once_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a2ab17c31f1cbb69baa1fb82b8cfb8c32bfe794 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_at_most_once_1.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{} +class B{} + +class Test0 { + foo111(a: A): void { } +} + +class Test1 extends Test0 { + + foo112(a: B): B { + return a; + } + overload foo{foo111, /* @@ label1 */foo111, foo112} +} + +/* @@@ label1 Error TypeError: Duplicate overloaded method. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_1.ets b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..dec7657edd7f6c47dd41b1f5b439678d14183d36 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_1.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class E { + foo1() {} + foo2() {} + overload foo{foo1, foo2} + foo3() { + let f = this.foo; + } +} + +/* @@? 22:22 Error TypeError: Overloaded method is used as value */ + diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_2.ets b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..79401623d249b1af4deaf68041bac458edf77bdf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_overloaded_name_used_as_value_2.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 foo1() {} +function foo2() {} +overload foo{foo1, foo2} +let OL = /* @@ label */foo; + +/* @@@ label Error TypeError: Overloaded method is used as value */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_union_call.ets b/ets2panda/test/ast/compiler/ets/overload/overload_union_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..f377a79a6ae473dad12fb0d80db368b0c8227c81 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_union_call.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 { + foo2(a: int) { } + foo1() { + return 1 + } + overload foo{ foo1, foo2 } +} + +class B { + foo2(a: int) { } + foo1() { + return 2 + } + overload foo{ foo1, foo2 } +} + +type AAA = A | B + +function foo(a: T) { + return /* @@ label1 */a.foo() +} + +/* @@@ label1 Error TypeError: Overload declaration cannot be called by union. */ diff --git a/ets2panda/test/ast/compiler/ets/overload/overload_union_call_2.ets b/ets2panda/test/ast/compiler/ets/overload/overload_union_call_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..e718f6244308177f35d7b72a24070b915d842405 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload/overload_union_call_2.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 { + foo2(a: int) { } + foo1() { + return 1 + } + overload foo{ foo1, foo2 } +} + +class B { + foo() { } +} + +type AAA = A | B + +function foo(a: T) { + return /* @@ label1 */a.foo() +} + +/* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label1 Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/overload_for_named_constructor.ets b/ets2panda/test/ast/compiler/ets/overload_for_named_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..0575959c2f8e34bbe7c7838f50b08d8d0ef4c794 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload_for_named_constructor.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{ + overload constructor {foo, bar}; + constructor foo(a:string, b?:string){} + constructor bar(a:number, b?:number){} +} + +function main(){ + new A() +} + +/* @@? 23:5 Error TypeError: No matching construct signature for A() */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/override11.ets b/ets2panda/test/ast/compiler/ets/override11.ets index 1bf873cd54dd7cadd8c96116ead55c9d39df338f..2c43199671770c0c92a925404dcaadf1c5a81391 100644 --- a/ets2panda/test/ast/compiler/ets/override11.ets +++ b/ets2panda/test/ast/compiler/ets/override11.ets @@ -21,5 +21,5 @@ class B extends A { override fn(t: int): void { } } -/* @@? 21:14 Error TypeError: fn(t: int): void in B cannot override fn(t: int): int in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: int): void in B not overriding any method */ +/* @@? 21:14 Error TypeError: fn(t: Int): void in B cannot override fn(t: Int): Int in A because overriding return type is not compatible with the other return type. */ +/* @@? 21:14 Error TypeError: Method fn(t: Int): void in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override14.ets b/ets2panda/test/ast/compiler/ets/override14.ets index 70cdd59cb77830507fafcba59c7d836531202371..59bca85ba3f6ab192075b05d734a1999a33027dd 100644 --- a/ets2panda/test/ast/compiler/ets/override14.ets +++ b/ets2panda/test/ast/compiler/ets/override14.ets @@ -21,5 +21,3 @@ class B extends A { override fn(t: Object): int { return 1} } -/* @@? 21:14 Error TypeError: fn(t: Object): int in B cannot override fn(t: T): T in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: Object): int in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override15.ets b/ets2panda/test/ast/compiler/ets/override15.ets index 3a910c970c95ae22a019e3a26af8bfdf97aff625..2afb8940d3f7ff872881b3c2ffc60be47684b524 100644 --- a/ets2panda/test/ast/compiler/ets/override15.ets +++ b/ets2panda/test/ast/compiler/ets/override15.ets @@ -21,5 +21,5 @@ interface I2 extends I { fn(): float; } -/* @@? 21:5 Error TypeError: fn(): float in I2 cannot override fn(): int in I because overriding return type is not compatible with the other return type. */ -/* @@? 21:5 Error TypeError: Method fn(): float in I2 not overriding any method */ +/* @@? 21:3 Error TypeError: fn(): Float in I2 cannot override fn(): Int in I because overriding return type is not compatible with the other return type. */ +/* @@? 21:3 Error TypeError: Method fn(): Float in I2 not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override3.ets b/ets2panda/test/ast/compiler/ets/override3.ets index 0ed1c28b81f399efb8de88e06aeb83f5d1a92341..96cdf17944ed5bf697ec2ac4054cd9d0b85b5ac5 100644 --- a/ets2panda/test/ast/compiler/ets/override3.ets +++ b/ets2panda/test/ast/compiler/ets/override3.ets @@ -17,5 +17,5 @@ interface I { toString(): int; } -/* @@? 17:11 Error TypeError: toString(): int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ -/* @@? 17:11 Error TypeError: Method toString(): int in I not overriding any method */ +/* @@? 17:3 Error TypeError: toString(): Int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ +/* @@? 17:3 Error TypeError: Method toString(): Int in I not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override7.ets b/ets2panda/test/ast/compiler/ets/override7.ets index 18900c1e849fef6fd0a098432c8ca20f446ea9cd..aca0ae3a32e7e578d50010e0b04addd4007e5a06 100644 --- a/ets2panda/test/ast/compiler/ets/override7.ets +++ b/ets2panda/test/ast/compiler/ets/override7.ets @@ -23,5 +23,5 @@ abstract class A implements I { public override fn(): int { return 1; } } -/* @@? 23:21 Error TypeError: fn(): int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ -/* @@? 23:21 Error TypeError: Method fn(): int in A not overriding any method */ +/* @@? 23:21 Error TypeError: fn(): Int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ +/* @@? 23:21 Error TypeError: Method fn(): Int in A not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets index 268606ee2e4db44ac8ff580a7f6fc8734341c184..abc1ea45628fd526592f8b87fcab27054610bdc4 100644 --- a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets +++ b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets @@ -25,4 +25,4 @@ class B { } } -/* @@@ label Error TypeError: Method foo(a: int): int in B not overriding any method */ +/* @@@ label Error TypeError: Method foo(a: Int): Int in B not overriding any method */ 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..718607481dfea2a938287f5603cbfea11ea028c2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/P3/P3.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. + */ + +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: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: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..442220438fe10d11a0f8c504528ccee1db498f8c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/main_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. + */ + +import {nn, nn1, nn2} from "./P3" + +/* @@? 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: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..9973e90217e072f4113e48d0fa682be2ddb01dc6 --- /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:22:5 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..a61fb5e005e7ba1b10f593c7a0ec49d482673ad1 --- /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:22:5 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..8d0dd864534d22e2eeb5ea7783580aecb005f1f3 --- /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:21:5 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_wrong_identifier.ets b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..22b996e74db89a8fba96d28baee3d2e739883d4a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + foo1(a: number) { } + foo2(a: Number) { } + foo3(a: Int) { } + foo4(a: String) { } + static foo5(a: Boolean) { } + static foo6(a: number) { } +} +function foo7(a: number) { } + +function main() { + let a = new A(); + a.foo1(Number); + a.foo2(Number); + a.foo3(Int); + a.foo4(String); + A.foo5(Boolean); + A.foo6(Number); + foo7(Number); + const v1 = Number.isSafeInteger(Number); + try { + const v1 = Number.isSafeInteger(Number); + } catch (e) { } +} + +/* @@? 28:3 Error TypeError: No matching call signature for foo1(Double) */ +/* @@? 28:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 29:3 Error TypeError: No matching call signature for foo2(Double) */ +/* @@? 29:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:3 Error TypeError: No matching call signature for foo3(Int) */ +/* @@? 30:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:10 Error TypeError: Class or interface 'Int' cannot be used as object */ +/* @@? 31:3 Error TypeError: No matching call signature for foo4(String) */ +/* @@? 31:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 31:10 Error TypeError: Class or interface 'String' cannot be used as object */ +/* @@? 32:3 Error TypeError: No matching call signature for foo5(Boolean) */ +/* @@? 32:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 32:10 Error TypeError: Class or interface 'Boolean' cannot be used as object */ +/* @@? 33:3 Error TypeError: No matching call signature for foo6(Double) */ +/* @@? 33:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 34:3 Error TypeError: No matching call signature for foo7(Double) */ +/* @@? 34:8 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 35:14 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 35:35 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 37:16 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 37:37 Error TypeError: Class name can't be the argument of function or method. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets b/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..39968154fee1957830420ef410bd854c23e857bf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const _innerFunc = (arg: { x: number } | undefined): number => { + if (arg === undefined) { + return 12; + } + return arg.x; +}; + +/* @@? 16:26 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ diff --git a/ets2panda/test/ast/compiler/ets/parser_annotation_n.ets b/ets2panda/test/ast/compiler/ets/parser_annotation_n.ets index 2a6fd1d1701ed9a8ffad6ff9b360c1c7afa07ccf..32781a0e03ff9243f03759e7940168c57252ce1d 100644 --- a/ets2panda/test/ast/compiler/ets/parser_annotation_n.ets +++ b/ets2panda/test/ast/compiler/ets/parser_annotation_n.ets @@ -16,4 +16,4 @@ @interface /* @@ label1 */� /* @@@ label1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 20:1 Error SyntaxError: Expected '{', got 'eos'. */ +/* @@? 20:1 Error SyntaxError: Expected '{', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/parser_format.ets b/ets2panda/test/ast/compiler/ets/parser_format.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cfa428977ed81efa7828a1a040bcf8dc8143316 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/parser_format.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. + */ + +declaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaare struct MainProg2 { + @@Stave +} + +/* @@? 16:1 Error TypeError: Unresolved reference declaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaare */ +/* @@? 16:39 Error SyntaxError: Unexpected token 'struct'. */ +/* @@? 16:39 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ +/* @@? 17:5 Error SyntaxError: There is no any node to insert at the placeholder position. */ +/* @@? 17:12 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/compiler/ets/parser_import.ets b/ets2panda/test/ast/compiler/ets/parser_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..3fb9464550bcc0d64c5aa909ff64063cd9c409e4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/parser_import.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 callbackc = (arrElem: JSValue) => { + import {a} from +} + +/* @@? 17:5 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ +/* @@? 18:1 Error SyntaxError: Unexpected token, expected string literal. */ +/* @@? 22:70 Error SyntaxError: Expected '}', got 'end of stream'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/partialTypeParameterParamInfer.ets b/ets2panda/test/ast/compiler/ets/partialTypeParameterParamInfer.ets new file mode 100644 index 0000000000000000000000000000000000000000..53e4be9d7d90e94f4a9e54e1537e3bf1bec9eb95 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/partialTypeParameterParamInfer.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 Base {} + +function foo(arg: Partial): void {} + +function main() { + foo(new Partial()) +} +/* @@? 18:29 Error TypeError: T in Partial must be a class or an interface type. */ diff --git a/ets2panda/test/ast/compiler/ets/partialType_check_in_RemoveUndefinedType.ets b/ets2panda/test/ast/compiler/ets/partialType_check_in_RemoveUndefinedType.ets new file mode 100644 index 0000000000000000000000000000000000000000..abe625355b83a683c9fa7ee6b74220d7e7bc1de0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/partialType_check_in_RemoveUndefinedType.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 genericFunc(p: Partial): void { + if (p !== undefined) { + } +} +function main() { + genericFunc<{a: number, b: string}>({a: 1}) +} + +/* @@? 16:35 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 21:3 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 21:15 Error TypeError: need to specify target type for class composite */ +/* @@? 21:38 Error TypeError: need to specify target type for class composite */ 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/re-declare_in_local_scope.ets b/ets2panda/test/ast/compiler/ets/re-declare_in_local_scope.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae18b2d15c50949483d15ef887ae806717445433 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/re-declare_in_local_scope.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. + */ + +{ + var ten = 1; + let ten = 10; +} + +/* @@? 17:9 Error SyntaxError: 'var' keyword is not supported. Use 'let' instead. */ +/* @@? 18:9 Error TypeError: Variable 'ten' has already been declared. */ \ 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/runtime/ets/local-class-modify-captured-parameter.ets b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets old mode 100644 new mode 100755 similarity index 55% rename from ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets rename to ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets index c217536ffd8227251751def07f819994cea58b40..974a88ae5f338857829d266e7a168c774dba52b8 --- a/ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets +++ b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets @@ -13,29 +13,24 @@ * 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 +---*/ -class GlobalClass -{ - static capture_param_method(param : int) - { - class LocalClass - { - method() - { - assertEQ(param, 1) - param = 3; - } - } - - let lc = new LocalClass(); - lc.method() - assertEQ(param, 3) - } +interface I { + i: number; + j: string; } -function main() : int -{ - GlobalClass.capture_param_method(1); - - return 0; +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.ets b/ets2panda/test/ast/compiler/ets/readonly.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c547d70ccb907ab28e25bc99ac049ddf47d69af --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly.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 f(x: Readonly) {} + +async function ff(x:T) { + f(a(x)) +} + +function a(x:T) : Readonly { return x } \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets index f0f192c0a9a6dc1285bf34c8b9c8c4da53346af3..ffe851e573069a92d24617f3f95b68ab18f0351f 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets @@ -13,16 +13,12 @@ * limitations under the License. */ -WE: /* @@ readonly1 */readonly /* @@ true */true; -let/* @@ colon */: /* @@ readonly2 */readonly/* @@ end */; +WE: readonly true; +let: readonly; -/* @@@ readonly1 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@@ readonly1 Error TypeError: Unresolved reference readonly */ -/* @@@ true Error SyntaxError: Invalid Type. */ -/* @@@ true Error SyntaxError: Unexpected token 'true'. */ - -/* @@@ colon Error SyntaxError: Identifier expected, got ':'. */ -/* @@@ readonly2 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@@ readonly2 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@@ readonly2 Error SyntaxError: Unexpected token 'readonly'. */ -/* @@@ end Error SyntaxError: Invalid Type. */ +/* @@? 16:5 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:5 Error TypeError: Unresolved reference readonly */ +/* @@? 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'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets index 4b6b812ce65e1dfe5fe85ef340763c9348c19016..d00c74ecc1831b78bc76ee72229e69029f04dc04 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets @@ -13,12 +13,6 @@ * limitations under the License. */ -let a: readonly int [/* @@ E1 */""/* @@ E2 */]; +let a: readonly int [""]; -/* @@@ E1 Error SyntaxError: Unexpected token, expected ']'. */ -/* @@@ E1 Error SyntaxError: Invalid Type. */ -/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ -/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ -/* @@@ E1 Error SyntaxError: Unexpected token ']'. */ -/* @@@ E2 Error SyntaxError: Unexpected token ']'. */ -/* @@@ E2 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:21 Error SyntaxError: Indexed access types are not supported, use type name instead! */ \ No newline at end of file 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 index fe4d6158f78c51023de89e1f32803c86ea9f73d9..32b89726adde01c9094267fc9c57ab5d87d48210 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets @@ -16,7 +16,4 @@ 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 index 3830a00052e10a05e2dadd2cd1222756c99a44be..a8269c5aec57fae9fb96a5e45f4f743d66ba9b2d 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets @@ -20,12 +20,7 @@ class A { } /* @@@ 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 index 816f9ea537cbdd0608b1cbb1b204d5eedc539e1c..46ad39e55c1155e8e58d8e5179d5278fe7e290aa 100644 --- a/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets @@ -13,11 +13,9 @@ * limitations under the License. */ -/* @@ readonly */readonly /* @@ static */static /* @@ S */S = c' '; +readonly static S = c' '; -/* @@@ readonly Error TypeError: Unresolved reference readonly */ -/* @@@ static Error SyntaxError: Invalid Type. */ -/* @@@ static Error SyntaxError: Unexpected token 'static'. */ -/* @@@ static Error SyntaxError: Unexpected token 'static'. */ -/* @@@ S Error SyntaxError: Unexpected token 'S'. */ -/* @@@ S Error TypeError: Unresolved reference S */ +/* @@? 16:1 Error TypeError: Unresolved reference readonly */ +/* @@? 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/readonlyField.ets b/ets2panda/test/ast/compiler/ets/readonlyField.ets index 808ae692ee6df8f203cddae6d3f1fa9536ddfcfc..e635f3632642cac0519c926f64dbcb47e55e9a35 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyField.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyField.ets @@ -13,7 +13,7 @@ * limitations under the License. */ class ReadonlyData { - readonly /* @@ label */value: T; + readonly value: T; constructor(value: T) { this.value = value; } @@ -21,7 +21,7 @@ class ReadonlyData { function main(): void { let myData = new ReadonlyData("import data"); - myData.value = "new data"; + /* @@ label */myData.value = "new data"; } -/* @@@ label Error TypeError: Cannot assign to a readonly variable value */ +/* @@@ label Error TypeError: Cannot assign to a readonly field value */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyField_2.ets b/ets2panda/test/ast/compiler/ets/readonlyField_2.ets index 96451387facf12e946eceb951b435e1a530bd4d9..b43c2d148997534d20322280c2fa8f5015d386f3 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyField_2.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyField_2.ets @@ -14,12 +14,12 @@ */ class ReadonlyPerson { - readonly /* @@ label */name: string; + readonly name: string; readonly age: number; } function updatePerson(person: ReadonlyPerson): ReadonlyPerson { - person.name = "Bob"; //CTE + /* @@ label */person.name = "Bob"; //CTE return person; } function main(): void { @@ -27,4 +27,4 @@ function main(): void { updatePerson(person); } -/* @@@ label Error TypeError: Cannot assign to a readonly variable name */ +/* @@@ label Error TypeError: Cannot assign to a readonly field name */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyType_1.ets b/ets2panda/test/ast/compiler/ets/readonlyType_1.ets index bd3c6a1de676a586a7edaf92248e13c62a4ae79d..b4cb4f0277b958970c6a00562790ef41a909eec1 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_1.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_1.ets @@ -14,7 +14,7 @@ */ class A { - /* @@ label */fld: Number + fld: Number constructor (fld : Number) { this.fld = fld } @@ -22,8 +22,9 @@ class A { function foo(a0: A) { let a: Readonly = new A(2) - a.fld = 5 + /* @@ label */a.fld = 5 } -/* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label Error TypeError: Cannot assign to a readonly field fld */ +/* @@@ label 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..7c73a1765cd1530d41df94b3b8b3f09c3b56651c 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_2.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_2.ets @@ -14,12 +14,13 @@ */ class A { - /* @@ label */fld: Number = 2 + fld: Number = 2 } function foo(a0: A) { let a: Readonly = {fld: 3} - a.fld = 5 + /* @@ label */a.fld = 5 } -/* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label Error TypeError: Cannot assign to a readonly field fld */ +/* @@@ label 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..9bbf937c5efa4aca50762e978efaad5c98fa0e17 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_3.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_3.ets @@ -14,10 +14,11 @@ */ class A { - /* @@ label */fld: Number = 2 + fld: Number = 2 foo (a0: Readonly) { - a0.fld = 5 + /* @@ label */a0.fld = 5 } } -/* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label Error TypeError: Cannot assign to a readonly field fld */ +/* @@@ label 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..03edcf4a18d86b52582af8796b0fb86f895bda39 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_4.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_4.ets @@ -14,7 +14,7 @@ */ class A { - /* @@ label */fld: Number = 2 + fld: Number = 2 foo (a0: A) { a0.fld = 5 } @@ -25,8 +25,9 @@ class B extends A {} class C extends B { fld: Number = 2 foo (a0: Readonly) { - a0.fld = 6 + /* @@ label */a0.fld = 6 } } -/* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label Error TypeError: Cannot assign to a readonly field fld */ +/* @@@ label 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 index d377fa27f9c66e4041ebb53d2585c89e9f1e938b..35d50fac5059d4dbee3c79e8b97c152c816daded 100644 --- a/ets2panda/test/ast/compiler/ets/readonly_array01.ets +++ b/ets2panda/test/ast/compiler/ets/readonly_array01.ets @@ -14,10 +14,10 @@ */ function main() { - let v: readonly number[][] = [[1.0,2.0]] + let v = [[1.0,2.0]] as readonly number[][] // smart cast workaround 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 */ - +/* @@? 19:5 Error TypeError: Object type doesn't have proper index access method. */ +/* @@? 19:12 Error TypeError: Can't resolve array type */ 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..662eea658f08e52b3c3d39396599106ae8fe53fb 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/record_with_getter_crash.ets b/ets2panda/test/ast/compiler/ets/record_with_getter_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0daa879158d3d99b66fccbddbb9b3361258f994 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/record_with_getter_crash.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. + */ + +interface I { + meth(): Record +} +interface J { + meth(): Record +} + +class A implements I { + meth(): Record { + return { + get a(): number { + return 11.0 + } + } + } +} + +class B implements J { + meth(): Record { + return { 'b': 22.0} + } +} + +let u1: I | J = new A() +let u2: I | J = new B() + +function main() { + assertEQ(u1.meth()['a'], 11.0) + assertEQ(u2.meth()['b'], 22.0) +} + +/* @@? 26:17 Error SyntaxError: Object pattern can't contain methods. */ +/* @@? 43:5 Error TypeError: Unresolved reference assertEQ */ +/* @@? 44:5 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets index a7d08982f99179aec3d858b0365e2ebbf182124d..f2f1b08aa92063a310383baee9819bff4879b4e3 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets @@ -17,6 +17,6 @@ class A>>{} class C extends A/* @@ label1 */>{} /* A does not satisfy the constraint due to invariance of T */ -/* @@@ label Error TypeError: Type A is not assignable to constraint type A>> */ -/* @@@ label2 Error TypeError: Type C is not assignable to constraint type A> */ -/* @@@ label1 Error TypeError: Type A is not assignable to constraint type A>> */ +/* @@@ label Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ +/* @@@ label2 Error TypeError: Type argument 'C' should be a subtype of 'A>'-constraint */ +/* @@@ label1 Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets index 7bfe478c3052a4383c4a6b0fdc2b275eafdc02a8..9ee831177ac4d9cc1e1fbde7792d3e0a99f5ebd2 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets @@ -16,4 +16,4 @@ interface A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets index fb2f2817251f84371fef51ccd6edd50fa7c9474d..3596a49b970eaec3a724466ce519c6cc4d5c71fe 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets @@ -16,4 +16,4 @@ interface A,T2 extends A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets index 7a588b42f8c787d6e69d060965d2240e8848ea4e..0238b2626c749d6cb6993a98133fbe35cb83284b 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets @@ -19,4 +19,4 @@ class T

{} class C extends A/* @@ label */{} /* Constraint: B|D|C <: A, but B is not a subtype of A due to T invariance */ -/* @@@ label Error TypeError: Type B|D|C is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B|D|C' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.ets b/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0f98280f500bc543bcfad24cadfd07042e1dc8b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/redecl_func_arow_param_in_body.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 ermissions and + * limitatioLicense. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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(bar: () => int) { + let x , bar(); + } + + function main(): void { + foo(() => {}); + } + +/* @@? 18:11 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 18:13 Error TypeError: Variable 'bar' has already been declared. */ +/* @@? 18:16 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 18:16 Error SyntaxError: Unexpected token '('. */ +/* @@? 18:17 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:18 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 22:14 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets b/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..ec66c92c5ee8b8439db2564cde211051711c311a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package escompat; + +class ArrayKeysIterator { + private a: Array +} + +export class Array { + a: T +} + +/* @@? 1:3 Error TypeError: Class 'Array' is already defined. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/requiredType_10_neg.ets b/ets2panda/test/ast/compiler/ets/requiredType_10_neg.ets index 98320d2d4ce205791760ad66c13b7a6bfb36b365..cc8b0e626ca83e7cf5c1a0c85589709f8bded498 100644 --- a/ets2panda/test/ast/compiler/ets/requiredType_10_neg.ets +++ b/ets2panda/test/ast/compiler/ets/requiredType_10_neg.ets @@ -25,4 +25,4 @@ function main(): void { let req_a: A = {fld: /* @@ label */{}}; } -/* @@@ label Error TypeError: Class property 'b_fld' needs to be initialized for Required. */ +/* @@? 21:18 Error TypeError: T in Required must be a class or an interface type. */ diff --git a/ets2panda/test/ast/compiler/ets/resolve_class_declaration.ets b/ets2panda/test/ast/compiler/ets/resolve_class_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..97180f8bebc508b8226952cec153081ad05e92cc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/resolve_class_declaration.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 I { + b5 : number;r_2.ETSGLOBAL::hot_catc { + return; +} + +/* @@? 17:20 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 17:30 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:30 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:31 Error SyntaxError: Identifier expected. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:41 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 18:5 Error SyntaxError: Invalid Type. */ 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..5cfc8c78642328650aac7d6c878559420bd02e27 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 @@ -22,8 +22,8 @@ function pi(): number { function main() { let v: UT = pi - assertTrue((v as NumFunc)() == 3.14); // Is used 'assertTrue' due to #22840 + arktest.assertTrue((v as NumFunc)() == 3.14); // Is used 'arktest.assertTrue' due to #22840 } /* @@? 24:17 Error TypeError: Type '() => Double' cannot be assigned to type '() => void|Double' */ -/* @@? 25:16 Error TypeError: Cannot use type 'void' as value. */ +/* @@? 25:24 Error TypeError: Cannot use type 'void' as value. */ diff --git a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type_1.ets b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type_1.ets index dd877c7254fec83e07245986a488679b255780c9..818d4995aaab947a026c4131bbfb9ca44a2e5c13 100644 --- a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type_1.ets +++ b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type_1.ets @@ -22,7 +22,8 @@ function pi(): number { function main() { let v: UT = /* @@ label */pi - assertEQ((v as NumFunc)(), 3.14); + arktest.assertEQ((v as NumFunc)(), 3.14); } /* @@@ label Error TypeError: Type '() => Double' cannot be assigned to type 'String|Double' */ +/* @@? 25:23 Error TypeError: Cannot cast type 'String|Double' to '() => Double' */ diff --git a/ets2panda/test/ast/compiler/ets/restvar_type_infer.ets b/ets2panda/test/ast/compiler/ets/restvar_type_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..b24788ce952c404b8cba82b6471b3187d8868fe4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/restvar_type_infer.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. +*/ + +function main() { + let r1 = ((...args) =>{ return args.length; })(1,2,3); + let r2 = ((a:number, ...args)=> { return args.length; })(1,2,3,4,5) +} + +/* @@? 17:14 Error TypeError: Cannot use type 'void' as value. */ +/* @@? 17:16 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 17:16 Error TypeError: The type of parameter 'args' cannot be inferred */ +/* @@? 18:14 Error TypeError: Cannot use type 'void' as value. */ +/* @@? 18:26 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 18:26 Error TypeError: The type of parameter 'args' cannot be inferred */ diff --git a/ets2panda/test/ast/compiler/ets/returnTypeAnnotation_typeParams_nullptr.ets b/ets2panda/test/ast/compiler/ets/returnTypeAnnotation_typeParams_nullptr.ets new file mode 100755 index 0000000000000000000000000000000000000000..64f4958d341625ff8da0c28b31f822b54cfacbda --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/returnTypeAnnotation_typeParams_nullptr.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: * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 Arr { + public mp(a: int): FixedArray<()> +} + +/* @@? 16:11 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:24 Error TypeError: FixedArray must have only one type parameter. */ +/* @@? 16:37 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 16:37 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 16:37 Error SyntaxError: Unexpected token '>'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/return_protected_function.ets b/ets2panda/test/ast/compiler/ets/return_protected_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..81897a3516f4c0decb8bf1daafd9b90c97ae6327 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/return_protected_function.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{ + protected static foo(){ + return "foo"; + } + static getfoo(){ + return A./* @@ label */foo; + } +}; + +/* @@@ label Error TypeError: Protected method is used as value */ \ No newline at end of file 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..6d1a17227009d7024b1d50a8548cf72a114e4014 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. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets index df5bce8676bbda21e4beda0551d0cf1d2ed441cf..78955a8122d25381b13e00dff486923743aa5f66 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets @@ -15,8 +15,7 @@ //declare function has body export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number {} -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ /* @@? 19:49 Error TypeError: Native, Abstract and Declare methods cannot have body. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets index 227dab0f7806e557ef85546174370040f5639a37..18bdf1ec9ef90f3ca5698970adb7c7e35c47de6d 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets @@ -15,7 +15,7 @@ //Not support non-declare function has same assembly code export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export function foo(a:A):number {} -/* @@? 19:8 Error TypeError: Function foo with this assembly signature already declared. */ \ No newline at end of file +/* @@? 19:8 Error TypeError: Method declaration `foo` must all ambient or non-ambient */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets index 5440079d8e17649250390fdf6c3c8db80df59082..31d4512f58cc0790abb82bced518c32002048c24 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets @@ -15,10 +15,7 @@ //Without rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets index 9900d58e0c497eec7288b26465a4912f6b63cd88..a35dbbffd63dcc6dd1ef28d70e06f18682ae5a91 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:string[]):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/same_name_field_err.ets b/ets2panda/test/ast/compiler/ets/same_name_field_err.ets index c5a321c0b36286b43449044c49225b112f084e46..fdfa470be384a0a806dab24a940e14e528ea91e6 100644 --- a/ets2panda/test/ast/compiler/ets/same_name_field_err.ets +++ b/ets2panda/test/ast/compiler/ets/same_name_field_err.ets @@ -20,8 +20,7 @@ class SameName { } function main(): void { - assertEQ(SameName.a, 32); + arktest.assertEQ(SameName.a, 32); } /* @@? 19:12 Error TypeError: Variable 'a' has already been declared. */ -/* @@? 19:12 Error TypeError: Property 'a' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/compiler/ets/same_name_fields.ets b/ets2panda/test/ast/compiler/ets/same_name_fields.ets index 1eace0870e7854aacf78b91468e54abde3ec54ea..a40fd3151c690f26a9da52dd674a6b847e23ed07 100644 --- a/ets2panda/test/ast/compiler/ets/same_name_fields.ets +++ b/ets2panda/test/ast/compiler/ets/same_name_fields.ets @@ -23,7 +23,6 @@ class SameName { "key": { "type": "Identifier", "name": "a", - "decorators": [], "loc": { "start": { "line": 18, @@ -66,7 +65,6 @@ class SameName { "key": { "type": "Identifier", "name": "a", - "decorators": [], "loc": { "start": { "line": 17, @@ -114,15 +112,14 @@ class DiffTypes { "key": { "type": "Identifier", "name": "a", - "decorators": [], "loc": { "start": { - "line": 108, + "line": 106, "column": 23, "program": "same_name_fields.ets" }, "end": { - "line": 108, + "line": 106, "column": 24, "program": "same_name_fields.ets" } @@ -133,12 +130,12 @@ class DiffTypes { "value": 7, "loc": { "start": { - "line": 108, + "line": 106, "column": 32, "program": "same_name_fields.ets" }, "end": { - "line": 108, + "line": 106, "column": 33, "program": "same_name_fields.ets" } @@ -157,15 +154,14 @@ class DiffTypes { "key": { "type": "Identifier", "name": "a", - "decorators": [], "loc": { "start": { - "line": 109, + "line": 107, "column": 30, "program": "same_name_fields.ets" }, "end": { - "line": 109, + "line": 107, "column": 31, "program": "same_name_fields.ets" } @@ -176,12 +172,12 @@ class DiffTypes { "value": "a", "loc": { "start": { - "line": 109, + "line": 107, "column": 42, "program": "same_name_fields.ets" }, "end": { - "line": 109, + "line": 107, "column": 45, "program": "same_name_fields.ets" } @@ -196,8 +192,8 @@ class DiffTypes { } */ function main(): void { - assertEQ(SameName.a, 42); - assertEQ((new SameName()).a, 32); - assertEQ(DiffTypes.a, "a"); - assertEQ((new DiffTypes()).a, 6); + arktest.assertEQ(SameName.a, 42); + arktest.assertEQ((new SameName()).a, 32); + arktest.assertEQ(DiffTypes.a, "a"); + arktest.assertEQ((new DiffTypes()).a, 6); } 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/setPropertyTypeOf.ets b/ets2panda/test/ast/compiler/ets/setPropertyTypeOf.ets new file mode 100644 index 0000000000000000000000000000000000000000..8821d43bc2a980223315e33315bcee5847d61889 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/setPropertyTypeOf.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 CustomError extends Error { + constructor(message?: string) { + // 'Error' breaks prototype chain here: + super(message) + // Restore prototype chain: + Object./* @@ label1 */setPrototypeOf(this, new/* @@ label2 */.target.prototype/* @@ label3 */) + } +} + +/* @@@ label1 Error SyntaxError: Runtime prototype inheritance is not supported because of static typing. */ +/* @@@ label2 Error SyntaxError: Invalid Type. */ +/* @@@ label3 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ diff --git a/ets2panda/test/ast/compiler/ets/set_init_without_param.ets b/ets2panda/test/ast/compiler/ets/set_init_without_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..50710b371ef27d48a5e727df5979aa86f2252df8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/set_init_without_param.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +set a '1;' + +/* @@? 16:1 Error SyntaxError: Extension Setter can only have 2 parameters. */ +/* @@? 16:5 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:7 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 22:77 Error SyntaxError: Expected ')', got 'end of stream'. */ +/* @@? 22:77 Error SyntaxError: Extension Accessor must have a receiver. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/signature_argument.ets b/ets2panda/test/ast/compiler/ets/signature_argument.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a2151301a0e5489560533f4517127adfe358f32 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/signature_argument.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 Index { + private button : B [] = []; + + async aboutToAppear() { + this.buttonsOptions.push({ + text: $r(value: T), + adRequestParams: {} + }); + } +} + +interface B { + text: ResourceStr; + adRequestParams: advertising.adRequestParams; +} + +/* @@? 20:14 Error TypeError: Property 'buttonsOptions' does not exist on type 'Index' */ +/* @@? 21:27 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 21:27 Error SyntaxError: Unexpected token. */ +/* @@? 21:30 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 21:31 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:13 Error SyntaxError: Unexpected token. */ +/* @@? 22:30 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 23:10 Error SyntaxError: Unexpected token ')'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 28:11 Error TypeError: Cannot find type 'ResourceStr'. */ +/* @@? 29:22 Error TypeError: Cannot find type 'advertising'. */ +/* @@? 29:34 Error TypeError: 'adRequestParams' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/signature_info_param.ets b/ets2panda/test/ast/compiler/ets/signature_info_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..86eadbdc4a3d26106f1f33d7fb053c67f196ce65 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/signature_info_param.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 testInfo() : void { + let iniP : Promise = intFunc(); + let pThen = iniP.then((d = e : Object) : Object => { return else;}); +} + +/* @@? 17:34 Error TypeError: Unresolved reference intFunc */ +/* @@? 18:34 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:42 Error SyntaxError: Expected '=>', got ')'. */ +/* @@? 18:42 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:44 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:44 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:46 Error SyntaxError: Unexpected token 'Object'. */ +/* @@? 18:46 Error TypeError: The type of parameter 'Object' cannot be inferred */ +/* @@? 18:65 Error SyntaxError: Unexpected token 'else'. */ +/* @@? 18:71 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/signature_param.ets b/ets2panda/test/ast/compiler/ets/signature_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..9c758d79536dcf8a7666d2b41a8b87d601229938 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/signature_param.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 foo1(f: () => void) { + try { + + } catch (e) { + arktest.assertTrue(false, "expected} +} + +class A {} + +function foo2(let f = ((x:A {} + +function foo3() { + foo2(() => {}}); + foo2(() => {}); +} + +/* @@? 20:35 Error SyntaxError: Newline is not allowed in strings */ +/* @@? 20:45 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 22:1 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token '{'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 24:1 Error SyntaxError: Expected '{', got 'let'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 24:1 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:1 Error SyntaxError: Nested functions are not allowed. */ +/* @@? 24:1 Error TypeError: Variable 'f' has already been declared. */ +/* @@? 24:1 Error TypeError: Unresolved reference x */ +/* @@? 26:1 Error SyntaxError: Nested functions are not allowed. */ +/* @@? 27:18 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 27:18 Error SyntaxError: Unexpected token ')'. */ +/* @@? 28:21 Error TypeError: Unresolved reference foo2 */ diff --git a/ets2panda/test/ast/compiler/ets/smart_cast.ets b/ets2panda/test/ast/compiler/ets/smart_cast.ets new file mode 100644 index 0000000000000000000000000000000000000000..226a7a068e399b1f1724c71e87c372fdde566e5c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/smart_cast.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(p: "Object" | "String" | "Number" = "Object") { // should be ok +} + +function bar(p: "Object") { + let s: "Object" = p != undefined ? p : "Object"// should be ok +} + +function baz(p: "Double") { + let s: "Object" = p != undefined ? p : "Double"// should be cte +} + +/* @@? 24:23 Error TypeError: Type '"Double"' cannot be assigned to type '"Object"' */ + diff --git a/ets2panda/test/ast/compiler/ets/smart_cast_while_test_mod.sts b/ets2panda/test/ast/compiler/ets/smart_cast_while_test_mod.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/smart_cast_while_test_mod.sts rename to ets2panda/test/ast/compiler/ets/smart_cast_while_test_mod.ets diff --git a/ets2panda/test/ast/compiler/ets/smart_cast_wuth_break.ets b/ets2panda/test/ast/compiler/ets/smart_cast_wuth_break.ets new file mode 100644 index 0000000000000000000000000000000000000000..aedd842942ecc7d3995d365635d377ee9ba0d2a9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/smart_cast_wuth_break.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(str: string | undefined): undefined { + let x: string | undefined = undefined; + for (let i = 0; i < 1; ++i) { + x = str; + if (x == "a") { + break; + } else { + x = undefined; + } + } + return /* @@ label */x; +} + + +function main() { + console.log(foo("a")); +} + +/* @@@ label Error TypeError: Type 'String|undefined' is not compatible with the enclosing method's return type 'undefined' */ diff --git a/ets2panda/test/ast/compiler/ets/special_type.ets b/ets2panda/test/ast/compiler/ets/special_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba9771e62fe3fe952b97584381a5ac87a6ce2931 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/special_type.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 foo1(a:Any){} +function foo2(a:Required){} +function foo3(a:Readonly){} +function foo4(a:Partial){} +function foo5(a:FixedArray){} + +foo1(()=>{}) +foo2(()=>{}) +foo3(()=>{}) +foo4(()=>{}) +foo5(()=>{}) + +/* @@? 16:17 Error SyntaxError: 'Required' is reserved and cannot be used as a variable/type name */ +/* @@? 17:17 Error SyntaxError: 'Readonly' is reserved and cannot be used as a variable/type name */ +/* @@? 18:17 Error SyntaxError: 'Partial' is reserved and cannot be used as a variable/type name */ +/* @@? 19:17 Error TypeError: FixedArray must have only one type parameter. */ +/* @@? 22:1 Error TypeError: No matching call signature for foo2(() => void) */ +/* @@? 23:1 Error TypeError: No matching call signature for foo3(() => void) */ +/* @@? 24:1 Error TypeError: No matching call signature for foo4(() => void) */ +/* @@? 25:1 Error TypeError: No matching call signature for foo5(() => void) */ + diff --git a/ets2panda/test/ast/compiler/ets/spreadExpressionAsPropertyInObjectLiteral.ets b/ets2panda/test/ast/compiler/ets/spreadExpressionAsPropertyInObjectLiteral.ets index bef75565fae3580a50411132d71ceadda5e07bd5..a73d747d9053d6962e7569c8e79754138772ae3c 100644 --- a/ets2panda/test/ast/compiler/ets/spreadExpressionAsPropertyInObjectLiteral.ets +++ b/ets2panda/test/ast/compiler/ets/spreadExpressionAsPropertyInObjectLiteral.ets @@ -21,4 +21,7 @@ const b2: Base = /* @@ label */{ ...{n: 200} } const c1: Child = /* @@ label1 */{ ...b1, a: "a" } /* @@@ label Error TypeError: The object literal properties must be key-value pairs */ -/* @@@ label1 Error TypeError: The object literal properties must be key-value pairs */ \ No newline at end of file +/* @@@ label Error TypeError: Non-optional property 'n' in type 'Base' is missing in object literal. */ +/* @@@ label1 Error TypeError: The object literal properties must be key-value pairs */ +/* @@@ label1 Error TypeError: Non-optional property 'n' in super type 'Base' of type 'Child' is missing in object literal. */ +/* @@@ label1 Error TypeError: Non-optional property 'a' in type 'Child' is missing in object literal. */ 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/spread_record.ets b/ets2panda/test/ast/compiler/ets/spread_record.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9782ab9747c4499a218df40d74a3a8ebcc80400 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/spread_record.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let r1: Record = { 'one': '1' } +console.log(...r1) // crash - Issue #26773 +let r2: Record = { 'two': '2' } +let r3: Record = { ...r1, ...r2 } +console.log(...r3) // crash - Issue #26773 + + +/* @@? 17:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@? 17:1 Error TypeError: No matching call signature for log(...r1) */ +/* @@? 17:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@? 17:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ +/* @@? 17:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ +/* @@? 20:1 Error TypeError: No matching call signature for log(...r3) */ +/* @@? 20:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@? 20:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ +/* @@? 20:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ diff --git a/ets2panda/test/ast/compiler/ets/static_index_function1.ets b/ets2panda/test/ast/compiler/ets/static_index_function1.ets index a341c997c9b417632509952ffa3a6ed8e389b954..36c1a7ebd551ea117a3c9dfddb806c4a3aad9ba0 100644 --- a/ets2panda/test/ast/compiler/ets/static_index_function1.ets +++ b/ets2panda/test/ast/compiler/ets/static_index_function1.ets @@ -29,5 +29,5 @@ function main() { /* @@@ label Error TypeError: '$_get' is a static property of 'A' */ /* @@@ label1 Error TypeError: '$_get' is a static property of 'A' */ -/* @@@ label2 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label2 Error SyntaxError: Class cannot be used as object. */ /* @@@ label3 Error TypeError: '$_get' is a static property of 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/static_index_function2.ets b/ets2panda/test/ast/compiler/ets/static_index_function2.ets index 9659ccec5293ce7a09fafb82e05ed1dff5c5231c..c6ae1e214f8ca52e2e8482918f9a36c7aea8f192 100644 --- a/ets2panda/test/ast/compiler/ets/static_index_function2.ets +++ b/ets2panda/test/ast/compiler/ets/static_index_function2.ets @@ -27,5 +27,5 @@ function main(): int { } /* @@@ label Error TypeError: '$_set' is a static property of 'A' */ -/* @@@ label1 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label1 Error SyntaxError: Class cannot be used as object. */ /* @@@ label2 Error TypeError: '$_set' is a static property of 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/string_enum_unary.ets b/ets2panda/test/ast/compiler/ets/string_enum_unary.ets new file mode 100644 index 0000000000000000000000000000000000000000..68ca4eb5fadf8a2c1d71f6484bf4833801b8e4cc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/string_enum_unary.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. + */ + +enum Color {Red = "10"} + + +function main() { + arktest.assertEQ(~/* @@ label */Color.Red, ~10) + arktest.assertEQ(+/* @@ label1 */Color.Red, 10) + arktest.assertEQ(-/* @@ label2 */Color.Red, -10) + // This was allowed because enum is in extended conditional expression which is expected. + arktest.assertEQ(!Color.Red, !10) +} + +/* @@@ label Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@@ label1 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@@ label2 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ 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/stwitch_with_non_case.ets b/ets2panda/test/ast/compiler/ets/stwitch_with_non_case.ets new file mode 100644 index 0000000000000000000000000000000000000000..9741d6c34dfd7b2e51905bc61e2a536605088304 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/stwitch_with_non_case.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(x: int): string { + let rc = "default"; + switch (x) { } +} + +/* @@? 16:10 Error TypeError: Function with a non void return type must return a value. */ diff --git a/ets2panda/test/ast/compiler/ets/subtype.ets b/ets2panda/test/ast/compiler/ets/subtype.ets new file mode 100644 index 0000000000000000000000000000000000000000..5207d81c18227c28b0b3fef250bc61fa73f5abca --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/subtype.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. + */ + +interface Interface_1 {} +interface Interface_2 {} + +class GenericObject { + give(value: T) { + return value; + } +} + +interface Factory { + create(): T; +} + +class GenericObjectFactory implements Factory { + create(): GenericObject { + return new GenericObject(); + } +} + +function g(factory: Factory): T { + return factory.create(); +} + +const factory = new GenericObjectFactory(); +const obj = g(factory); +obj.give({}); + +/* @@? 19:58 Error TypeError: Type argument 'Interface_2' should be a subtype of 'Interface_1'-constraint */ 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/switch_case_null_tstype.ets b/ets2panda/test/ast/compiler/ets/switch_case_null_tstype.ets new file mode 100644 index 0000000000000000000000000000000000000000..e5cacaf668537b14bbfe830020f94752452ddf7d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/switch_case_null_tstype.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 arg='2'; +let v null|int=null; +class A{} +switch (arg){ + case v: + break; + case A: + break; +} + +/* @@? 17:7 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 17:7 Error SyntaxError: Unexpected token 'null'. */ +/* @@? 17:7 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 17:12 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 22:5 Error TypeError: Constant expression required */ +/* @@? 22:10 Error SyntaxError: Class cannot be used as object. */ +/* @@? 22:10 Error TypeError: Switch case type 'A' is not comparable to discriminant type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets index 116c419830283712211b242d46bfa09c3bf3e2e1..d1499c6e6e82ad7fcc75a975b902f456f8d67fbd 100644 --- a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets +++ b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets @@ -22,13 +22,13 @@ class IndexStr { indexField: string = "title" foo() { switch (this.indexField) { - /* @@ label */case IndexField.TITLE: - assertEQ(this.indexField, IndexField.TITLE) - break; case IndexField.TITLE: - assertEQ(this.indexField, IndexField.TITLE) + arktest.assertEQ(this.indexField, IndexField.TITLE) + break; + /* @@ label */case IndexField.TITLE: + arktest.assertEQ(this.indexField, IndexField.TITLE) } } } -/* @@@ label Error TypeError: Variable has same value with another switch case */ \ No newline at end of file +/* @@@ label Error TypeError: Case duplicate */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/template_fold.ets b/ets2panda/test/ast/compiler/ets/template_fold.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4255f98ba47d7a86666685d4100a2e3f9767496 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/template_fold.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +`\0#{(new (Reflect)() ? new () : {f: [], : 2})}${true}` + +/* @@? 16:2 Error SyntaxError: Octal escape sequences are not allowed in template strings. */ + diff --git a/ets2panda/test/ast/compiler/ets/then_ret.ets b/ets2panda/test/ast/compiler/ets/then_ret.ets new file mode 100644 index 0000000000000000000000000000000000000000..ccb920814022254cac89d0ca6eb8f762e322e1e1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/then_ret.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const asyncFunction = async () => { + return Promise.resolve(1.0) +}; + +let thenRet : Promise = asyncFunction() + .then((result) => { + return Promise.resolve(result + 2.0) + }) \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/this_expr_invalid_call_in_annotation_decl.ets b/ets2panda/test/ast/compiler/ets/this_expr_invalid_call_in_annotation_decl.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff742c6bddad68f907eee6c43571c03d026d81ba --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/this_expr_invalid_call_in_annotation_decl.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 Anno { + testBools: boolean[] = [ + this.barAttr = 0, + ] +} + +/* @@? 17:28 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/compiler/ets/this_in_wrong_context.ets b/ets2panda/test/ast/compiler/ets/this_in_wrong_context.ets new file mode 100644 index 0000000000000000000000000000000000000000..b9948db8a3ec5ea25d8f020fb616aadecf252bb5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/this_in_wrong_context.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 declare @interface ClassAuthor { + color: Color[] = [this.listener !== undefined] +} + +/* @@? 1:3 Error TypeError: Cannot find type 'Color'. */ +/* @@? 17:5 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ +/* @@? 17:22 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 17:23 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 17:23 Warning Warning: The instance field initializer expression cannot use the this. */ +/* @@? 17:28 Error TypeError: Property 'listener' does not exist on type 'Error' */ diff --git a/ets2panda/test/ast/compiler/ets/tryCatchErrorFlow.ets b/ets2panda/test/ast/compiler/ets/tryCatchErrorFlow.ets index 1b0e6ff8171ed285c7a7b46ab3d4eb44360211a9..4efd4a36f80aa0467017aeb9216d00588d215dac 100644 --- a/ets2panda/test/ast/compiler/ets/tryCatchErrorFlow.ets +++ b/ets2panda/test/ast/compiler/ets/tryCatchErrorFlow.ets @@ -18,7 +18,7 @@ function main(): void { throw new DivideByZeroError(); } catch (p){ //Do something. - } /* @@ label */catch (p: DivideByZeroError) { + } /* @@ label */catch (p) { //Do something. } } diff --git a/ets2panda/test/ast/compiler/ets/tryCatchErrorIncorrectParamType.ets b/ets2panda/test/ast/compiler/ets/tryCatchErrorIncorrectParamType.ets index 466b07dfcb6e2d64959eb6d5ef17abc280e9d9c7..9c4729d53c6be97c4e74a5d6ce9b395c5ee3aefc 100644 --- a/ets2panda/test/ast/compiler/ets/tryCatchErrorIncorrectParamType.ets +++ b/ets2panda/test/ast/compiler/ets/tryCatchErrorIncorrectParamType.ets @@ -16,9 +16,7 @@ function main(): void { try { throw new Error(); - } catch (/* @@ label */p: Object) { + } catch (p) { //Do something. } } - -/* @@@ label Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ diff --git a/ets2panda/test/ast/compiler/ets/tryCatchFlow.ets b/ets2panda/test/ast/compiler/ets/tryCatchFlow.ets index e7ab397a8977d58f2a05eedebb5045ec9573fb05..b64f40fc663b11e3fa70c05b1f62bb7251592253 100644 --- a/ets2panda/test/ast/compiler/ets/tryCatchFlow.ets +++ b/ets2panda/test/ast/compiler/ets/tryCatchFlow.ets @@ -18,9 +18,5 @@ function main(): void { //Exception occures here. } catch (e) { //Do something. - } /* @@ label */catch (e: NullPointerError) { - //Do something. } } - -/* @@@ label Error TypeError: Default catch clause should be the last in the try statement */ diff --git a/ets2panda/test/ast/compiler/ets/tryCatchIncorrectParamType.ets b/ets2panda/test/ast/compiler/ets/tryCatchIncorrectParamType.ets index 1dd8994ce2f4f7d7d97a8fb0c1d0bf70c048961a..ddcca948af331254f57458e9a9151da09bdb0669 100644 --- a/ets2panda/test/ast/compiler/ets/tryCatchIncorrectParamType.ets +++ b/ets2panda/test/ast/compiler/ets/tryCatchIncorrectParamType.ets @@ -16,8 +16,7 @@ function main(): void { try { //Exception occures here. - } catch (/* @@ label */e: Object) { + } catch (e) { //Do something. } } -/* @@@ label Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ diff --git a/ets2panda/test/ast/compiler/ets/try_catch_already_declared.ets b/ets2panda/test/ast/compiler/ets/try_catch_already_declared.ets new file mode 100644 index 0000000000000000000000000000000000000000..81a718b1216d20cff6c6eb00c6b894779ecc47d6 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/try_catch_already_declared.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. + */ + +try { +} catch (a) { + let a = 1 +} + +/* @@? 18:9 Error TypeError: Variable 'a' has already been declared. */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets index d874643b8fda8e8ee67c8107849ba96862e381f3..b03095bb29c8f63584f53ab314ea686c0139ae6b 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double]' cannot be assigned to type '[double, double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double]' cannot be assigned to type '[Double, Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets index 5c6ff60feaf69b0d7667706807265a3547ebcb1d..b6a37f7126cb07e239ba9a58b735f2b9fe0e6b4b 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double, double]' cannot be assigned to type '[double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double, Double]' cannot be assigned to type '[Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_13_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_13_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..6ffa4811bc60b930637d00cf97047235a7b8b68e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tuple_types_13_neg.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. + */ + +// move this test case to runtime test after the CTE is fixed +class A { + A = 1; + static readonly KEY = 0; + static readonly KEY1 = 1; + + foo() { + let tuple: [number, string] = [0, "a"]; + arktest.assertEQ(tuple[A.KEY], 0); + arktest.assertEQ(tuple[A.KEY1], "a"); + } +} + +/* @@? 24:32 Error TypeError: Element accessor value is out of tuple size bounds. */ +/* @@? 25:32 Error TypeError: Element accessor value is out of tuple size bounds. */ 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 c29473759b9c2c045f362a56710bf22a2a7fafb5..ea8e9d99a571a33951a62d101b72f40b3ca9978b 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_6_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets index 7f792a64d5403a11eb9a37a030c7c38777304655..0d723e75d437c8cbc73f88bde06c830465eca726 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets @@ -16,7 +16,6 @@ function main(): void { let a: [number] = [1]; - let b: [Number] = /* @@ label */a; + let b: [Number] = a; } -/* @@@ label Error TypeError: Type '[double]' cannot be assigned to type '[Double]' */ 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 0a18e7020b610612f17cf9be1e4f8b2f61322d45..ea48bd251d88f0246ff63e8ff3fe23bb9b4410ea 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets @@ -22,10 +22,5 @@ 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 '='. */ -/* @@@ label Error TypeError: Type '[double, String, *ERROR_TYPE*]' cannot be assigned to type '[double, String, Int]' */ diff --git a/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_01.ets b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..976f1c71f6cdaf3aa8f97d3ada30bf5e0e532b3b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_01.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. + */ + +type ValueAlias = Record<"val", V>; + +declare function value(): ValueAlias; + + +/* @@@ label Error TypeError: Type argument 'U' should be a subtype of 'String'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_02.ets b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..96cf4d03326b0bafb8935e69cb3d221657f63c8c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_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. + */ + +type ValueAlias = Record<"val", V>; + +declare function value(): ValueAlias; + +/* @@ label */value(); + + +/* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_03.ets b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_03.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5d5d8815d23d6f9a844aca71ea07e7087ccd074 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_03.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type ValueAlias = Record<"val", V>; + +declare function value(): ValueAlias; + +value(); diff --git a/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_04.ets b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_04.ets new file mode 100644 index 0000000000000000000000000000000000000000..7378bd24f9ea49436f55c00fad536ef825b814b9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typeAliasWithConstraint_04.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 = T; + +let v: A; + + +/* @@@ label1 Error TypeError: Type argument 'Int' should be a subtype of 'String'-constraint */ +/* @@@ label2 Error TypeError: Type argument 'String' should be a subtype of 'Numeric'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/type_alise_with_lambda.ets b/ets2panda/test/ast/compiler/ets/type_alise_with_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..3b39e198c9b2f0474894efc6606986117daa8b22 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_alise_with_lambda.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 type L T> + +/* @@? 16:26 Error TypeError: Cannot find type 'T'. */ +/* @@? 21:1 Error SyntaxError: Expected '=', got 'end of stream'. */ +/* @@? 21:1 Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/compiler/ets/type_as_value.ets b/ets2panda/test/ast/compiler/ets/type_as_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..2fdb848aaef88b463c0cb23c3ad397fee714d7a1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_as_value.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 a = number[][] + +/* @@? 16:17 Error TypeError: 'Array>' only refers to a type, but is being used as a value here. */ \ No newline at end of file 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..46b03a8e16d9cb89c6776cf7ad86ced8efba602c 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: Class name 'WeakSet' used in the wrong context */ /* @@? 26:1 Error TypeError: Object type doesn't have proper index access method. */ +/* @@? 26:1 Error SyntaxError: Class cannot be used as object. */ /* @@? 26:16 Error TypeError: Type 'undefined' is not constructible. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/param_typeannotation_null.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/param_typeannotation_null.ets new file mode 100644 index 0000000000000000000000000000000000000000..71e76536db95195f451ec2584e8ae947aa24a29d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/param_typeannotation_null.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 inter { + get value(): Double; + set value(A = Int.MAX_VALUE + 1); +} + +function foo(i: Partial>): void {} + +/* @@? 18:17 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/property_typeerror.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/property_typeerror.ets new file mode 100644 index 0000000000000000000000000000000000000000..345a9e3ef7caa7a721626af9795859b8d9ecc564 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/property_typeerror.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 { + set property(break) {} +} + +function foo (partial: Partial) {} + +/* @@? 17:15 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:16 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:16 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:16 Error SyntaxError: Unexpected token 'break'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:23 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets index 7e42c8c105bf2b5241abc90fbd791e8fbf2f671c..f3cc9e64c33dc67868eca46d1e389b42f69e6568 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets @@ -40,14 +40,11 @@ type T15 = Required /* @@? 22:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 24:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 25:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ -/* @@? 26:18 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 28:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 30:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 31:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ -/* @@? 32:20 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 34:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 36:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 37:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ -/* @@? 38:20 Error TypeError: Only reference types can be converted to utility types. */ 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 f845db8bb1c59e9476aa76d659bceac367ce60f7..799e9d1a8063e84e303b53ecf815ade00a1d014c 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 @@ -24,8 +24,7 @@ function foo() { void = [([...asyncGenerator])] } -/* @@? 16:1 Error TypeError: Unresolved reference a */ -/* @@? 20:1 Error TypeError: Unresolved reference c */ +/* @@? 21:9 Error TypeError: Unresolved reference a */ +/* @@? 21:17 Error TypeError: Unresolved reference c */ /* @@? 24:5 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 24:10 Error SyntaxError: Unexpected token '='. */ /* @@? 24:18 Error TypeError: Unresolved reference asyncGenerator */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_test.ets b/ets2panda/test/ast/compiler/ets/type_error_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..cbb33753e830d5f3662f40bf1d22372839d3ac50 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_error_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. + */ + +export class SHA1Hash{ + private _int32(data:Int32Array,offset?:int):void{ + offset=0 + swap32(data[offset ++] as int) + } +} +const swap32:(num:int)=>int = ((c:int):int =>c) + +/* @@? 19:16 Warning Warning: 'As' expression for cast is deprecated for numeric types. Use explicit conversion function Double.toInt(...) instead. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_test2.ets b/ets2panda/test/ast/compiler/ets/type_error_test2.ets new file mode 100644 index 0000000000000000000000000000000000000000..08c72c921ab06fa7752e36ba967dfb6a2c01800c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_error_test2.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let f:(c:string, ...abe])=>void = (c:be ...abe])=>{} + +/* @@? 16:18 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 16:24 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 16:24 Error SyntaxError: Rest parameter must be the last formal parameter. */ +/* @@? 16:35 Error TypeError: Type '(c: *ERROR_TYPE*) => void' cannot be assigned to type '(c: String, ...abe: *ERROR_TYPE*) => void' */ +/* @@? 16:38 Error TypeError: Cannot find type 'be'. */ +/* @@? 16:41 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:41 Error SyntaxError: Expected '=>', got '...'. */ +/* @@? 16:41 Error SyntaxError: Unexpected token '...'. */ +/* @@? 16:41 Error TypeError: Unexpected return value, enclosing method return type is void. */ +/* @@? 16:44 Error SyntaxError: Unexpected token 'abe'. */ +/* @@? 16:44 Error TypeError: Unresolved reference abe */ +/* @@? 16:47 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:49 Error SyntaxError: Unexpected token '=>'. */ diff --git a/ets2panda/test/ast/compiler/ets/type_parameter.ets b/ets2panda/test/ast/compiler/ets/type_parameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..d453160a29bae5fff51f25ffed42675bab83ce7a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/type_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. + */ + +type foo + +let a : foo = 1; + +/* @@? 16:15 Error TypeError: Type Parameter T should be defined before use. */ +/* @@? 18:1 Error SyntaxError: Expected '=', got 'let'. */ +/* @@? 18:1 Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets b/ets2panda/test/ast/compiler/ets/typealias_as_value.ets similarity index 80% rename from ets2panda/linter/test/main/prop_name_from_value.ets rename to ets2panda/test/ast/compiler/ets/typealias_as_value.ets index bdfdc1a80d5529ad17bdec94f11f1a0e7e493de8..e6f3bb13a735fddfbc53d9b1ef91d04416d4b067 100644 --- a/ets2panda/linter/test/main/prop_name_from_value.ets +++ b/ets2panda/test/ast/compiler/ets/typealias_as_value.ets @@ -13,13 +13,10 @@ * limitations under the License. */ -enum TEST { - A, - B, - C +type RF = (p:RF) => RF + +function main(){ + let v1 = () => {return RF} } -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 +/* @@? 19:28 Error TypeError: Type name 'RF' used in the wrong context */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/typealias_conflict_with_builtin.ets b/ets2panda/test/ast/compiler/ets/typealias_conflict_with_builtin.ets new file mode 100644 index 0000000000000000000000000000000000000000..80fc58e64188eedb24fa7c62050c0ad92d25ce3d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typealias_conflict_with_builtin.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. + */ + +type Type = int; + +/* @@? 1:3 Error TypeError: Class 'Type' is already defined with different type. */ diff --git a/ets2panda/test/ast/compiler/ets/typealias_default_type_01.ets b/ets2panda/test/ast/compiler/ets/typealias_default_type_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..b7051016a8b9613cff7ce9aa7589dc585c3b65d5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typealias_default_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. + */ + +type ErrorCallBack1 = (err: T) => void + +type ErrorCallBack2 = (err: T) => void + +function test1(call: ErrorCallBack1) { } // should be ok + +function test2(call: ErrorCallBack2) { } // should be error because typeParam has no default type + +function test3(call: ErrorCallBack2) { } // should be ok because we have explicitly provided a type. + +/* @@? 22:22 Error TypeError: Type alias declaration is generic, but too few type arguments were provided */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/typealias_default_type_02.ets b/ets2panda/test/ast/compiler/ets/typealias_default_type_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f91a1fe204dd57a024b9c768f51b2d1ae9ca5f4 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/typealias_default_type_02.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. + */ + +type ErrorCallBack1 = (err: T) => R + +type ErrorCallBack2 = (err: T) => R + +type ErrorCallBack3 = (err: T) => R + +function test1(call: ErrorCallBack1) { } // should be ok + +function test2(call: ErrorCallBack2) { } // should be error because typeParam has no default type + +function test3(call: ErrorCallBack2) { } // should be error because we have not provided all types. + +function test4(call: ErrorCallBack2) { } // should be ok because we have provided all types. + +function test5(call: ErrorCallBack3) { } // should be ok because the second type param has a default type + +function test6(call: ErrorCallBack3) { } // should be error + +/* @@? 24:22 Error TypeError: Type alias declaration is generic, but too few type arguments were provided */ +/* @@? 26:36 Error TypeError: Expected at least 2 type arguments, but got 1. */ +/* @@? 32:22 Error TypeError: Type alias declaration is generic, but too few type arguments were provided */ \ No newline at end of file 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/unexpected_param_01.ets b/ets2panda/test/ast/compiler/ets/unexpected_param_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e15bcbf7dada134279d2b9f12f5c685e0b3a4ab --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unexpected_param_01.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 byteP: Promise = byteFunc() +let pthen = byteP.then((value ? Object): Object => { + return value + +}); +await byteP; + +/* @@? 16:30 Error TypeError: Unresolved reference byteFunc */ +/* @@? 17:41 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:41 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:41 Error SyntaxError: Expected '=>', got 'identification literal'. */ +/* @@? 17:41 Error SyntaxError: Class cannot be used as object. */ +/* @@? 17:48 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:50 Error SyntaxError: Unexpected token 'Object'. */ +/* @@? 17:50 Error TypeError: The type of parameter 'Object' cannot be inferred */ +/* @@? 18:12 Error TypeError: Unresolved reference value */ +/* @@? 20:2 Error SyntaxError: Unexpected token ')'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/unexpected_param_02.ets b/ets2panda/test/ast/compiler/ets/unexpected_param_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5bb53c7ebb55422acc3f0b24ff8b109b185e907 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unexpected_param_02.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?){} + +/* @@? 16:16 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/unionCommonMember_neg.ets b/ets2panda/test/ast/compiler/ets/unionCommonMember_neg.ets index be96553f9d317cdf82a501eadebd625caa460aa9..f03ea9734f398242b012ee3ac1dfefae39255300 100644 --- a/ets2panda/test/ast/compiler/ets/unionCommonMember_neg.ets +++ b/ets2panda/test/ast/compiler/ets/unionCommonMember_neg.ets @@ -41,21 +41,20 @@ function getUnion(): A | B { function main() { const u = getUnion() - assertEQ(/* @@ label1 */u.fld1, 42) - assertEQ(/* @@ label2 */u.fld2, 42.0) - assertEQ(/* @@ label3 */u.fld3[0], "abc") - assertEQ(/* @@ label4 */u.fld4[0], "def") - assertEQ(/* @@ label5 */u.fld5, 42.0) - assertEQ(/* @@ label6 */u.fld6, 42.0) - assertEQ(/* @@ label7 */u.fld7, 42.0) - assertEQ(/* @@ label8 */u.fld8, new Map()) + arktest.assertEQ(/* @@ label1 */u.fld1, 42) + arktest.assertEQ(/* @@ label2 */u.fld2, 42.0) + arktest.assertEQ(/* @@ label3 */u.fld3[0], "abc") + arktest.assertEQ(/* @@ label4 */u.fld4[0], "def") + arktest.assertEQ(/* @@ label5 */u.fld5, 42.0) + arktest.assertEQ(/* @@ label6 */u.fld6, 42.0) + arktest.assertEQ(/* @@ label7 */u.fld7, 42.0) + arktest.assertEQ(/* @@ label8 */u.fld8, new Map()) } -/* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label2 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label3 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label4 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label5 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label6 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label7 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label8 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label3 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label4 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label5 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label6 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label7 Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label8 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/unionType_clone.ets b/ets2panda/test/ast/compiler/ets/unionType_clone.ets new file mode 100644 index 0000000000000000000000000000000000000000..1af439f0e8543de1bee657ea7694ae31acac4155 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unionType_clone.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. + */ + +function castValueKoBoolean(value ?: boolect) { + if (value instanceof Sean) { + if (value === undefined) return; + + let innerValue = !value; +} : xml.XmlDyastValueToString(value: Object) { + if (value instanceof String) { + value += "Hello Smar/* + +/* @@? 16:38 Error TypeError: Cannot find type 'boolect'. */ +/* @@? 17:26 Error TypeError: Cannot find type 'Sean'. */ +/* @@? 21:3 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:5 Error SyntaxError: Unexpected token 'xml'. */ +/* @@? 21:5 Error TypeError: Unresolved reference xml */ +/* @@? 21:36 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 21:36 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:38 Error SyntaxError: Unexpected token 'Object'. */ +/* @@? 21:38 Error SyntaxError: Class cannot be used as object. */ +/* @@? 21:44 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:46 Error SyntaxError: Unexpected token '{'. */ +/* @@? 23:18 Error SyntaxError: Newline is not allowed in strings */ +/* @@? 37:70 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/compiler/ets/union_field_access.ets b/ets2panda/test/ast/compiler/ets/union_field_access.ets new file mode 100644 index 0000000000000000000000000000000000000000..33cb90075f7fa1295cef7c0d4e22a26a10d9202c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_field_access.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. + */ + +type U = TypeA | TypeB; + +interface TypeA { + kind: 'A'; + a: number; +} +interface TypeB { + kind: 'B'; + b: string; +} + +function IfWithString(val: U) { + return /* @@ label */val['kind'] === 'B' +} + +/* @@@ label Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/compiler/ets/union_field_access_2.ets b/ets2panda/test/ast/compiler/ets/union_field_access_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f9fd604200891c531d16c50c85e7f13565b8d3c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_field_access_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. + */ + +// ensure compiler doesn't crash when compiling invalid code. + +(a ? delete arguments==({: false, Float64Array: []}) : [ArrayBuffer[false]]) + +/* @@? 18:1 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 18:2 Error TypeError: Unresolved reference a */ +/* @@? 18:6 Error TypeError: Types cannot be modified at runtime with 'delete'. */ +/* @@? 18:13 Error SyntaxError: Unexpected token. */ +/* @@? 18:13 Error TypeError: Unresolved reference arguments */ +/* @@? 18:24 Error TypeError: need to specify target type for class composite */ +/* @@? 18:26 Error SyntaxError: Unexpected token. */ +/* @@? 18:28 Error SyntaxError: Unexpected token. */ +/* @@? 18:54 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 18:76 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets b/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets index 7bfd2cf937262bf035483ffce67df1e3bf0bd467..df0895904f95a6d29227998b0d60d3f9817d4480 100644 --- a/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets +++ b/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets @@ -35,14 +35,14 @@ let u3: A|A = new A(11) let u4: A|A = new A('a') function main() { - assertEQ(u1.fld, 'b') - assertEQ(u2.fld, 10) + arktest.assertEQ(u1.fld, 'b') + arktest.assertEQ(u2.fld, 10) - assertEQ(u3.fld, 11) - assertEQ(u4.fld, 'a') + arktest.assertEQ(u3.fld, 11) + arktest.assertEQ(u4.fld, 'a') } -/* @@? 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. */ +/* @@? 38:22 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 39:22 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 41:22 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 42:22 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/union_overload_crash.ets b/ets2panda/test/ast/compiler/ets/union_overload_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..01d75715b7a7840938025bb0989de29ffe62b83d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_overload_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 A { + foo() {} + foo(a : number) {} +} + +type AVoidNumber = A | A + +let a = new A(); + +(a as AVoidNumber).foo !== undefined + +/* @@? 25:1 Error TypeError: Overloaded method is used as value */ 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/union_type.ets b/ets2panda/test/ast/compiler/ets/union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e3cb3e06d0aeb0c298d4e2a16563321655fb514 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_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. + */ + +class A { + foo() {} +} + +interface B { + foo?: () => void; +} + +function foo1(x : A | B) { + if (x.foo) { + return; + } +} + +/* @@? 25:9 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/union_type_of_partial_type.ets b/ets2panda/test/ast/compiler/ets/union_type_of_partial_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..e4ea92495b82b4c51bb4f9c482368c1fc0edba7c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_type_of_partial_type.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: * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 A>{ + foo({ }, init: Partial | undefined): void { + } +} + +/* @@? 16:9 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:9 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 16:9 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:12 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:27 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 16:42 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:43 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:45 Error SyntaxError: void is a predefined type, cannot be used as an identifier */ +/* @@? 16:50 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/compiler/ets/union_types_4.ets b/ets2panda/test/ast/compiler/ets/union_types_4.ets index 0933a8cae7996d2451bdee90bfd7ca4867902c26..f22ce635f51e9f947df5343ad481105d66559f9e 100644 --- a/ets2panda/test/ast/compiler/ets/union_types_4.ets +++ b/ets2panda/test/ast/compiler/ets/union_types_4.ets @@ -22,11 +22,11 @@ class B {} function main() { let x : String | short | A = 5 as short; - assertEQ((x as short) * 2, 10, "Error! Must be 10"); + arktest.assertEQ((x as short) * 2, 10, "Error! Must be 10"); x = "STRSTR"; - assertTrue((x as String).equals("STRSTR"), "Error! Must be `STRSTR`") + arktest.assertTrue((x as String).equals("STRSTR"), "Error! Must be `STRSTR`") x = new A(); - assertEQ((x as A).num, 42, "Error! Field of A must be `42`"); + arktest.assertEQ((x as A).num, 42, "Error! Field of A must be `42`"); x = /* @@ label */new B(); // CTE } diff --git a/ets2panda/test/ast/compiler/ets/union_types_forof_1.ets b/ets2panda/test/ast/compiler/ets/union_types_forof_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b13724b2d10945e3c15315d3c042c2b2c7793f73 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_types_forof_1.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 processValue(value: string | number): void { + if (typeof value === 'string') { + // Handle string case + for (const it of value) { + console.log(it); + } + } else { + // Handle number case + console.log(value.toString()); + } +} + +const testValues: (string | number)[] = ['hello', 42, 'world', 7]; + +for (const item of testValues) { + processValue(item); +} + +/* @@? 19:26 Error TypeError: Object type doesn't have proper iterator method. */ 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..81037bd2a560d695e393f4d1b2852abfa1225b60 --- /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(Double, "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(Double, 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. */ diff --git a/ets2panda/test/ast/compiler/ets/unresolve_class_with_type_infer.ets b/ets2panda/test/ast/compiler/ets/unresolve_class_with_type_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..472597e3c531be5f6c8824116dfa8a1217156688 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unresolve_class_with_type_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>(record: Record>){ + +} + +foo({}) + +/* @@? 16:39 Error TypeError: Cannot find type 'A'. */ +/* @@? 16:73 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 20:1 Error TypeError: No matching call signature for foo(...) */ +/* @@? 20:5 Error TypeError: need to specify target type for class composite */ diff --git a/ets2panda/test/ast/compiler/ets/unresolved_reference.ets b/ets2panda/test/ast/compiler/ets/unresolved_reference.ets index f2dff3a5f03ca1c9f2220cca228ded133516c56c..9478fc0e84d5c05b9fa08f7c6f6f748fe0426ea5 100644 --- a/ets2panda/test/ast/compiler/ets/unresolved_reference.ets +++ b/ets2panda/test/ast/compiler/ets/unresolved_reference.ets @@ -37,5 +37,5 @@ function main() { let a = (new A).b } -/* @@? 28:13 Error TypeError: Unresolved reference b */ +/* @@? 16:13 Error TypeError: Unresolved reference b */ /* @@? 37:21 Error TypeError: Property 'b' does not exist on type 'A' */ diff --git a/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/file1.ets b/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/file1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f2b2c5a5597ebb6f33383e06f6ef81567433d221 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/file1.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. + */ + + +export function atomicTask() { + const buffer = new ArrayBuffer(4); + const sharedArray = new Int32Array() + for (let i = 0; i < 10; i++) { + Atomics.add(shareArray, 0, 1); + } + return Atomics.load(shareArray, 0); +} + +/* @@? 21:17 Error TypeError: Unresolved reference shareArray */ +/* @@? 23:12 Error TypeError: Call to `load` is ambiguous as `2` versions of `load` are available: `load(typedArray: BigInt64Array, index: Double): BigInt` and `load(typedArray: BigUint64Array, index: Double): BigInt` */ diff --git a/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/main_test.ets b/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/main_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..d5901ed027ab34b7dfdb4452e19f09fb29e679bf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unresolved_reference_identifier/main_test.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 {atomicTask} from "./file1" +const task = new taskpool.Task(atomicTask); + +/* @@? file1.ets:23:12 Error TypeError: Call to `load` is ambiguous as `2` versions of `load` are available: `load(typedArray: BigInt64Array, index: Double): BigInt` and `load(typedArray: BigUint64Array, index: Double): BigInt` */ +/* @@? file1.ets:23:25 Error TypeError: Unresolved reference shareArray */ diff --git a/ets2panda/test/ast/compiler/ets/update_const.ets b/ets2panda/test/ast/compiler/ets/update_const.ets new file mode 100644 index 0000000000000000000000000000000000000000..15ffd430673492a7e6c6f970300e7698288ade34 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/update_const.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(): void { + const c = 0; + /* @@ label */++c; +} + +/* @@@ label Error TypeError: Cannot assign to a constant variable c */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/export1.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/export1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3b6361ce1a4789171931375970fec7e30eca2183 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/export1.ets @@ -0,0 +1,17 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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{} diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/export2.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/export2.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd2d2b0a2bb7edc167a63a31f8c942f328adc945 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/export2.ets @@ -0,0 +1,17 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 B{} diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_copyright.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_copyright.ets new file mode 100644 index 0000000000000000000000000000000000000000..f5862745c147147f51b9ec5b5714f065230eda3a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_copyright.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" + +class A{} diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_importdecl.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_importdecl.ets new file mode 100644 index 0000000000000000000000000000000000000000..7245e8367d5aac3c021703a513bf65f2dd5e008a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_after_importdecl.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 as A } from "./export1.ets" +import { B as B } from "./export2.ets" + +"use static" +let str:String = "use static" diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_before_importdecl.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_before_importdecl.ets new file mode 100644 index 0000000000000000000000000000000000000000..730bab7c5d8dcef84f875cf13ec9b48d068168c1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_before_importdecl.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" +import {A as A} from "./export1.ets" +import {B as B} from "./export2.ets" diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line.ets new file mode 100644 index 0000000000000000000000000000000000000000..34045c2ff1fba6cbc4f2b9e554a52993a8dc8092 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line.ets @@ -0,0 +1,17 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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{} diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..c14b258b49588ae4c02145599c8dfabaa7bde4ea --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2.ets @@ -0,0 +1,17 @@ +'use static' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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{} diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2_neg.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..df09abb5e1ee956798bed2bc2115dfee085086c2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_2_neg.ets @@ -0,0 +1,19 @@ +'use statics' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 as A } from "./export1.ets" + +/* @@? 17:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_3_neg.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_3_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..1b1cd257acd0d0cbf73be91edb3d5b127469f7ec --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_3_neg.ets @@ -0,0 +1,19 @@ +"uses static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 as A } from "./export1.ets" + +/* @@? 17:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_neg.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0a410adc716e144cc402fdb62ae96b724f39a06 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_in_first_line_neg.ets @@ -0,0 +1,19 @@ +'uses static' +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 as A } from "./export1.ets" + +/* @@? 17:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/flag_middle_importdecl_neg.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_middle_importdecl_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..b048662c5703cee2ba8b580714f257041e2bc5f8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/flag_middle_importdecl_neg.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 as A} from "./export1.ets" +"use static" +import {B as B} from "./export2.ets" + +/* @@? 18:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package.ets new file mode 100644 index 0000000000000000000000000000000000000000..07508594ee080e6a93496f8f2806936dc7881ee8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package.ets @@ -0,0 +1,17 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 usestaticpackage; diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package2.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package2.ets new file mode 100644 index 0000000000000000000000000000000000000000..07508594ee080e6a93496f8f2806936dc7881ee8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package/flag_before_package2.ets @@ -0,0 +1,17 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 usestaticpackage; diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package_2_neg/flag_before_package.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package_2_neg/flag_before_package.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee44269d82572ab85a05a0214ff273283d4a6b39 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package_2_neg/flag_before_package.ets @@ -0,0 +1,24 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 usestaticpackage3; + +let str2:String = "use static" +import {A as A} from "../export1.ets" +import {B as B} from "../export2.ets" + +/* @@? 20:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ +/* @@? 21:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package_3_neg/flag_before_package.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package_3_neg/flag_before_package.ets new file mode 100644 index 0000000000000000000000000000000000000000..55490f06d0b94f607cc3ecab80a8e8b9cc0eddd2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package_3_neg/flag_before_package.ets @@ -0,0 +1,25 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 usestaticpackage3; + +"use static" +import {A as A} from "../export1.ets" +import {B as B} from "../export2.ets" + +/* @@? 19:1 Error SyntaxError: Invalid package toplevel statement */ +/* @@? 20:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ +/* @@? 21:1 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae374bb21fb24b2b877438455e694bd9f3e729cd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package.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. + */ + +package usestaticpackage2; + +"use static" + +/* @@? 18:1 Error SyntaxError: Invalid package toplevel statement */ diff --git a/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package2.ets b/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package2.ets new file mode 100644 index 0000000000000000000000000000000000000000..551145bbe750acc82006c7d76ef820ae82d68dcd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/use_static_flag/package_neg/flag_package2.ets @@ -0,0 +1,19 @@ +"use static" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 usestaticpackage2; + +/* @@? flag_package.ets:18:1 Error SyntaxError: Invalid package toplevel statement */ diff --git a/ets2panda/test/ast/compiler/ets/utility_type_can_not_found_etsobjecttype.ets b/ets2panda/test/ast/compiler/ets/utility_type_can_not_found_etsobjecttype.ets new file mode 100644 index 0000000000000000000000000000000000000000..d92b4f5bde2f8ccf9086d89fd25a971b111e6f17 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/utility_type_can_not_found_etsobjecttype.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. + */ + +type BaseObject = Record; + +class X { + x: T; + + constructor(init?: Partial) { + + this.x = {} as T; + + } +} + +/* @@? 16:34 Error TypeError: Cannot find type 'xny'. */ +/* @@? 21:29 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 23:14 Error TypeError: Target type for class composite needs to be an object type, found 'T' */ 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..56379e67dbe0238974ae76eed3723fd3318d30f6 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 @@ -14,7 +14,5 @@ */ function main() : void { - let a: Byte = /* @@ label */new Byte(2); + let a: Byte = new Byte(2); } - -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ 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..a7b4bf5973bc15b55d66b4e363546a50b98f31a6 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: No matching construct signature for std.core.Float(int, "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/voidTypeInBinaryOperation.ets b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets index 14947fde7e913d4efb9ed5c7b9ebf9620d63b70b..92db5f8ba840084ef330bbbedd41e1a31c204853 100644 --- a/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets +++ b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets @@ -17,9 +17,9 @@ function check(): void { } function main(): void { - assertTrue(false || check()) + arktest.assertTrue(false || check()) } -/* @@? 20:3 Error TypeError: No matching call signature for assertTrue(void) */ -/* @@? 20:23 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 20:23 Error TypeError: Type 'void' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@? 20:3 Error TypeError: No matching call signature for assertTrue(Boolean|void) */ +/* @@? 20:22 Error TypeError: Type 'Boolean|void' is not compatible with type 'Boolean' at index 1 */ +/* @@? 20:31 Error TypeError: Cannot use type 'void' as value. */ 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 c54c59d67a72ef256bd830f57e4f54a1c101b441..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 @@ -18,6 +18,3 @@ async function foo():Promise{ } /* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 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 d93580a127a2e4c45a243461d049dd5836025550..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 @@ -18,9 +18,3 @@ function foo(x: T) {} foo(void) /* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 18:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ')'. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/with-statement.ets b/ets2panda/test/ast/compiler/ets/with-statement.ets new file mode 100644 index 0000000000000000000000000000000000000000..98519d8934800b5a5a94a939d7f5b57f52d1cc20 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/with-statement.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. + */ + + // arkts-no-with + +function main(): void { + /* @@ label1 */with(/* @@ label2 */Math) { + let r: number = 42 + console.log("Area: ", PI * r * r) + } +} + +/* @@@ label1 Error SyntaxError: 'with' statement is not supported, please use fully qualified names! */ +/* @@@ label1 Error TypeError: Expected 3 arguments, got 1. */ +/* @@@ label1 Error TypeError: No matching call signature for with(Math) */ +/* @@@ label1 Error TypeError: Expected 3 arguments, got 1. */ +/* @@@ label2 Error TypeError: Class or interface 'Math' cannot be used as object */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/user_defined_27.ets b/ets2panda/test/ast/compiler/ets/without_semicolon_before_struct_declaration.ets similarity index 82% rename from ets2panda/test/ast/parser/ets/user_defined_27.ets rename to ets2panda/test/ast/compiler/ets/without_semicolon_before_struct_declaration.ets index 73cfa2236bcae2dfc1bc2a9ce90e035ce31852a7..95aac85f2fe82d954f73743e8945375749c84ccc 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_27.ets +++ b/ets2panda/test/ast/compiler/ets/without_semicolon_before_struct_declaration.ets @@ -13,8 +13,10 @@ * limitations under the License. */ -struct instanceof{ - a : string = "15"; +let x: number = 1; +const y: number = x +struct C { + f: number = 1; } -/* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ +/* @@? 18:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/wrong_variable_binding.ets b/ets2panda/test/ast/compiler/ets/wrong_variable_binding.ets new file mode 100644 index 0000000000000000000000000000000000000000..c9f2d161ac777d0a94186bbc33fbac1ace9ae92b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/wrong_variable_binding.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 { + + public C; + + public C: "+v)"; + + public constructor() {} + + } + + class D extends C{} + +/* @@? 19:13 Error SyntaxError: Field type annotation expected. */ +/* @@? 21:12 Error TypeError: Variable 'C' has already been declared. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/xgc_ea/xgc_ea.ets b/ets2panda/test/ast/compiler/ets/xgc_ea/xgc_ea.ets new file mode 100755 index 0000000000000000000000000000000000000000..05b98fcb0a68a6c37b33e96200c65aaf43680e4c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/xgc_ea/xgc_ea.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: * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 xgc_ea + +const SHARED_OBJECTS_COUNT: testResult, "test20 $2" + +/* @@? 17:7 Error SyntaxError: Missing initialization for const package property */ +/* @@? 17:29 Error TypeError: Cannot find type 'testResult'. */ +/* @@? 17:41 Error SyntaxError: Identifier expected, got 'string literal'. */ +/* @@? 17:41 Error SyntaxError: Number, string or computed value property name 'test20 $2' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 23:95 Error SyntaxError: Variable must be initialized or it's type must be declared. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/AllowSequence.ets b/ets2panda/test/ast/parser/ets/AllowSequence.ets index 3e72a4ceecf450336af8c0be3eb7c813c5bb51f8..54699864e1235d2fe6fba812836e27f499bcd4f4 100644 --- a/ets2panda/test/ast/parser/ets/AllowSequence.ets +++ b/ets2panda/test/ast/parser/ets/AllowSequence.ets @@ -21,8 +21,4 @@ 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 ')'. */ +/* @@? 19:17 Error SyntaxError: Comma operator is supported only in 'for' loops. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets b/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets index 43ec5bf3168e11e89ef8eedfe57a560f43c1e3f8..8a366c6af3d6d0c024d56523d22573abc69418b2 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: Type 'Array<() => Int>' cannot be assigned to type '() => FixedArray' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets b/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets index b9334bb5d7603461956eec9c9b1c04b0bf9755dd..ea7ab949d18acc732ada531af4acf9454910abe8 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets @@ -15,7 +15,7 @@ try { let x = 77 -} catch(a: exception) +} catch(a) } try @@ -41,22 +41,22 @@ function foo() { 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: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: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'. */ +/* @@? 42:16 Error SyntaxError: 'in' operator is not supported. Use 'instanceof' operator to check whether an object is the instance of a class that contains the necessary class member. */ +/* @@? 42:28 Error SyntaxError: Expected ';', got ')'. */ +/* @@? 42:28 Error SyntaxError: Invalid left-hand side in 'For[In/Of]Statement'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets index 78b272bb38af482c3cb05ba89df214ccddb781b6..93e45d54543314685369023f1f128998e3034dae 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets @@ -104,7 +104,7 @@ function foo(... a: byte): void {} native function foo(... b: byte): long; function min(v: double, u: double): double { - assertTrue(false) + arktest.assertTrue(false) return v < u ? v : u; } @@ -138,12 +138,12 @@ function main(): void { //Do something. } - assertTrue(foo(), undefined); + arktest.assertTrue(foo(), undefined); f(0); let a10: A = new A(); - assertTrue(a10.getInner().i == 2); // #22840 assertEQ incorrect check types of operands + arktest.assertTrue(a10.getInner().i == 2); // #22840 arktest.assertEQ incorrect check types of operands let instance_A: A = new A(2, 3); let instanc_A: A = new A(2); @@ -155,7 +155,7 @@ function main(): void { instance1.getValue(); let b: A = new A(); - assertTrue(b.getInner().foo() == 1); // #22840 assertEQ incorrect check types of operands + arktest.assertTrue(b.getInner().foo() == 1); // #22840 arktest.assertEQ incorrect check types of operands min(1.0, 1.0) let let = 0; @@ -169,124 +169,127 @@ function main(): void { /* @@? 18:14 Error SyntaxError: Optional variable is not allowed in for of statements. */ /* @@? 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. */ +/* @@? 37:33 Error SyntaxError: Unexpected token 'rethrows'. */ +/* @@? 37:33 Error TypeError: Unresolved reference rethrows */ /* @@? 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:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 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: 'this' cannot be referenced from a static context */ +/* @@? 45:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 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 ':'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:61 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 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 either array or tuple type. */ -/* @@? 59:23 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 55:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 59:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 63:22 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 */ +/* @@? 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: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 92:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 93:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 103:25 Error SyntaxError: Rest parameter should be either array or tuple type. */ -/* @@? 104:32 Error SyntaxError: Rest parameter should be either array or tuple 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. */ +/* @@? 103:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 104:21 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 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:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 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:1 Error TypeError: Function foo with this assembly signature already declared. */ /* @@? 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: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 SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 123:6 Error TypeError: Unresolved reference abc */ +/* @@? 125:1 Error TypeError: Method declaration `foo` must all ambient or non-ambient */ /* @@? 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:18 Error SyntaxError: Unexpected token '0'. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 141:16 Error TypeError: This expression is not callable. */ +/* @@? 137:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 141:24 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. */ +/* @@? 146:28 Error TypeError: Property 'getInner' does not exist on type 'A' */ /* @@? 148:25 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 149:24 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 151:20 Error TypeError: Cannot find type 'D0'. */ /* @@? 151:29 Error TypeError: Cannot find type 'D0'. */ /* @@? 157:16 Error TypeError: A is abstract therefore cannot be instantiated. */ -/* @@? 158:16 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 158:26 Error TypeError: Property 'getInner' does not exist on type 'A' */ +/* @@? 161:9 Error SyntaxError: Hard keyword 'let' cannot be used as identifier */ /* @@? 161:9 Error SyntaxError: Identifier expected, got 'let'. */ /* @@? 162:9 Error SyntaxError: Identifier expected, got 'const'. */ +/* @@? 162:9 Error SyntaxError: Hard keyword 'const' cannot be used as identifier */ /* @@? 163:9 Error SyntaxError: Identifier expected, got 'new'. */ +/* @@? 163:9 Error SyntaxError: Hard keyword 'new' cannot be used as identifier */ /* @@? 164:5 Error TypeError: This expression is not callable. */ /* @@? 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 */ -/* @@? 293:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 296: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..54308f81cd7fe710064c2adf0f80c7f1c401ea89 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets @@ -113,7 +113,7 @@ export class StringFasta { ret += fastaRandom(3 * count * 1000, IUB); ret += fastaRandom(5 * count * 1000, HomoSap); - assertEQ(ret, this.expected, "Incorrect result"); + arktest.assertEQ(ret, this.expected, "Incorrect result"); } } @@ -122,34 +122,30 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 24:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 25:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 26:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 27:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 28:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 29:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 30:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 31:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 32:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 33:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 34:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 35:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 36:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 21:9 Error TypeError: Unresolved reference IUB */ +/* @@? 22:9 Error TypeError: Unresolved reference IUB */ +/* @@? 23:9 Error TypeError: Unresolved reference IUB */ +/* @@? 24:9 Error TypeError: Unresolved reference IUB */ +/* @@? 25:9 Error TypeError: Unresolved reference IUB */ +/* @@? 26:9 Error TypeError: Unresolved reference IUB */ +/* @@? 27:9 Error TypeError: Unresolved reference IUB */ +/* @@? 28:9 Error TypeError: Unresolved reference IUB */ +/* @@? 29:9 Error TypeError: Unresolved reference IUB */ +/* @@? 30:9 Error TypeError: Unresolved reference IUB */ +/* @@? 31:9 Error TypeError: Unresolved reference IUB */ +/* @@? 32:9 Error TypeError: Unresolved reference IUB */ +/* @@? 33:9 Error TypeError: Unresolved reference IUB */ +/* @@? 34:9 Error TypeError: Unresolved reference IUB */ +/* @@? 35:9 Error TypeError: Unresolved reference IUB */ +/* @@? 36:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 37:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 38:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 39:9 Error TypeError: Unresolved reference HomoSap */ +/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,26 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Int' has no call signatures. */ /* @@? 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' */ +/* @@? 112:32 Error TypeError: Property 'count' must be accessed through 'this' */ /* @@? 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' */ +/* @@? 113:32 Error TypeError: Property 'count' must be accessed through 'this' */ +/* @@? 113:46 Error TypeError: Unresolved reference IUB */ /* @@? 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' */ +/* @@? 114:32 Error TypeError: Property 'count' must be accessed through 'this' */ +/* @@? 114:46 Error TypeError: Unresolved reference HomoSap */ +/* @@? 116:36 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 39c8b1c969a52b4b3a09a5482f9d9fca8da7ea95..e2021d154bfe14f8fe495ff5c3ec5f61ffc42718 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets @@ -28,4 +28,3 @@ class array_type { /* @@@ 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. */ - diff --git a/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets b/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets index e50e7e009395b1ad9816c3aeb1a38b4d4f9cf1e6..44f291da40da477a7b0108f54aa3a5b88ac41c43 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets @@ -24,3 +24,5 @@ function main(): void { } /* @@@ label Error TypeError: Enum name 'Color' used in the wrong context */ +/* @@? 21:22 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ +/* @@? 22:13 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'Color' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets index da4c91a29a93ee93e6ed17dcc36f090fefb9ecfd..c5987fed62c60c698810c9d5e0f901e341ac7b91 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets @@ -25,5 +25,6 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file + +/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 26:12 Error Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator1.ets b/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator1.ets index 7f20c01b849608c35c605d24ff231b44df479213..1261d3366d8d4e674a9f1501da90c146b3363af3 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator1.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator1.ets @@ -46,7 +46,7 @@ function main(): void { let res = ""; let a = new A(); for (let x of a) res += x; - assertEQ(res, "abc"); + arktest.assertEQ(res, "abc"); } /* @@? 48:19 Error TypeError: Iterator method must return an object which implements Iterator */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator2.ets b/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator2.ets index 143ae02d612c407ef403db72a145cb4a11d38534..2c650b8cc120f30adbdfc5bf2e5b36135e8bbb5d 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator2.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/forOfCustomIterator2.ets @@ -44,7 +44,7 @@ function main(): void { let res = ""; let a = new A(); for (let x of a) res += x; - assertEQ(res, "abc"); + arktest.assertEQ(res, "abc"); } /* @@? 46:19 Error TypeError: Iterator method must return an object which implements Iterator */ 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..8e6155210fa7272fb23c82e699bd9168ac942d4f 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets @@ -15,11 +15,11 @@ let a: FixedArray = [1, 2, 3]; -function forins(): int { - for (let i: int of "abcdef") { +function forins(): string { + for (let i: string of "abcdef") { return i; } - return c'*'; + return '*'; } function main(): void { @@ -32,4 +32,4 @@ function main(): void { } } -/* @@@ label Error TypeError: Source element type 'double' is not assignable to the loop iterator type 'float'. */ +/* @@@ label Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Float'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/functionTypeParam_neg2.ets b/ets2panda/test/ast/parser/ets/FixedArray/functionTypeParam_neg2.ets index 6651396d4b4f70b98d33b6f13bddcc063ecc15c2..3c8a14a8176d96137d9ed63cfa37fdb31bdff8a6 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/functionTypeParam_neg2.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/functionTypeParam_neg2.ets @@ -23,13 +23,19 @@ declare class Environment { static foo7(props1: {key:string, value:int}[], props2: FixedArray): void; } -/* @@? 17:23 Error SyntaxError: Invalid Type. */ -/* @@? 18:25 Error SyntaxError: Invalid Type. */ +/* @@? 17:23 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 18:25 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ /* @@? 19:25 Error SyntaxError: Invalid Type. */ +/* @@? 21:16 Error TypeError: Native and Declare methods should have explicit return type. */ /* @@? 21:20 Error SyntaxError: Invalid Type. */ /* @@? 21:28 Error SyntaxError: Invalid Type. */ /* @@? 21:37 Error SyntaxError: Unexpected token, expected '=>'. */ -/* @@? 21:37 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 21:37 Error SyntaxError: Invalid Type. */ +/* @@? 21:39 Error SyntaxError: Unexpected token '--'. */ +/* @@? 21:41 Error SyntaxError: Unexpected token '-'. */ +/* @@? 21:42 Error SyntaxError: Unexpected token ','. */ +/* @@? 21:43 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:44 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:45 Error SyntaxError: void is a predefined type, cannot be used as an identifier */ /* @@? 22:20 Error SyntaxError: Invalid Type. */ -/* @@? 23:25 Error SyntaxError: Invalid Type. */ \ No newline at end of file +/* @@? 23:25 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 23:36 Error SyntaxError: Unexpected token ','. */ 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 ce9fff73c6e52403a5b8c24b84227f069cc59e31..a49879c670f44037f457897496ce555d512c3d98 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,7 +19,7 @@ function main(): void { s.toString() let a: int [] = [1, 2] let b = s ?? a; - /* @@ label */b.toString(); + b.toString(); } -/* @@? 22:19 Error TypeError: Type String|int[] is illegal in union member expression. */ +/* @@? 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 9ad1e60b924c2b2fff1506bb5af87cfe6942e87e..5e4dcd90af1268a7da5c3d5f0265b4db417bfdfb 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets @@ -43,71 +43,43 @@ 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: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: 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 SyntaxError: Unexpected token 'int'. */ -/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 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:22 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 ']'. */ 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..3bf1015d7a8c86fcd55daca16a8fb31d0f4cc634 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/nonIntegralIndex.ets b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets index 6d3751d902f8eab281f4399c873927bc48d1709d..7f0a390e842243a0ddf2dee23729b7c65a284c2d 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets @@ -19,4 +19,4 @@ export class Test { } } -/* @@@ label Error TypeError: Type 'double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ +/* @@@ 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/FixedArray/predefined_non_primitive_types.ets b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets index b4ef18b4e99a3a2269bd9473f6728fa42eedfeac..e096d5945f662dcffe7e5732a142e313c2f2c66a 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets @@ -36,5 +36,6 @@ let s: String = "abc"; let a: FixedArray = new int[5]; /* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ +/* @@? 23:25 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ /* @@? 27:31 Error TypeError: Cannot find type 'Bool'. */ -/* @@? 27:38 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ +/* @@? 27:38 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ 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..76821f2070cf19e0b4617b8ae47be6ce5d0c93ea 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..516d11b4d23167c75db764dd596470bc71b98d7e 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/record_object_value.ets b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets index 90442a1300b850ec2513c1751658e4279d8c68a4..d989ef82179c3964bb21c98cfb5350849a6d38f8 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets @@ -48,8 +48,8 @@ function main(){ }; let errormap2:Record = { - "john":{/* @@ label2 */agee:10, salary:10}, - "Mary":{age:21, salary:10, /* @@ label3 */other:10} + "john":/* @@ label2 */{/* @@ label3 */agee:10, salary:10}, + "Mary":{age:21, salary:10, /* @@ label4 */other:10} }; let stringarraymap:Record> = { @@ -57,7 +57,9 @@ function main(){ "Mary":["20", "30"] }; } -/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'double' at property 'age' */ -/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'double' at property 'salary' */ -/* @@@ label2 Error TypeError: type PersonInfoInterface has no property named agee */ -/* @@@ label3 Error TypeError: type PersonInfoInterface has no property named other */ +/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'Double' at property 'age' */ +/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'Double' at property 'salary' */ +/* @@@ label2 Error TypeError: Non-optional property 'salary' in type 'PersonInfoInterface' is missing in object literal. */ +/* @@@ label2 Error TypeError: Non-optional property 'age' in type 'PersonInfoInterface' is missing in object literal. */ +/* @@@ label3 Error TypeError: type PersonInfoInterface has no property named agee */ +/* @@@ label4 Error TypeError: type PersonInfoInterface has no property named other */ \ No newline at end of file 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 a408eaf019b4a4b7be1eb52bcfbc18e07e941bd6..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 SyntaxError: Unexpected token 'void'. */ +/* @@@ 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/spreadexpr_in_newexpr_neg01.ets b/ets2panda/test/ast/parser/ets/FixedArray/spreadexpr_in_newexpr_neg01.ets index ff2284a2983df75e6b7338f194c91987d71a4485..7eef9e9c85e61c440dcd6661ba7e7a5e12fc73a2 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/spreadexpr_in_newexpr_neg01.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/spreadexpr_in_newexpr_neg01.ets @@ -33,6 +33,5 @@ function main() { /* @@? 19:9 Error SyntaxError: Unexpected token 'this'. */ /* @@? 19:13 Error SyntaxError: Unexpected token '.'. */ /* @@? 19:14 Error TypeError: Variable 'fld' has already been declared. */ -/* @@? 19:14 Error TypeError: Property 'fld' must be accessed through 'this' */ /* @@? 19:20 Error TypeError: Unresolved reference p */ /* @@? 21:1 Error SyntaxError: Unexpected token '}'. */ 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/this_as_array_element.ets b/ets2panda/test/ast/parser/ets/FixedArray/this_as_array_element.ets index 16d7df9fbf204f48fbaf080a72e9e77d9933e375..6f81fc075f84dc7ddf830ab6a973986d205e4afa 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/this_as_array_element.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/this_as_array_element.ets @@ -14,5 +14,8 @@ */ class Link { - a: FixedArray = [this]; + a: FixedArray; + constructor() { + this.a = [this]; + } } 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..a0436293f73260cd5f0d6aff01eb0c9edead3b46 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,13 @@ 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: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 bb6c655e2b323ee2d5d5015c4712528689e920a3..37de6fe998ab731177911580d49d617a788b01c8 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets @@ -18,15 +18,14 @@ function foo(...^number: FixedArray): int { } /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 16:17 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 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 SyntaxError: Unexpected token '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 */ /* @@? 17:12 Error TypeError: Indexed access is not supported for such expression type. */ 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 fa85f223688b82814631dc7e055b3328edda1c66..556218db5c599a6582a3ba6226c8036a8e0391f1 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets @@ -36,15 +36,7 @@ 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 SyntaxError: Expected ')', got 'int'. */ /* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 29:20 Error SyntaxError: Unexpected token '='. */ -/* @@? 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..311e9b269334ace1bfb51c801d559aebe42d6ec4 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets @@ -23,13 +23,10 @@ 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 '('. */ -/* @@? 22:61 Error SyntaxError: Invalid Type. */ -/* @@? 22:61 Error SyntaxError: Unexpected token '('. */ +/* @@? 22:61 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 22:63 Error SyntaxError: Unexpected token 'FixedArray'. */ /* @@? 22:63 Error TypeError: Unresolved reference FixedArray */ /* @@? 22:82 Error SyntaxError: Unexpected token, expected '('. */ /* @@? 22:116 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 22:116 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..9e88ba3b09ecd686b4a1aebfda7d32b4d45cdcf8 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 'Array' 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..e6bb326eef0026db69e30812e6dfc2bc3cd6e1db 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..d31642e769b87be22eb93ac64b491232cfce12f0 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: Type 'Array<() => Int>' cannot be assigned to type '() => 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..131be93eeacd12423fbbf6d79e008737523c0b43 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.ets +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.ets @@ -85,25 +85,26 @@ interface I1 { /* @@? 18:30 Error TypeError: Native, Abstract and Declare methods cannot have body. */ /* @@? 19:21 Error TypeError: Static property 'f' must be accessed through it's class 'A' */ /* @@? 22:12 Error SyntaxError: Access modifier must precede field and method modifiers. */ -/* @@? 22:20 Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ +/* @@? 22:36 Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ /* @@? 22:46 Error TypeError: Native, Abstract and Declare methods cannot have body. */ /* @@? 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. */ +/* @@? 27:20 Error TypeError: Non abstract class has abstract method. */ +/* @@? 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. */ +/* @@? 41:11 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ +/* @@? 41:11 Error SyntaxError: The special predefined method '$_get' cannot be asynchronous. */ /* @@? 41:16 Error TypeError: Return type of async function must be 'Promise'. */ -/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameter. */ -/* @@? 45:5 Error SyntaxError: The special predefined method '$_set' cannot be asynchronous. */ +/* @@? 45:11 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameter. */ +/* @@? 45:11 Error SyntaxError: The special predefined method '$_set' cannot be asynchronous. */ /* @@? 45:16 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' cannot be asynchronous. */ -/* @@? 47:5 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ +/* @@? 47:11 Error SyntaxError: The special predefined method '$_iterator' cannot be asynchronous. */ +/* @@? 47:11 Error SyntaxError: The special predefined method '$_iterator' should not have parameters. */ /* @@? 47:21 Error TypeError: The return type of '$_iterator' must be a type that implements Iterator interface. */ /* @@? 47:21 Error TypeError: Return type of async function must be 'Promise'. */ /* @@? 54:21 Error TypeError: Initializers are not allowed in ambient contexts: x */ /* @@? 54:23 Error SyntaxError: Initializers are not allowed in ambient contexts. */ +/* @@? 58:1 Error TypeError: Unresolved reference declare */ /* @@? 58:9 Error SyntaxError: Unexpected token 'native'. */ /* @@? 58:16 Error SyntaxError: 'native' flags must be used for functions only at top-level. */ /* @@? 58:22 Error TypeError: Native and Declare methods should have explicit return type. */ @@ -112,12 +113,14 @@ interface I1 { /* @@? 58:25 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 58:25 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 58:25 Error SyntaxError: Unexpected token '}'. */ +/* @@? 61:5 Error SyntaxError: Illegal start of CLASS expression. */ /* @@? 62:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@? 65:5 Error SyntaxError: Illegal start of INTERFACE expression. */ /* @@? 66:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ /* @@? 66:18 Error SyntaxError: Private interface methods must have body. */ /* @@? 67:9 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ -/* @@? 67:16 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 67:16 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 67:16 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 67:16 Error SyntaxError: Identifier expected. */ /* @@? 67:24 Error SyntaxError: Private interface methods must have body. */ /* @@? 72:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ @@ -128,4 +131,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 521660666b2fe92500891371b034004bb0e32719..12d43efaec8076c8234019e630853a390a535443 100644 --- a/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets @@ -36,68 +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 SyntaxError: Unexpected token 'void'. */ -/* @@? 24:27 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 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: 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: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 f1a1bac9355051e04eba42620f38d97b2d736581..899de53972fe0f73745efbef8c0b7f314b523183 100644 --- a/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets +++ b/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets @@ -25,5 +25,4 @@ class int {} /* @@? 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'. */ +/* @@? 23:7 Error SyntaxError: int is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets index d1736c1bb8bf7762f8911d53f8fb364e8e70cbb3..07c11ed802bb88da3e3f60fc25813ed724ceb06f 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets @@ -34,7 +34,7 @@ function f() { try let x: number = 89 -} catch(a: Exception) { +} catch(a) { } try x: number; @@ -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'. */ @@ -69,7 +65,7 @@ throw /* @@? 42:1 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ /* @@? 43:5 Error SyntaxError: Expected '{', got 'let'. */ /* @@? 45:9 Error SyntaxError: Unexpected token '{'. */ +/* @@? 47:1 Error SyntaxError: Illegal start of CLASS expression. */ /* @@? 48:5 Error SyntaxError: Unexpected token 'let'. */ /* @@? 52:1 Error SyntaxError: Illegal newline after throw. */ -/* @@? 76:1 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 76:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 72: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..be3ba4c48a4f7d2d01a78924169a03429709d4d8 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements3.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements3.ets @@ -15,7 +15,7 @@ try { let x = 77 -} catch(a: exception) +} catch(a) } try @@ -41,22 +41,22 @@ function foo() { 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: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: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'. */ +/* @@? 42:16 Error SyntaxError: 'in' operator is not supported. Use 'instanceof' operator to check whether an object is the instance of a class that contains the necessary class member. */ +/* @@? 42:28 Error SyntaxError: Expected ';', got ')'. */ +/* @@? 42:28 Error SyntaxError: Invalid left-hand side in 'For[In/Of]Statement'. */ 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..335d3e99b434b70dbed0aff375a541e248a81102 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,6 @@ function main(){ Test escape characters` | "X"; } -/* @@? 17:15 Error SyntaxError: Invalid character escape sequence. */ +/* @@? 17:5 Error SyntaxError: Illegal start of Type Alias expression. */ /* @@? 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..2eca08c7dc33c5f4079a4225bb99c53eb59c3b70 100644 --- a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets @@ -32,8 +32,9 @@ class /* @@ label4 */{/* @@ label5 */} /* @@? 17:19 Error SyntaxError: Unexpected token 'function'. */ /* @@? 21:20 Error SyntaxError: Unexpected token 'let'. */ /* @@? 22:20 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'double' */ +/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'Double' */ +/* @@? 28:22 Error SyntaxError: Number, string or computed value property name '77' is not allowed, use classes to access data by property names that are identifiers */ /* @@? 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'. */ +/* @@? 41:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleFunctionErrors.ets b/ets2panda/test/ast/parser/ets/MultipleFunctionErrors.ets index 85f7f8a87135c0e294950d3ebbe3a70f80ae0539..5db33dcca04e3611534c95b28b872d732fbd7ca9 100644 --- a/ets2panda/test/ast/parser/ets/MultipleFunctionErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleFunctionErrors.ets @@ -17,9 +17,11 @@ function /* @@ label */(): void { } function /* @@ label1 */(): /* @@ label2 */{ - return 77; + /* @@ label3 */return /* @@ label4 */77; } /* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@@ label2 Error SyntaxError: Invalid Type. */ +/* @@@ label2 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@@ label3 Error SyntaxError: Unexpected token 'return'. */ +/* @@@ label4 Error SyntaxError: Unexpected token '77'. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets index 758b001e43f51cd7b526f4767f442c1f877d4121..f5ca1c97b2936862f7841f75784a26ef28dd11b3 100644 --- a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets @@ -104,7 +104,7 @@ function foo(... a: byte): void {} native function foo(... b: byte): long; function min(v: double, u: double): double { - assertTrue(false) + arktest.assertTrue(false) return v < u ? v : u; } @@ -138,12 +138,12 @@ function main(): void { //Do something. } - assertTrue(foo(), undefined); + arktest.assertTrue(foo(), undefined); f(0); let a10: A = new A(); - assertTrue(a10.getInner().i == 2); // #22840 assertEQ incorrect check types of operands + arktest.assertTrue(a10.getInner().i == 2); // #22840 arktest.assertEQ incorrect check types of operands let instance_A: A = new A(2, 3); let instanc_A: A = new A(2); @@ -155,7 +155,7 @@ function main(): void { instance1.getValue(); let b: A = new A(); - assertTrue(b.getInner().foo() == 1); // #22840 assertEQ incorrect check types of operands + arktest.assertTrue(b.getInner().foo() == 1); // #22840 arktest.assertEQ incorrect check types of operands min(1.0, 1.0) let let = 0; @@ -169,118 +169,123 @@ function main(): void { /* @@? 18:14 Error SyntaxError: Optional variable is not allowed in for of statements. */ /* @@? 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. */ +/* @@? 37:33 Error SyntaxError: Unexpected token 'rethrows'. */ +/* @@? 37:33 Error TypeError: Unresolved reference rethrows */ /* @@? 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:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 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: Identifier expected, got 'null'. */ -/* @@? 43:6 Error SyntaxError: Type alias name cannot be '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: 'this' cannot be referenced from a static context */ +/* @@? 45:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 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: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 either array or tuple type. */ -/* @@? 59:23 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 55:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 59:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 63:22 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 */ +/* @@? 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 either array or tuple type. */ -/* @@? 104:32 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 103:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 104:21 Error SyntaxError: Rest parameter should be either array or tuple 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. */ /* @@? 116:12 Error TypeError: All return statements in the function should be empty or have a value. */ +/* @@? 119:1 Error TypeError: Function foo with this assembly signature already declared. */ +/* @@? 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 '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:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ +/* @@? 119:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 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 TypeError: Unresolved reference abc */ +/* @@? 125:1 Error TypeError: Method declaration `foo` must all ambient or non-ambient */ /* @@? 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: Expected ')', got '='. */ +/* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ +/* @@? 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 ')'. */ -/* @@? 141:16 Error TypeError: This expression is not callable. */ +/* @@? 137:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 141:24 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. */ +/* @@? 146:28 Error TypeError: Property 'getInner' does not exist on type 'A' */ /* @@? 148:25 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 149:24 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 151:20 Error TypeError: Cannot find type 'D0'. */ /* @@? 151:29 Error TypeError: Cannot find type 'D0'. */ /* @@? 157:16 Error TypeError: A is abstract therefore cannot be instantiated. */ -/* @@? 158:16 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 158:26 Error TypeError: Property 'getInner' does not exist on type 'A' */ /* @@? 161:9 Error SyntaxError: Identifier expected, got 'let'. */ +/* @@? 161:9 Error SyntaxError: Hard keyword 'let' cannot be used as identifier */ /* @@? 162:9 Error SyntaxError: Identifier expected, got 'const'. */ +/* @@? 162:9 Error SyntaxError: Hard keyword 'const' cannot be used as identifier */ /* @@? 163:9 Error SyntaxError: Identifier expected, got 'new'. */ +/* @@? 163:9 Error SyntaxError: Hard keyword 'new' cannot be used as identifier */ /* @@? 164:5 Error TypeError: This expression is not callable. */ /* @@? 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 */ -/* @@? 287:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ +/* @@? 292: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..47e9de0529e51f3eea5905699b433d282c3d8cbd 100644 --- a/ets2panda/test/ast/parser/ets/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/StringFasta.ets @@ -113,7 +113,7 @@ export class StringFasta { ret += fastaRandom(3 * count * 1000, IUB); ret += fastaRandom(5 * count * 1000, HomoSap); - assertEQ(ret, this.expected, "Incorrect result"); + arktest.assertEQ(ret, this.expected, "Incorrect result"); } } @@ -122,34 +122,30 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 24:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 25:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 26:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 27:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 28:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 29:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 30:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 31:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 32:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 33:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 34:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 35:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ -/* @@? 36:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ -/* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 21:9 Error TypeError: Unresolved reference IUB */ +/* @@? 22:9 Error TypeError: Unresolved reference IUB */ +/* @@? 23:9 Error TypeError: Unresolved reference IUB */ +/* @@? 24:9 Error TypeError: Unresolved reference IUB */ +/* @@? 25:9 Error TypeError: Unresolved reference IUB */ +/* @@? 26:9 Error TypeError: Unresolved reference IUB */ +/* @@? 27:9 Error TypeError: Unresolved reference IUB */ +/* @@? 28:9 Error TypeError: Unresolved reference IUB */ +/* @@? 29:9 Error TypeError: Unresolved reference IUB */ +/* @@? 30:9 Error TypeError: Unresolved reference IUB */ +/* @@? 31:9 Error TypeError: Unresolved reference IUB */ +/* @@? 32:9 Error TypeError: Unresolved reference IUB */ +/* @@? 33:9 Error TypeError: Unresolved reference IUB */ +/* @@? 34:9 Error TypeError: Unresolved reference IUB */ +/* @@? 35:9 Error TypeError: Unresolved reference IUB */ +/* @@? 36:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 37:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 38:9 Error TypeError: Unresolved reference HomoSap */ +/* @@? 39:9 Error TypeError: Unresolved reference HomoSap */ +/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,26 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Int' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Int' has no call signatures. */ /* @@? 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' */ +/* @@? 112:32 Error TypeError: Property 'count' must be accessed through 'this' */ /* @@? 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' */ +/* @@? 113:32 Error TypeError: Property 'count' must be accessed through 'this' */ +/* @@? 113:46 Error TypeError: Unresolved reference IUB */ /* @@? 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' */ +/* @@? 114:32 Error TypeError: Property 'count' must be accessed through 'this' */ +/* @@? 114:46 Error TypeError: Unresolved reference HomoSap */ +/* @@? 116:36 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/accessor_call.ets b/ets2panda/test/ast/parser/ets/accessor_call.ets index 030d431499f21d0d9fab274a0961f16d1309bc18..918aaffe3935735b4bb87a0232011df893697547 100644 --- a/ets2panda/test/ast/parser/ets/accessor_call.ets +++ b/ets2panda/test/ast/parser/ets/accessor_call.ets @@ -21,4 +21,4 @@ function main(): void { /* @@ label */new A().x(); } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets b/ets2panda/test/ast/parser/ets/ambient_class_missing_body.ets similarity index 86% rename from ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets rename to ets2panda/test/ast/parser/ets/ambient_class_missing_body.ets index 4d96d8de990f08633df87a01c1b9fcc6dfd9fa67..1428f6e5baa5676ce2ee84722bc810a2c6463a62 100644 --- a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets +++ b/ets2panda/test/ast/parser/ets/ambient_class_missing_body.ets @@ -13,9 +13,7 @@ * limitations under the License. */ -function main(): void { - let c:char = c'X'; - let s:string = c; +declare class B - assertEQ(s, "X") -} \ No newline at end of file + +/* @@? 20:1 Error SyntaxError: Ambient class declarations must have a body. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_declaration.ets b/ets2panda/test/ast/parser/ets/ambient_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee8515f1165a059d526145237fd3c025eb1347b2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/ambient_declaration.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 /* @@ label1 */module /* @@ label2 */"someModule" /* @@ label3 */{} + +/* @@@ label1 Error SyntaxError: Ambient module declaration is not supported! */ +/* @@@ label1 Error TypeError: Unresolved reference module */ +/* @@@ label2 Error SyntaxError: Unexpected token 'someModule'. */ +/* @@@ label3 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_10.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_10.ets new file mode 100644 index 0000000000000000000000000000000000000000..6089b2b4463dd14697fea0260bc15d1c68a1f96f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_10.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. + */ + +declare class ClassWithSymbols { + public readonly [x: number]: string; + public /* @@ label1 */[x: number]: () => void; +} + + +/* @@@ label1 Error SyntaxError: Only one index signature can exist in a class */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_11.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_11.ets new file mode 100644 index 0000000000000000000000000000000000000000..b12c0c7f6655b79cfdcacd55f39ef44b55e57745 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_11.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. + */ + +declare interface I{ + [index:number]:long; +} + +declare class C{ + [index:number]:long; +} diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets index 7b5c41ba881ae1ae8068e8473f0fd3e9d8cc432a..d1c5273f0c247d8fe5770b7b5d1c50c9ca0d7117 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets @@ -21,10 +21,4 @@ function main() { let a : A = new A(); } -/* @@? 17:6 Error SyntaxError: Unexpected token 'index'. */ -/* @@? 17:12 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:14 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ -/* @@? 17:20 Error SyntaxError: Field type annotation expected. */ -/* @@? 17:20 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 18:1 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:6 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets index c4f60ba8db373a47fe65087577a1826b8f7b66b1..4f06b3693e3fbd2a9b19aac40a6f7a13b882b374 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets @@ -14,11 +14,19 @@ */ declare class A { - [index : /* @@ label */string] : string + [index : string] : string } function main() { let a : A = new A(); } -/* @@@ label Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: ] expected in index signature. */ +/* @@? 17:20 Error SyntaxError: An index signature must have a type annotation. */ +/* @@? 17:20 Error SyntaxError: Expected ':', got ']'. */ +/* @@? 17:20 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:24 Error SyntaxError: string is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets index 26857e6ececae6f412f4f848b8d32cb34f066ef0..33e4fff0d11dc57e84ca295c89f2d1d1d37bbc0e 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets @@ -22,7 +22,6 @@ 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 */ \ No newline at end of file +/* @@@ label Error SyntaxError: Expected ':', got '}'. */ +/* @@@ label Error SyntaxError: Invalid Type. */ +/* @@@ label Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_5.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_5.ets index 0319741534bdaff23b2d7436e57906189b3b7cae..7ea0d48dd447a6d9c576e9427a2d7b8cfbdc799d 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_5.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_5.ets @@ -21,4 +21,6 @@ function main() { let a : A = new A(); } +/* @@@ label Error SyntaxError: Invalid Type. */ /* @@@ label Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@@ label Error SyntaxError: Unexpected token '?'. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets index aace691a4e8c3ca1de775117e00346db0c7c2caa..c9e6ef112ef706cb157758f8bb5c491a2c321b09 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets @@ -15,16 +15,12 @@ declare class A { [index : number /* @@ label */: /* @@ label1 */string -/* @@ label2 */} +} -/* @@ label3 */function main/* @@ label5 */() { +function main() { let a : A = new A(); } /* @@@ label Error SyntaxError: ] expected in index signature. */ /* @@@ label1 Error SyntaxError: An index signature must have a type annotation. */ -/* @@@ 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 */ \ No newline at end of file +/* @@@ label1 Error SyntaxError: Expected ':', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets index 3f3942b7968f4e420d38be3ace67071626c117cd..62e5623e90ffa388b98664a0f462b1a359771abe 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets @@ -15,17 +15,14 @@ declare class A { [index/* @@ label */] /* @@ label1 */: /* @@ label2 */string -/* @@ label3 */} +} -/* @@ label4 */function main/* @@ label6 */() { +function main() { let a : A = new A(); } -/* @@@ label Error SyntaxError: Index type expected in index signature. */ -/* @@@ label1 Error SyntaxError: Index type must be number in index signature. */ -/* @@@ label2 Error SyntaxError: ] expected in index signature. */ -/* @@@ 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 */ \ No newline at end of file +/* @@@ label Error SyntaxError: Index type expected in index signature. */ +/* @@@ label1 Error SyntaxError: Index type must be number in index signature. */ +/* @@@ label1 Error SyntaxError: ] expected in index signature. */ +/* @@@ label2 Error SyntaxError: An index signature must have a type annotation. */ +/* @@@ label2 Error SyntaxError: Expected ':', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets index 27a91515bca38ba9aa439145bd36c8027d9e66a5..4d3d2c85391c59df3df421d2ec171879cb82d670 100644 --- a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets +++ b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets @@ -27,5 +27,5 @@ function main (): void { goo (0, new X(), "ambiguous") } -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I5, s: String): void` */ -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I2, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I5, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I2, s: String): void` */ diff --git a/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets b/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3fefe0e9d7faba4363d6e128cd0cede10d40f6b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const enum E { + A = 10, + B = 20, + C = 30 +} + +const enum E1 { + A = "A", + B = "B" +} + +@interface Anno { + a: number + b = [(10 + 3), E.A] + c: string + d: boolean + e: E[] = [E.A, E.B, E.C] + f: number[] + g: number[][][] + h: E + i: E[][][] + j: E1 + k: E1[][][] +} + + +@Anno({a: E.A + 10, c: "a" + "b", d: (1 === 1), f: [], g: [[[0]]], h: E.A, i: [], j: E1.B, k: []}) +class C{ + @Anno({a: 10, b: [1, 2, 3], c: "cde", d: true, f: [1], g:[[[0], [1]]], h: E.A, i: [[[E.A], [E.B]]], j: E1.B, k: [[[E1.A], [E1.B]]]}) + public foo() {} +} + +/* @@? 29:4 Error SyntaxError: Missing type annotation for property 'b'. */ +/* @@? 42:11 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 44:16 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.ets index c91e54e8e1546c2aa440ca29bec14288070dc0b2..1c44ded6935e22953442f74a0911854b7eed7949 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.ets @@ -20,6 +20,6 @@ class A{} } -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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/annotationDecl_bad_initializer03.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer03.ets index 956e26b9c611beb309229a95dd0cc94a7eab0783..6d9b6522bd51b0dff2714bdf880f314c3a696073 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer03.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer03.ets @@ -14,8 +14,8 @@ */ @interface MyAnno { - testProperty1: string = /* @@ label */[1,2,a] + testProperty1: string = [1,2,/* @@ label */a] } -/* @@@ label Error TypeError: Expected type for array literal should be an array type, got String */ +/* @@@ label Error TypeError: Unresolved reference a */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer06.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer06.ets index be2cfb7042f696fe921d00acfbcb17dd4c2e5d9e..8ede82f797615d800106dd7336fa08ef929f63d7 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer06.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_bad_initializer06.ets @@ -20,4 +20,3 @@ class A{} } /* @@@ label Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 19:43 Error TypeError: Type '(a: Int) => void' cannot be assigned to type 'String' */ 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 999e7e695385f45efcb9cee17d3a24067e4ad48c..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 @@ -20,7 +20,6 @@ /* @@? 18:18 Error SyntaxError: Identifier expected, got ':'. */ /* @@? 18:20 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ -/* @@? 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 7f8809336f6092f7d601522f2f277cb8022f0bc8..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 @@ -19,7 +19,6 @@ /* @@@ label1 Error SyntaxError: Identifier expected, got ':'. */ /* @@? 17:35 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ -/* @@? 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_parser_bad_token04.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token04.ets index 88cfdb4017c6ae03aa5e3c0e1528447d239f0ba0..21d016f414d88fec5654f578d80e1fa95fb1f85f 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token04.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token04.ets @@ -19,7 +19,4 @@ import * as Src from "./annotation_export" Src.MyAnno class /* @@ label */A/* @@ label1 */{} -/* @@? 19:1 Error TypeError: Class literal is not yet supported. */ -/* @@? 20:21 Error SyntaxError: Unexpected token 'A'. */ -/* @@? 20:21 Error TypeError: Unresolved reference A */ -/* @@? 20:37 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:5 Error TypeError: Property 'MyAnno' does not exist on type 'annotation_export' */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token05.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token05.ets index dd02b7775a4ff91a997b54029cc34129564ce478..5648eba09f5026058368c85d7c067fbcc59f697c 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token05.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token05.ets @@ -16,7 +16,7 @@ import * as Src from "./annotation_export" -Src./* @@ label */MyAnno() +/* @@ label */Src.MyAnno() class A{} -/* @@@ label Error TypeError: Property 'MyAnno' does not exist on type 'annotation_export' */ +/* @@@ label Error TypeError: MyAnno is an annotation therefore cannot be instantiated. */ 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_access_modifier03.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.ets index c6d1285bf8ac75f6673ba770e7e0c0105e76c263..9128014805bfc66074dbdc7af9dc93730a329dc0 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.ets @@ -19,4 +19,3 @@ /* @@@ label Error SyntaxError: Unexpected token 'static'. */ /* @@@ label1 Error SyntaxError: Unexpected token '@'. */ -/* @@? 15:38 Error SyntaxError: Annotations can only be declared at the top level. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.ets index 79ef906623e292c7f02b97ce1b33d93ca70c8cf0..02ed066c23bdfeb9d4be5ee5db49ca8d92d3b83f 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.ets @@ -17,6 +17,7 @@ class A{} } +/* @@? 17:5 Error SyntaxError: Hard keyword 'class' cannot be used as identifier */ /* @@? 17:5 Error SyntaxError: Identifier expected, got 'class'. */ /* @@? 17:12 Error SyntaxError: Missing type annotation for property 'A'. */ /* @@? 17:12 Error SyntaxError: Identifier expected, got '{'. */ 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_param01.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.ets index 291e9fc476b02b5d03e0c415a0f5c32b63d79253..2fb3feaa785b30cd97c365acd222dcee03a80d01 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param01.ets @@ -23,6 +23,6 @@ class A{} class B{} -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param02.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param02.ets index cbe206da4501889fc11d8d1278ed8f2380eb2644..4b52a661a36ab459713ce26f6f16e2ae3702fa83 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param02.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param02.ets @@ -23,4 +23,5 @@ class A{} class B{} /* @@@ label Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ /* @@? 22:23 Error TypeError: Type 'A' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets index cd104710cf1c2bf5fb4186fb4da86ff654bd321a..578d3567c669a8cf51100074e9df5ec96711cc76 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets @@ -21,4 +21,5 @@ @MyAnno({testProperty1: "1", testProperty2: [1, 2, a]}) class B{} -/* @@? 21:45 Error TypeError: Expected type for array literal should be an array type, got double */ +/* @@? 21:45 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 21:52 Error TypeError: Unresolved reference a */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param05.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param05.ets index 5a155bd89adda2a8dec9d079ef43ed0d8cd6f23d..587d3a3031f78346ca9b74188601993a842f4154 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param05.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param05.ets @@ -22,4 +22,3 @@ class B{} /* @@@ label Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 21:40 Error TypeError: type String has no property named s */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param06.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param06.ets index 9c370a5eb2d331e5ae72efffa39eb46e0102c42b..785dbfea7efe31217615a5b7f4a637f2d4b70a0d 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param06.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param06.ets @@ -22,3 +22,4 @@ class B{} /* @@@ label Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ /* @@? 20:23 Error TypeError: Type '(a: Int) => void' cannot be assigned to type 'String' */ +/* @@? 20:23 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param07.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param07.ets index c1e3d6541e6f28dd8087f3ac33021f5feb526827..d5077544840f5baec9e408280c5c401c4a4c1374 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param07.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param07.ets @@ -19,7 +19,7 @@ } -function foo(@MyAnno ...a/* @@ label */){} - -/* @@@ label Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +function foo(@MyAnno ...a){} /* @@? 22:15 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ +/* @@? 22:22 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 22:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.ets index 6bda66d08940770a04e4aba7da07a38063a7dfc2..389af848c79f2620d8032f0262f11c897692c21a 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.ets @@ -28,9 +28,9 @@ class B{ } -/* @@@ label1 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label1 Error SyntaxError: Class cannot be used as object. */ /* @@@ label1 Error TypeError: Type 'A' cannot be assigned to type 'String' */ /* @@@ label1 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@@ label2 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label2 Error SyntaxError: Class cannot be used as object. */ /* @@@ label2 Error TypeError: Type 'A' cannot be assigned to type 'String' */ /* @@@ label2 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.ets index 4b9930aa0d222eb5214dcade67a4db552f1c4cfc..cf347df6c7611ddf4a4c5bcee21246e4c4e21a2f 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.ets @@ -23,6 +23,6 @@ class A{} function foo(@MyAnno({testProperty1: /* @@ label */A}) x: int) { } -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_global_variable_decl.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.ets index 42cc5b89bb8b5bda80e4639bcdcd232d948fed20..535b365f32749b2966664b57af09b1d91fa69913 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.ets @@ -24,6 +24,6 @@ class A{} let x = "abc" -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_interface.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.ets index b05a133e46f00d369cb474906c343f83d30a8e32..d544f882f733615ca8a40d5147dca8378cbd237b 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.ets @@ -25,6 +25,6 @@ interface itf { foo() : string } -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_interfacemethod.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.ets index 1dc2531c2f20d0531331bbd39a205d2dc142b6a7..ae609bf8f8e979ea73aa697849a7690cbb5ea1d7 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.ets @@ -25,6 +25,6 @@ interface itf { } -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_interfaceproperty.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets index 0262653495ab65b55d254a03d36c5943582a40a1..4ce655dabf0b46248667309f22d432a25226c175 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 @@ -25,9 +25,6 @@ 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 SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_local_variable_decl.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.ets index bcb548094fdb7a8e0199987cbb6fc293ef37d14f..9c65ff8922fa6cfa80a0326c5990a7912e1a0b45 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.ets @@ -26,6 +26,6 @@ function main():void { } -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ /* @@@ 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_bad_param_for_type_alias.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.ets index 20828eff75c8e3514fe48652e3652bc4cb590e23..d066379ae2a7cd455245297dce539fde638108b0 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.ets @@ -24,14 +24,13 @@ class A{} type t1 = int function main(): void { - @MyAnno({testProperty1: /* @@ label2 */A}) - type t2 = int + @MyAnno({testProperty1: A}) + /* @@ label2 */type t2 = int } -/* @@@ label1 Error TypeError: Class name 'A' used in the wrong context */ +/* @@@ label1 Error SyntaxError: Class cannot be used as object. */ /* @@@ label1 Error TypeError: Type 'A' cannot be assigned to type 'String' */ /* @@@ label1 Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@@ label2 Error TypeError: Class name 'A' used in the wrong context */ -/* @@@ label2 Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@@ label2 Error TypeError: Invalid value for annotation field, expected a constant literal. */ +/* @@@ label2 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label2 Error SyntaxError: Annotations are not allowed on this type of declaration. */ 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 6516d74eb9c355ee292ccf832a5787ad1bc7d40b..96304af4406e85870489c188070c4065893f4f47 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 @@ -26,52 +26,43 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: } /* @@? 19:10 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 19:14 Error TypeError: The type of parameter 'MyAnno' cannot be inferred */ /* @@? 19:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 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 SyntaxError: Unexpected token 'int'. */ /* @@? 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. */ /* @@? 22:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 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:45 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 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 ')'. */ +/* @@? 22:89 Error SyntaxError: Unexpected token '{'. */ /* @@? 25:1 Error TypeError: Function foo is already declared. */ -/* @@? 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: Unexpected token, expected ',' or ')'. */ /* @@? 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: Label must be followed by a loop statement. */ /* @@? 25:45 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 25:45 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 25:45 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 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 '{'. */ \ No newline at end of file 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/annotationUsage_tmp.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_tmp.ets index cbe206da4501889fc11d8d1278ed8f2380eb2644..7173d03c9b6bd42d7bd5f63767fa6e99bb266ed0 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_tmp.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_tmp.ets @@ -23,4 +23,5 @@ class A{} class B{} /* @@@ label Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ -/* @@? 22:23 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: Type 'A' cannot be assigned to type 'String' */ 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/parser/ets/local-class.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets similarity index 84% rename from ets2panda/test/parser/ets/local-class.ets rename to ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets index 94e03361a4137d274d079cf3232dc94c77aa1efd..6aa297c6185a40b8efca0fe980376453fc46353f 100644 --- a/ets2panda/test/parser/ets/local-class.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets @@ -13,8 +13,9 @@ * limitations under the License. */ -function main() : int -{ - class LocalClass { } - return 0; -} \ No newline at end of file +function foo() {} + +@/* @@ label */foo +@interface anno {} + +/* @@@ label Error TypeError: Cannot find type 'foo'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/arithmetic/ops_overflow.ets b/ets2panda/test/ast/parser/ets/arithmetic/ops_overflow.ets new file mode 100644 index 0000000000000000000000000000000000000000..83e76e9d97dc403dcdb43916b408fc985baf5fa8 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/arithmetic/ops_overflow.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. + */ + +const INT_MIN:int = -2147483648; +const DivInt = /*@@ DivInt */ INT_MIN / -1; +const ModInt = /*@@ ModInt */ INT_MIN % -1; +const MulInt = /*@@ MulInt */ INT_MIN * -1; +const SubInt = /*@@ SubInt */ INT_MIN - 1; +const AddInt = /*@@ AddInt */ INT_MIN + INT_MIN; + +const BYTE_MIN:Byte = -128; +const BYTE_NEG_ONE:Byte = -1; +const BYTE_POS_ONE:Byte = 1; +const DivByte = /*@@ DivByte */ BYTE_MIN / BYTE_NEG_ONE; +const ModByte = /*@@ ModByte */ BYTE_MIN % BYTE_NEG_ONE; +const MulByte = /*@@ MulByte */ BYTE_MIN * BYTE_NEG_ONE; +const SubByte = /*@@ SubByte */ BYTE_MIN - BYTE_POS_ONE; +const AddByte = /*@@ AddByte */ BYTE_MIN + BYTE_MIN; + +// Negation is allowed since parser treats -128 as -(128). +const NegInt = -INT_MIN; +const NegByte = -BYTE_MIN; + +/* @@@ DivInt Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ ModInt Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ MulInt Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ SubInt Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ AddInt Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ DivByte Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ ModByte Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ MulByte Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ SubByte Error TypeError: Arithmetic operation causes an overflow. */ +/* @@@ AddByte Error TypeError: Arithmetic operation causes an overflow. */ 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_literal_inference.ets b/ets2panda/test/ast/parser/ets/array_literal_inference.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ab410b887fe3c48ecaffd2c36e4e14e6b9dff44 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/array_literal_inference.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(): void { + let b: [] = /* @@ label */[ 1 ] +} + +/* @@@ label Error TypeError: Initializer has 1 elements, but tuple requires 0 */ \ No newline at end of file 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 98f77116906351ca937ad3cb5bb91663820c2f7a..44f57bdbc23a0c4c5468ac982357460d98196ec0 100644 --- a/ets2panda/test/ast/parser/ets/array_type.ets +++ b/ets2panda/test/ast/parser/ets/array_type.ets @@ -28,4 +28,3 @@ class array_type { /* @@@ 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. */ - diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets index 4f43f45947bc04c843818e374273890a9a511f25..83c44d1cf3d992c8ecd541a105992e7833f725c6 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets @@ -14,8 +14,8 @@ */ function main(): void { - /* @@ label1 */assertTrue(/* @@ label2 */"true") + /* @@ label1 */arktest.assertTrue(/* @@ label2 */"true") } /* @@@ label1 Error TypeError: No matching call signature for assertTrue("true") */ -/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'Boolean' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets index e63562d1a0993583cb2956ba5dd81b9be173bb26..30a3f6b53d887387e9767382e54efdda8d0c4d4c 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets @@ -14,8 +14,8 @@ */ function main(): void { - /* @@ label1 */assertTrue(/* @@ label2 */1) + /* @@ label1 */arktest.assertTrue(/* @@ label2 */1) } -/* @@@ label1 Error TypeError: No matching call signature for assertTrue(int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'boolean' at index 1 */ +/* @@@ label1 Error TypeError: No matching call signature for assertTrue(Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'Boolean' at index 1 */ 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/assignment_non-functional_variable_to_functional_type_1.ets b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets index d19b824b7b5ec003e43b95c6964220598cf7aef4..2d9c1d6732e590dfd41211ae8ce4749bedaf29ff 100644 --- a/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets @@ -20,4 +20,4 @@ function main() a = /* @@ label */b } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int' */ diff --git a/ets2panda/test/ast/parser/ets/asteriks_in_selective_binding.ets b/ets2panda/test/ast/parser/ets/asteriks_in_selective_binding.ets new file mode 100644 index 0000000000000000000000000000000000000000..367d9d3f2bd41687028bb20349d7a4dc9d1db6f7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/asteriks_in_selective_binding.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 { * } from './module'; + +/* @@? 16:10 Error SyntaxError: The '*' token is not allowed as a selective binding (between braces). */ +/* @@? 16:10 Error SyntaxError: Unexpected token '*'. */ +/* @@? 16:14 Error TypeError: Unresolved reference from */ +/* @@? 16:19 Error SyntaxError: Unexpected token './module'. */ diff --git a/ets2panda/test/ast/parser/ets/async_function_bad.ets b/ets2panda/test/ast/parser/ets/async_function_bad.ets index 6d7733236c198b36703f05e352da1db8143931fa..d7c4a852b25b8e90f91677213358c186e36d53bd 100644 --- a/ets2panda/test/ast/parser/ets/async_function_bad.ets +++ b/ets2panda/test/ast/parser/ets/async_function_bad.ets @@ -19,11 +19,9 @@ async native function foo(): Promise; /* @@? 16:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 16:14 Error SyntaxError: Unexpected token, expected '('. */ /* @@? 16:14 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 16:23 Error TypeError: The type of parameter 'foo' cannot be inferred */ /* @@? 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:30 Error TypeError: Class name 'Promise' used in the wrong context */ +/* @@? 16:28 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:30 Error SyntaxError: Unexpected token 'Promise'. */ +/* @@? 16:30 Error SyntaxError: Class cannot be used as object. */ diff --git a/ets2panda/test/ast/parser/ets/async_lambda_bad.ets b/ets2panda/test/ast/parser/ets/async_lambda_bad.ets index 702a26d0ced70fc76c75c67ee2f13ba02061e935..addfd7657ba1724ff2cd4ebb67ee3a98a247714e 100644 --- a/ets2panda/test/ast/parser/ets/async_lambda_bad.ets +++ b/ets2panda/test/ast/parser/ets/async_lambda_bad.ets @@ -14,5 +14,3 @@ */ let lambda: () => int = async /* @@ label */(): int => { return 1; } - -/* @@@ label Error TypeError: Return type of async lambda must be 'Promise' */ diff --git a/ets2panda/test/runtime/ets/lambda_with_default.ets b/ets2panda/test/ast/parser/ets/async_this.ets similarity index 78% rename from ets2panda/test/runtime/ets/lambda_with_default.ets rename to ets2panda/test/ast/parser/ets/async_this.ets index 85e5cf14dd61752a5d4634e502557813364ea232..7abb732b25bc33d6eea6962267f13c9980ca25e7 100644 --- a/ets2panda/test/runtime/ets/lambda_with_default.ets +++ b/ets2panda/test/ast/parser/ets/async_this.ets @@ -13,13 +13,10 @@ * limitations under the License. */ -function main() { - ()=> { - class A { - foo(x :String ="aa"){ - return x; - } - } +class A{ + async foo(this:A){ + return new Promise((resolve)=>{}) } - assertTrue(true) } + +/* @@? 17:15 Error SyntaxError: Unexpected 'this' keyword in non-receiver context. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/await_argument_null.ets b/ets2panda/test/ast/parser/ets/await_argument_null.ets index 9b7a14c21a652b69bb7b6964519a143d756cd44d..80bafac1206b5a966adb6866503b595cb26e06ea 100644 --- a/ets2panda/test/ast/parser/ets/await_argument_null.ets +++ b/ets2panda/test/ast/parser/ets/await_argument_null.ets @@ -14,9 +14,10 @@ */ async function foo(): Promise { - let obj: Object = await /* @@ label */null; + let obj: Object = /* @@ label */await null; return /* @@ label1 */null; } -/* @@@ label Error TypeError: 'await' expressions require Promise object as argument. */ +/* @@@ label Error TypeError: Type 'null' can not be awaited, it is not a Promise. */ +/* @@@ label Error TypeError: Type 'null' cannot be assigned to type 'Object' */ /* @@@ label1 Error TypeError: Type 'null' is not compatible with the enclosing method's return type 'Promise | Object' */ 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_object_bad.ets b/ets2panda/test/ast/parser/ets/await_object_bad.ets index 0b3bf805beece237b9a7d06af2d055d4cec640b1..f7d0995413fe66400d9770a2f20dfaefc65280ee 100644 --- a/ets2panda/test/ast/parser/ets/await_object_bad.ets +++ b/ets2panda/test/ast/parser/ets/await_object_bad.ets @@ -14,9 +14,9 @@ */ async function foo(): Promise { - let obj: Object = await /* @@ label */5; + let obj: Object = /* @@ label */await 5; return /* @@ label1 */null; } -/* @@@ label Error TypeError: 'await' expressions require Promise object as argument. */ +/* @@@ label Error TypeError: Type 'Int' can not be awaited, it is not a Promise. */ /* @@@ label1 Error TypeError: Type 'null' is not compatible with the enclosing method's return type 'Promise | Object' */ 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..4e77ac3504eb0fe575b83ec5f4ee7de37a694224 --- /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); + arktest.assertEQ(await p, 6); + arktest.assertEQ(await p * 2, 12); + arktest.assertEQ(await p / 2, 3); + arktest.assertEQ(await p % 3, 0); + arktest.assertEQ(await p + 1, 7); + arktest.assertEQ(await p - 2, 4); + arktest.assertEQ(await p === 6, true); + arktest.assertEQ(await p != 4, true); + arktest.assertEQ(1 << await p, 64); + arktest.assertEQ(await p > 3, true); + arktest.assertEQ(await p < 3, false); + arktest.assertEQ(await p == 6, true); + arktest.assertEQ(await p != 1, true); + arktest.assertEQ(await p & 3, 2); + arktest.assertEQ(await p ^ 2, 4); + arktest.assertEQ(await p | 1, 7); + + let b = Promise.resolve(false); + arktest.assertEQ(await b || true, true); + let n = Promise.resolve(null); + arktest.assertEQ(await n ?? 42, 42); + let r = await p > 3 ? "yes" : "no"; + arktest.assertEQ(r, "yes"); + let x = await p; + arktest.assertEQ(x, 6); +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/await_promise_bad.ets b/ets2panda/test/ast/parser/ets/await_promise_bad.ets index d0ee72abbd50899c18e50cd7ebc25219c3dfe023..e1d10cf9598b5c59b6973b46dd952155bdba73f8 100644 --- a/ets2panda/test/ast/parser/ets/await_promise_bad.ets +++ b/ets2panda/test/ast/parser/ets/await_promise_bad.ets @@ -14,9 +14,9 @@ */ async function foo(): Promise { - let obj: Object = await /* @@ label */new Object(); + let obj: Object = /* @@ label */await new Object(); return /* @@ label1 */null; } -/* @@@ label Error TypeError: 'await' expressions require Promise object as argument. */ +/* @@@ label Error TypeError: Type 'Object' can not be awaited, it is not a Promise. */ /* @@@ label1 Error TypeError: Type 'null' is not compatible with the enclosing method's return type 'Promise | Object' */ diff --git a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets index 1ff5c330df473013907b03a2909c42ccb81538c9..fca951695d795059af2144eaf118d1360da68648 100644 --- a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets +++ b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets @@ -27,4 +27,5 @@ function main() /* @@ label */b(1, 2) } -/* @@@ label Error TypeError: This expression is not callable. */ +/* @@@ label Error TypeError: No static $_invoke method and static $_instantiate method in b. b() is not allowed. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ 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/circular_class_extends.ets b/ets2panda/test/ast/parser/ets/circular_class_extends.ets new file mode 100644 index 0000000000000000000000000000000000000000..4cac2e3719f03516fa733c496a5644d10b11e338 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/circular_class_extends.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. + */ + +namespace m { + export class c { + } +} + +// Instead of assigning namespace to variable, export the namespace directly +export { m }; + +// If you want to re-export the class from the namespace: +export class c extends m.c {} + +/* @@? 25:28 Error TypeError: Class's super type is itself */ diff --git a/ets2panda/test/ast/parser/ets/circular_in_class_functions.ets b/ets2panda/test/ast/parser/ets/circular_in_class_functions.ets new file mode 100644 index 0000000000000000000000000000000000000000..d128f8bccee0a32e9b22da38a5be5a09aa1c7e0b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/circular_in_class_functions.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 Test { + foo() {} + + bar() { + this.baz(this, "*1*"); + + const t = new Test() + this.baz(t, "*2*"); + } + + baz(a: Test, k: keyof Test) {} +} + +/* @@? 20:9 Error TypeError: No matching call signature for baz(Test, "*1*") */ +/* @@? 20:24 Error TypeError: Type '"*1*"' is not compatible with type '"foo"|"bar"|"baz"' at index 2 */ +/* @@? 23:9 Error TypeError: No matching call signature for baz(Test, "*2*") */ +/* @@? 23:21 Error TypeError: Type '"*2*"' is not compatible with type '"foo"|"bar"|"baz"' at index 2 */ +/* @@? 26:31 Error TypeError: Circular type of reference */ diff --git a/ets2panda/test/ast/parser/ets/circular_type_in_alias.ets b/ets2panda/test/ast/parser/ets/circular_type_in_alias.ets new file mode 100644 index 0000000000000000000000000000000000000000..09a0912afdb078b51efeb8e558a248d3b9c6d2fc --- /dev/null +++ b/ets2panda/test/ast/parser/ets/circular_type_in_alias.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. + */ + +type Loop> = { + [P in keyof T]: U[P] extends boolean ? number : string; +}; + +/* @@? 16:24 Error TypeError: Circular type alias reference */ +/* @@? 16:38 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 17:6 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 17:10 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:16 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:18 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:18 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:19 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:22 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:23 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 17:24 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:26 Error SyntaxError: Unexpected token 'extends'. */ +/* @@? 17:34 Error SyntaxError: boolean is a predefined type, cannot be used as an identifier */ +/* @@? 17:42 Error SyntaxError: Unexpected token '?'. */ +/* @@? 17:44 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ +/* @@? 17:51 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:53 Error SyntaxError: string is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.ets b/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.ets index ef8d91f4ec84dbd0bdf6199e3a05f264d41c0dd5..5724caccac56b6e47b75648daeaaed243d5b1a28 100644 --- a/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.ets +++ b/ets2panda/test/ast/parser/ets/class-instance-field-redeclaration.ets @@ -19,4 +19,3 @@ class C { } /* @@@ label Error TypeError: Variable 'foo' has already been declared. */ -/* @@@ label Error TypeError: Property 'foo' must be accessed through 'this' */ diff --git a/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.ets b/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.ets index 87471276b09cc49968c4d2105a525345c4dabd4e..7951f410c99a0826dd9d00f62d92d5022f853a9c 100644 --- a/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.ets +++ b/ets2panda/test/ast/parser/ets/class-static-field-redeclaration.ets @@ -19,4 +19,3 @@ class C { } /* @@@ label Error TypeError: Variable 'foo' has already been declared. */ -/* @@@ label Error TypeError: Static property 'foo' must be accessed through it's class 'C' */ 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/test_jsvalue_set_property_2.ets b/ets2panda/test/ast/parser/ets/class_composite_invalid_target.ets similarity index 77% rename from ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets rename to ets2panda/test/ast/parser/ets/class_composite_invalid_target.ets index c1d3f0a5cb700a6429918fae9140328e6df25e0d..dcf98bfb30aa553154b813838ef5df2056894836 100644 --- a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets +++ b/ets2panda/test/ast/parser/ets/class_composite_invalid_target.ets @@ -13,9 +13,10 @@ * limitations under the License. */ -function fn(): void { - let v: JSValue; - /* @@ label */v.prop_name = 5.6; -} +type A = number | boolean; -/* @@@ label Warning Warning: Variable 'v' is used before being assigned. */ +let obj: A = { + x: 123 +}; + +/* @@? 18:14 Error TypeError: Target type for class composite needs to be an object type, found 'Double|Boolean' */ diff --git a/ets2panda/test/ast/parser/ets/class_keyword.ets b/ets2panda/test/ast/parser/ets/class_keyword.ets index f34d001a8c3e3270a960406e2c941dfabda5c726..93b3062592e6a82a9602391d9a7253617865f5ef 100644 --- a/ets2panda/test/ast/parser/ets/class_keyword.ets +++ b/ets2panda/test/ast/parser/ets/class_keyword.ets @@ -13,13 +13,10 @@ * limitations under the License. */ -final /* @@ label */kngkgj class /* @@ label1 */B /* @@ label2 */{ +final kngkgj class B { } -/* @@@ label Error SyntaxError: Unexpected token 'kngkgj'. */ -/* @@? 16:21 Error TypeError: Cannot find type 'kngkgj'. */ -/* @@? 16:21 Error TypeError: Class literal is not yet supported. */ -/* @@@ label1 Error SyntaxError: Unexpected token 'B'. */ -/* @@? 16:49 Error TypeError: Unresolved reference B */ -/* @@@ label2 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:7 Error SyntaxError: Unexpected token 'kngkgj'. */ +/* @@? 16:7 Error TypeError: Unresolved reference kngkgj */ +/* @@? 16:14 Error SyntaxError: Unexpected token 'class'. */ 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_optional_property.ets b/ets2panda/test/ast/parser/ets/class_optional_property.ets index ce1be206b3083fb2b2dac5992fe4378eab8bbad5..a0c0ea28577b0444f7d3f5e04c35130c480b6d4e 100644 --- a/ets2panda/test/ast/parser/ets/class_optional_property.ets +++ b/ets2panda/test/ast/parser/ets/class_optional_property.ets @@ -17,4 +17,4 @@ class A { applyNormalAttribute ?: () => void = /* @@ label */1 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => void|undefined' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => void|undefined' */ 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/class_variable_empty.ets b/ets2panda/test/ast/parser/ets/class_variable_empty.ets index aa702d4d0e01de724559f20930f285709885d74a..cb91389b8db3d6d4c1d3554615ab4cf364381efa 100644 --- a/ets2panda/test/ast/parser/ets/class_variable_empty.ets +++ b/ets2panda/test/ast/parser/ets/class_variable_empty.ets @@ -17,8 +17,11 @@ function main(): void { { class A {} let a: A = new A; - assertTrue(a != null) + arktest.assertTrue(a != null) } - assertTrue(/* @@ label */a != null) + arktest.assertTrue(a != null) } -/* @@@ label Error TypeError: Unresolved reference a */ \ No newline at end of file +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ +/* @@? 22:22 Error TypeError: Unresolved reference a */ diff --git a/ets2panda/test/ast/parser/ets/comma_only_in_for.ets b/ets2panda/test/ast/parser/ets/comma_only_in_for.ets new file mode 100644 index 0000000000000000000000000000000000000000..049e5d2b5670040165073ca76becc3c44cc2502a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/comma_only_in_for.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 x = 0 +x = (++x/* @@ label */, x++) + +/* @@@ label Error SyntaxError: Comma operator is supported only in 'for' loops. */ diff --git a/ets2panda/test/ast/parser/ets/comma_only_in_for_2.ets b/ets2panda/test/ast/parser/ets/comma_only_in_for_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..4b39ce75341e138ad75365c91d09828ac6f915ba --- /dev/null +++ b/ets2panda/test/ast/parser/ets/comma_only_in_for_2.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 x = 10 +let y = (x++/* @@ label */, 2, 44, x+10) + +/* @@@ label Error SyntaxError: Comma operator is supported only in 'for' loops. */ diff --git a/ets2panda/test/ast/parser/ets/constFloatInSwitch.ets b/ets2panda/test/ast/parser/ets/constFloatInSwitch.ets index e20ecb818261118d5a105607f905c24a8a398cb6..9b252bca1823743b16df1aea7bd63f8fad26182c 100644 --- a/ets2panda/test/ast/parser/ets/constFloatInSwitch.ets +++ b/ets2panda/test/ast/parser/ets/constFloatInSwitch.ets @@ -26,10 +26,10 @@ function main(): void { break case 2: break - default: assertTrue(false, "Not expected execution here"); + default: arktest.assertTrue(false, "Not expected execution here"); } } } -/* @@@ label1 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'int' */ -/* @@@ label2 Error TypeError: Unexpected type double */ +/* @@@ label1 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Int' */ +/* @@? 25:33 Error TypeError: Switch case type 'double' is not comparable to discriminant type 'int' */ diff --git a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets index f77025113d6a03ddbd00939ff3498011ad6af27d..56d7728f427cc0275cd0fb1f19d53fc1e40b6134 100644 --- a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets +++ b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets @@ -25,5 +25,5 @@ enum Color { } -/* @@? 20:14 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ -/* @@? 24:11 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ +/* @@? 20:14 Error SyntaxError: Division by zero is not allowed. */ +/* @@? 24:11 Error SyntaxError: Division by zero is not allowed. */ diff --git a/ets2panda/test/ast/parser/ets/constructorFunctionType_n.ets b/ets2panda/test/ast/parser/ets/constructorFunctionType_n.ets new file mode 100644 index 0000000000000000000000000000000000000000..b5087a482b4b6bc37b878d3be1d44f53cddc0e35 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/constructorFunctionType_n.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 Person { + constructor(name: string,age: number) {} +} +type PersonCtor = new (name: string, age: number) => Person + +/* @@? 19:1 Error SyntaxError: Constructor function types are not supported. */ diff --git a/ets2panda/test/ast/parser/ets/constructor_no_type_parameters.ets b/ets2panda/test/ast/parser/ets/constructor_no_type_parameters.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f5695c28969865c29577d9c4d346fd685bc60ab --- /dev/null +++ b/ets2panda/test/ast/parser/ets/constructor_no_type_parameters.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 C { + constructor(x: int) {} +} + +class D { + constructor(x: T) {} +} diff --git a/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets index d31d7c3e7a9b63085039b91a46b9988c1aaa4024..6b09631bfbdf4398522d75642ca940451999740a 100644 --- a/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets +++ b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets @@ -16,12 +16,12 @@ class C { constructor(x: number, y: string); constructor(s: string); - constructor(xs: any, y?: any) {} + constructor(xs: xny, y?: xny) {} } 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'. */ +/* @@? 19:19 Error TypeError: Cannot find type 'xny'. */ +/* @@? 19:28 Error TypeError: Cannot find type 'xny'. */ diff --git a/ets2panda/test/ast/parser/ets/constructor_type_parameters.ets b/ets2panda/test/ast/parser/ets/constructor_type_parameters.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff1194075b9aad7afca50984b7a91e611b1e07b0 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/constructor_type_parameters.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 C { + constructor(x: T) {} +} + +/* @@? 17:17 Error SyntaxError: Constructor should not have type parameters. */ diff --git a/ets2panda/test/ast/parser/ets/continue_while_target_outside_lambda.ets b/ets2panda/test/ast/parser/ets/continue_while_target_outside_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..b80b62d70107be76a499ebac316317c1fb017d92 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/continue_while_target_outside_lambda.ets @@ -0,0 +1,32 @@ +/*--- +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: Continue target outside lambda +tags: [negative, compile-only] +---*/ + +function main(): void { + target: + while(true) { + const f = () => { + while(true) { + continue target; + } + } + } +} + +/* @@? 26:17 Error TypeError: Continue target can't be outside the function */ diff --git a/ets2panda/test/ast/parser/ets/cycle_constructor.ets b/ets2panda/test/ast/parser/ets/cycle_constructor.ets index cfcd15c37117e8191d1a1c808a0252497119475f..39de52dd4507d888caeffb117e4955f3b9161270 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 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/decl_in_param.ets b/ets2panda/test/ast/parser/ets/decl_in_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..39e7ac9b8f22cb6f5796d6ff0e57cd8a085c4823 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/decl_in_param.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 f(public x: number){ +} +class C{ + constructor(public m:number) {} + m(public x:number) {} +} +/* @@? 16:12 Error SyntaxError: Declaring fields in parameter list is not supported */ +/* @@? 19:17 Error SyntaxError: Declaring fields in parameter list is not supported */ +/* @@? 20:7 Error SyntaxError: Declaring fields in parameter list is not supported */ diff --git a/ets2panda/test/ast/parser/ets/declare_ambient_context.ets b/ets2panda/test/ast/parser/ets/declare_ambient_context.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7284c2aee5079dbf8a3aca94887a2e31a0dfd61 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/declare_ambient_context.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 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. +*/ + +declare namespace A{ + declare function foo(): void +} + +/* @@? 17:5 Error SyntaxError: A 'declare' modifier cannot be used in an already ambient context. */ diff --git a/ets2panda/test/ast/parser/ets/declare_annotation.ets b/ets2panda/test/ast/parser/ets/declare_annotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba73fcc9baeb39b9f037ef4395bdaca852d3a71b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/declare_annotation.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. + */ + +@interface ClassAuthor { + au`horName: string = "1" +} + +class A{ + @ClassAuthor + foo1(){} + + @ClassAuthor("11") + foo2(){} + + @ClassAuthor({authorName: "22"}) + foo3() + +/* @@? 17:7 Error SyntaxError: Missing type annotation for property 'au'. */ +/* @@? 17:7 Error SyntaxError: Identifier expected, got '`'. */ +/* @@? 21:6 Error TypeError: The required field 'au' must be specified. Fields without default values cannot be omitted. */ +/* @@? 24:6 Error TypeError: Annotation 'ClassAuthor' requires multiple fields to be specified. */ +/* @@? 24:18 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ +/* @@? 27:6 Error TypeError: The required field 'au' must be specified. Fields without default values cannot be omitted. */ +/* @@? 27:19 Error TypeError: The parameter 'authorName' does not match any declared property in the annotation 'ClassAuthor'. */ +/* @@? 28:9 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 39:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets index 0c45ca27f6849ad0ff1809083335947178026352..29c95eb7e73edeec0489647523271cf63834cc9b 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:18 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:18 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:18 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets index 175aac24e64efafd405c224f57575e8aac3fdf5f..d826e1d2056cd8c841cffd2ee8f069977b7ca548 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:25 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:25 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:25 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_neg.ets b/ets2panda/test/ast/parser/ets/declare_class_neg.ets index 442c851340a95ca4b4d110a3074a09b2ad1324dc..9426627656abb696ad89feccf9518d102251c1c2 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_neg.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_neg.ets @@ -14,11 +14,11 @@ */ declare class A { - declare /* @@ label */constructor() + declare/* @@ label */ constructor() } class B { - declare /* @@ label1 */constructor() + declare/* @@ label1 */ constructor() } -/* @@@ label Error SyntaxError: Field type annotation expected. */ -/* @@@ label1 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:10 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:10 Error SyntaxError: Field type annotation expected. */ /* @@? 20:37 Error TypeError: Only abstract or native methods can't have body. */ diff --git a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets index 61605b9c0d41be5e590fd2276c0ed928727e5719..0b586d7dafcea2a6f641907604702a9f9197c101 100644 --- a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets +++ b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets @@ -49,10 +49,11 @@ class B { } /* @@? 17:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 18:9 Error TypeError: Unresolved reference dfdfsfdf */ /* @@? 20:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ /* @@? 23:20 Error TypeError: Unresolved reference foo */ /* @@? 27:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ /* @@? 36:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ -/* @@? 39:5 Error SyntaxError: Field type annotation expected. */ +/* @@? 38:13 Error SyntaxError: Field type annotation expected. */ /* @@? 39:20 Error TypeError: This expression is not callable. */ /* @@? 43:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ 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/default_parameter3.ets b/ets2panda/test/ast/parser/ets/default_parameter3.ets index a1ea174314af3add6e8317a2595810cc60eeafa6..80c76508f8a0a8e3b18f3bd1bc9ff341ff6df977 100644 --- a/ets2panda/test/ast/parser/ets/default_parameter3.ets +++ b/ets2panda/test/ast/parser/ets/default_parameter3.ets @@ -18,4 +18,4 @@ function foo(a : int = 10, /* @@ label */b : int, c : int = 15) : int return a + b; } -/* @@@ label Error SyntaxError: Required parameter follows default parameter(s). */ +/* @@@ label Error SyntaxError: A required parameter cannot follow an optional parameter. */ diff --git a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets index e41197292f16348b5911fcc0a048a82718a2ba67..445b9063bde45cb0ae806160c22c423986ba8cd7 100644 --- a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets +++ b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets @@ -23,4 +23,4 @@ function main(): void { foo(/* @@ label */a == b); } -/* @@@ label Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@@ label Error TypeError: Operator '==' cannot be applied to types '"alma"' and 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/do_while.ets b/ets2panda/test/ast/parser/ets/do_while.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0256a02dc90595b88b4f306486badc062f2360b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/do_while.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. + */ + +do a + +/* @@? 16:4 Error TypeError: Unresolved reference a */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected 'while'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 24:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 24:1 Error SyntaxError: Missing condition in do while statement */ +/* @@? 24:1 Error SyntaxError: Expected ')', got 'end of stream'. */ 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/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets index e01a4ddc3b21c6c7dcb358e752a2f4d1b68ce4e5..15a984dc8f63a08467238342facaa8ad9dd54f3c 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets @@ -20,7 +20,9 @@ flags: [dynamic-ast] import { A } from "dynamic_import_tests/modules/module" function main(): void { - let x = /* @@ label */new A(/* @@ label1 */"abc", 10) + let x = new A("abc", 10) } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ -/* @@@ label Error TypeError: No matching construct signature for module.A("abc", int) */ + +/* @@? 23:13 Error TypeError: Expected 0 arguments, got 2. */ +/* @@? 23:13 Error TypeError: No matching construct signature for module.A("abc", Int) */ +/* @@? 23:19 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets index 6d872c4eabbbab5558b3f626cd45c30bb0c0a2f5..c2356b47e29135ca013137b2a7e4a1803f6b1d18 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { p.f1 = /* @@ label */10 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets index 39bac5dcae933a6b81bac4e0f5352b11714ee72b..20edcbd465566ba1555e892fa1d18f18b061b658 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.f2 } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..fba26f324210f8a335408b5830bcad53e11d1a26 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { A, I, Animal } from "dynamic_import_tests/modules/module" + +let a = /* @@ label */new Animal() // CTE + +class Bird extends Animal /* @@ label1 */{ // OK + move(): void { } +} + +class C extends A /* @@ label2 */{ + override foo(p: double): string { + } //ok +} // ok + +let c = new C() +c.f1 // ok +C.f2 // ok +c./* @@ label3 */f3 // cte +c.foo(123) // ok +C.bar() // ok +c./* @@ label4 */foa() //cte + +class C1 implements I /* @@ label5 */{ // ok + s: string + f1(p: string): double { + return 12 + } + f2(p: double): string { + return "" + } +} + +function foo(i: I) { + i.s // ok + i./* @@ label6 */n // cte + i.f1("") // ok + i./* @@ label7 */f3() // cte +} + +/* @@@ label Error TypeError: Animal is abstract therefore cannot be instantiated. */ +/* @@@ label1 Error TypeError: class Bird can not extends class Animal which is from dynamic declaration file. */ +/* @@@ label2 Error TypeError: class C can not extends class A which is from dynamic declaration file. */ +/* @@@ label3 Error TypeError: Property 'f3' does not exist on type 'C' */ +/* @@@ label4 Error TypeError: Property 'foa' does not exist on type 'C' */ +/* @@@ label5 Error TypeError: class C1 can not implements interface I which is from dynamic declaration file. */ +/* @@@ label6 Error TypeError: Property 'n' does not exist on type 'I' */ +/* @@@ label7 Error TypeError: Property 'f3' does not exist on type 'I' */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets index 23eb4a01ec774aa0e3edce4914baf27266be38ac..db83b85465026483c39f0d5a06e2b3960ca3f955 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets @@ -22,5 +22,5 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { /* @@ label */p.foo(/* @@ label1 */"abc") } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ +/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ /* @@@ label Error TypeError: No matching call signature for foo("abc") */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets index 3acfee0beaa0a0da642ca8eaf5a429d99691863e..bb4b9e0c59ed936887cb351fbd4cd8b1c6402097 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.bar() } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_error.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..940a12d9810ace25736374825faa8bdc90c8adcd --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { MyError } from "dynamic_import_tests/modules/module" + +function main() { + try { + throw new MyError() + } catch (e) { + let myError = e as MyError; + } +} + diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_function_use_as_value.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_function_use_as_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..a82806dcf2aa847a9260193728d45e2b255d79df --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_function_use_as_value.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { foo, A } from "dynamic_import_tests/modules/module" + +function bar(f:(p:A)=>void){} + +bar(foo) // should not crash \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ea885ad62afc35ddf3ff692e6cb51308a0efa6f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { ns } from "dynamic_import_tests/modules/module" + +()=>{ + let a = new ns.A() +} diff --git a/ets2panda/test/parser/ets/constructorThrowsRethrows.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_optional_interface.ets similarity index 81% rename from ets2panda/test/parser/ets/constructorThrowsRethrows.ets rename to ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_optional_interface.ets index b65c49c82c69c8ff89b8d0eeb1040c86ae97c1e2..460ece0428a424a2e36c0a07e9cd9bf41e4ae217 100644 --- a/ets2panda/test/parser/ets/constructorThrowsRethrows.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_optional_interface.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -class TestClass { - constructor() throws {} -} +/*--- +flags: [dynamic-ast] +---*/ -class TestClassToo { - constructor(param: (c: int, b: int) => char throws) rethrows {} -} +import { OptionalInterface } from "dynamic_import_tests/modules/module" + +let a: OptionalInterface = {} diff --git a/ets2panda/test/ast/parser/ets/launch_super_ctor.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets similarity index 74% rename from ets2panda/test/ast/parser/ets/launch_super_ctor.ets rename to ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets index 840455baf973fcb12ffb772512cb05ec89c7aac0..2f6e3285bfff0b17a3b1eb57d1d9fc3b2b727ff3 100644 --- a/ets2panda/test/ast/parser/ets/launch_super_ctor.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets @@ -13,13 +13,16 @@ * limitations under the License. */ -class Base { -} +/*--- +flags: [dynamic-ast] +---*/ + +import { C, requiredC } from "dynamic_import_tests/modules/module" -class Derived extends Base { - constructor() { - launch /* @@ label */super(); - } +class A { + f?: A = new A() // should be ok } -/* @@@ label Error TypeError: Call to 'super' must be first statement in constructor */ +function foo(c: C) { } + +foo({ s: "" }) // should be ok diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/readonly_dynamic_class_interface.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/readonly_dynamic_class_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..f81878ad25902484504e643c6835ccecde2af278 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/readonly_dynamic_class_interface.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { C, I2 } from "dynamic_import_tests/modules/module" + +function main() { + let c: Readonly = { s: "123" } + c.s = "234" + let i: Readonly = { + name: "abc", + age: 123 + } + i.age = 124 +} + +/* @@? 24:5 Error TypeError: The 'Readonly' property cannot be reassigned. */ +/* @@? 24:5 Error TypeError: Cannot assign to a readonly variable s */ +/* @@? 29:5 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_extends_dynamic_class_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_extends_dynamic_class_bad.ets new file mode 100644 index 0000000000000000000000000000000000000000..57d9770affe6fd6bf4e8e51c58fb2ba9a77ec2ee --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_extends_dynamic_class_bad.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { C } from "dynamic_import_tests/modules/module" + +class A extends C /* @@ label */{ +} + +/* @@@ label Error TypeError: class A can not extends class C which is from dynamic declaration file. */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_impl_dynamic_interface_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_impl_dynamic_interface_bad.ets new file mode 100644 index 0000000000000000000000000000000000000000..28aadb3b200250a2cf2db6afd7dca734c2083ba6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_class_impl_dynamic_interface_bad.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { I } from "dynamic_import_tests/modules/module" + +class A implements I /* @@ label */{ + s:string = "aaa" + f1(p: string): double { + return 0.1; + } + f2(p: double): string { + return "foo"; + } +} + +/* @@@ label Error TypeError: class A can not implements interface I which is from dynamic declaration file. */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_interface_extends_dynamic_interface_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_interface_extends_dynamic_interface_bad.ets new file mode 100644 index 0000000000000000000000000000000000000000..4832fff1936bd21fba260be931905de1b647ed4a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/static_interface_extends_dynamic_interface_bad.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { I } from "dynamic_import_tests/modules/module" + +/* @@ label */interface A extends I { +} + +/* @@@ label Error TypeError: interface A can not extends interface I which is from dynamic declaration file. */ diff --git a/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets b/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets index 48d3448c4ef1913dfb83a09d79412d4b504f8d20..113b6cd6708e1901d8ee56ace99c9313b16601f7 100644 --- a/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets +++ b/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets @@ -20,14 +20,12 @@ function main() { .catch((a: object | null | undefined): never => { throw a as Error }) - } catch (e: Error) { - assertEQ(e.message, "Dynamic import is not supported") + } catch (e) { + arktest.assertEQ((e as Error).message, "Dynamic import is not supported") return } - assertTrue(!"nothing was thrown") + arktest.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:9 Error TypeError: Type '*ERROR_TYPE*' can not be awaited, it is not a Promise. */ 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 index 9552cc43a987d63b20da913d3326f7cbaef23102..dab191d5b7e27239944032f95c54f80efa65ebaa 100644 --- a/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets +++ b/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets @@ -21,18 +21,9 @@ return x+1; }); -/* @@? 16:1 Error TypeError: No matching call signature */ -/* @@? 16:1 Error TypeError: Expected 1 arguments, got 0. */ -/* @@? 16:2 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 16:2 Error SyntaxError: Unexpected token 'function'. */ -/* @@? 18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? 18:4 Error SyntaxError: Unexpected token ')'. */ -/* @@? 20:1 Error TypeError: Can't resolve array type */ -/* @@? 20:8 Error SyntaxError: Unexpected token 'function'. */ -/* @@? 20:8 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 20:16 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 20:17 Error TypeError: The type of parameter 'x' cannot be inferred */ +/* @@? 16:2 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 20:1 Error TypeError: Can't resolve array type */ +/* @@? 20:8 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ /* @@? 20:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ -/* @@? 22:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/enum.ets b/ets2panda/test/ast/parser/ets/enum.ets index fad4cf5c8343e6178e2f532036c8fdb91acc16b7..3443eb3f6c38ac0318e3b1f6bdbc74e170d7ec40 100644 --- a/ets2panda/test/ast/parser/ets/enum.ets +++ b/ets2panda/test/ast/parser/ets/enum.ets @@ -28,40 +28,42 @@ function colorToInt(c: Color): int { function main(): void { let red: Color = Color.Red; - assertEQ(red, Color.Red); - assertEQ(colorToInt(red), 0); + arktest.assertEQ(red, Color.Red); + arktest.assertEQ(colorToInt(red), 0); let red2: Color = red; - assertEQ(red, red2); - assertEQ(Color.Red, red2); + arktest.assertEQ(red, red2); + arktest.assertEQ(Color.Red, red2); let red_int: int = red as int; - assertEQ(red_int, 0); - assertEQ(red_int, Color.Red as int); + arktest.assertEQ(red_int, 0); + arktest.assertEQ(red_int, Color.Red as int); let a: A = new A(red); - assertEQ(a.c, Color.Red); + arktest.assertEQ(a.c, Color.Red); switch(red) { case Color.Green: - assertTrue(false) + arktest.assertTrue(false) break; case Color.Red: - assertTrue(true) + arktest.assertTrue(true) break; default: - assertTrue(false) + arktest.assertTrue(false) } switch(Color.Blue) { case Color.Green: case Color.Red: - assertTrue(false) + arktest.assertTrue(false) break; case Color.Blue: - assertTrue(true) + arktest.assertTrue(true) break; default: - assertTrue(false) + arktest.assertTrue(false) } } + +/* @@? 26:10 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/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/enum11.ets b/ets2panda/test/ast/parser/ets/enum11.ets index 0e1d8e35b438b8899285779527accddc1d6a604d..c78d967491c138158f757858b21bd5b205dc833c 100644 --- a/ets2panda/test/ast/parser/ets/enum11.ets +++ b/ets2panda/test/ast/parser/ets/enum11.ets @@ -24,3 +24,5 @@ function main(): void { } /* @@@ label Error TypeError: Enum name 'Color' used in the wrong context */ +/* @@? 21:22 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ +/* @@? 22:13 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'Color' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/enum15.ets b/ets2panda/test/ast/parser/ets/enum15.ets index 94ef7cd8c0f89f505c029a468c3069637df8e66f..2a32ffa2191b4f4c875c4bee460fe9c95697bed6 100644 --- a/ets2panda/test/ast/parser/ets/enum15.ets +++ b/ets2panda/test/ast/parser/ets/enum15.ets @@ -20,6 +20,7 @@ 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..ef121a53aaa5679da3c5b3891c2c0187d6ed8688 100644 --- a/ets2panda/test/ast/parser/ets/enum17.ets +++ b/ets2panda/test/ast/parser/ets/enum17.ets @@ -19,4 +19,5 @@ enum InvalidInitTypeEnum { Blue } -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@? 19:7 Error TypeError: Arithmetic operation causes an overflow. */ +/* @@? 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..b052216cadf5f248d42a0991f53e6cafe16ce94e 100644 --- a/ets2panda/test/ast/parser/ets/enum22.ets +++ b/ets2panda/test/ast/parser/ets/enum22.ets @@ -18,5 +18,3 @@ 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..fbea4d6c3b28da754b46afcf9aefa975a6e94f11 100644 --- a/ets2panda/test/ast/parser/ets/enum23.ets +++ b/ets2panda/test/ast/parser/ets/enum23.ets @@ -17,6 +17,4 @@ enum duplicateKeysNumCase { Red = 1, /* @@ 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' */ +/* @@@ label Error TypeError: Variable 'Red' has already been declared. */ \ No newline at end of file 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..1e38fdc9ccbd23cad43d8f136596e7b6b20be27b 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 */ + +/* @@@ label2 Error TypeError: Class 'Date' is already defined with different type. */ +/* @@@ label1 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ diff --git a/ets2panda/test/ast/parser/ets/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/enum30.ets b/ets2panda/test/ast/parser/ets/enum30.ets index f166e84ac76e31ca6d996507453d6613a7609f2c..321054058bc438a9690feaddc3950f1cff611527 100644 --- a/ets2panda/test/ast/parser/ets/enum30.ets +++ b/ets2panda/test/ast/parser/ets/enum30.ets @@ -31,7 +31,7 @@ enum ColorE { G = Color.Red | 1 } enum ColorF { - H = Color.Red ? ColorE.G : (ColorD.E | 1) as int, + H = Color.Red ? ColorE.G : (ColorD.E | 1), I = (ColorE.G / 25) } diff --git a/ets2panda/test/ast/parser/ets/enum31.ets b/ets2panda/test/ast/parser/ets/enum31.ets index 3af1f2679b74f3d343dfcfbb648e7ae525e592c9..78bc7d8d2c0e91a50dea1257ee25d1952c6131a2 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 */ +/* @@? 20:27 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 24:28 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/enum33.ets b/ets2panda/test/ast/parser/ets/enum33.ets new file mode 100644 index 0000000000000000000000000000000000000000..4de3700721c350951daef3a4d262df9d7743805b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enum33.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Percentage { + A = 0.45, + B = 0.55 +} diff --git a/ets2panda/test/ast/parser/ets/enum34.ets b/ets2panda/test/ast/parser/ets/enum34.ets new file mode 100644 index 0000000000000000000000000000000000000000..9fcdc33582450ae23757dd3ddf4d970e5d45f1f2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enum34.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction { + A = 1, + B = 0.1 +} + + +/* @@? 18:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ diff --git a/ets2panda/test/ast/parser/ets/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/enum7.ets b/ets2panda/test/ast/parser/ets/enum7.ets index 0027570f04fc1d34fd7bf082bfd5f2b8533f74ef..9fb29fa64f841de53bd2c441141321fcecdd757f 100644 --- a/ets2panda/test/ast/parser/ets/enum7.ets +++ b/ets2panda/test/ast/parser/ets/enum7.ets @@ -17,8 +17,8 @@ enum Color { Red } enum Color2 { Red } function main(): void { - // Is used 'assertTrue' due to #22840 - assertTrue(/* @@ label */Color.Red != Color2.Red); + // Is used 'arktest.assertTrue' due to #22840 + arktest.assertTrue(/* @@ label */Color.Red != Color2.Red); } /* @@@ label Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation.ets b/ets2panda/test/ast/parser/ets/enumAnnotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..625a12d886895dff4224b374a8202471f5cc53d5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: int { + A = 1, + B = 1 +} diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation2.ets b/ets2panda/test/ast/parser/ets/enumAnnotation2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d790c608a386b3a6eeb2d2f9403b61013fbe9bf5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation2.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: double { + A = 1.2, + B = 3.1 +} diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation3.ets b/ets2panda/test/ast/parser/ets/enumAnnotation3.ets new file mode 100644 index 0000000000000000000000000000000000000000..17fc47a361df438e6b9e34a0765f1d222caba8c0 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation3.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: string { + A = "A", + B = "B" +} + + +/* @@? 16:23 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation4.ets b/ets2panda/test/ast/parser/ets/enumAnnotation4.ets new file mode 100644 index 0000000000000000000000000000000000000000..2816b123bbfe215c49f072278a0a92fd70ce361f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation4.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: customInt { + A = 1, + B = 2 +} + + +/* @@? 16:26 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation5.ets b/ets2panda/test/ast/parser/ets/enumAnnotation5.ets new file mode 100644 index 0000000000000000000000000000000000000000..64ff1a363563cd8cb88b37c7e1ccc12df2f30269 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation5.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: int { + A = "A", + B = "B" +} + + +/* @@? 17:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 18:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation6.ets b/ets2panda/test/ast/parser/ets/enumAnnotation6.ets new file mode 100644 index 0000000000000000000000000000000000000000..b52526a67f952ca270ba61ea16bd1c25d2a59444 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation6.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Fraction: byte { + A = 1, + B = 2 +} + + +/* @@? 16:21 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation7.ets b/ets2panda/test/ast/parser/ets/enumAnnotation7.ets new file mode 100644 index 0000000000000000000000000000000000000000..05c4208c2ccc6d51ac26286e099f25c2cc93d10f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation7.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum E: double{ + A = 1.1, + B = 1.2 + 1.3, + C = B, + D = C + 1.5, + E = D - 2.5, + F = D * C, +} \ No newline at end of file diff --git a/ets2panda/test/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..28e438a43b2fc9e7a407c2214eed6f96314ed571 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative.ets @@ -26,13 +26,13 @@ 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. */ +/* @@? 25: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 'end of stream'. */ /* @@? 39: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..8764bff88cc296286f62e6bc0ae83d5b003e45dc 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets @@ -24,6 +24,7 @@ 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/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets index 6593711c1c5008fb95740028363e7ddac21adfeb..01cd69625eb71456383e81b3fc1fa65605488e00 100644 --- a/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets @@ -25,5 +25,6 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file + +/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 26:12 Error Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ diff --git a/ets2panda/test/parser/ets/methodThrowsRethrows.ets b/ets2panda/test/ast/parser/ets/export_after_statement.ets similarity index 80% rename from ets2panda/test/parser/ets/methodThrowsRethrows.ets rename to ets2panda/test/ast/parser/ets/export_after_statement.ets index 8467cf16b78aa7baf2ed41c2de8b6eefce7e91bb..cf56e544dead5fdb081574db5965292a1b5edff0 100644 --- a/ets2panda/test/parser/ets/methodThrowsRethrows.ets +++ b/ets2panda/test/ast/parser/ets/export_after_statement.ets @@ -13,8 +13,8 @@ * limitations under the License. */ -class TestClass { - testMethodThrows(): void throws {} - - testMethodRethrows(param: (c: int, b: int) => char throws): void rethrows {} +while (false) export { } + +/* @@? 16:15 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 16:15 Error SyntaxError: Missing body in while statement */ diff --git a/ets2panda/test/ast/parser/ets/export_as.ets b/ets2panda/test/ast/parser/ets/export_as.ets new file mode 100644 index 0000000000000000000000000000000000000000..f2c130fbe82e2eb4dc9f52b8c778f816c0390894 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/export_as.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 /* @@ label1 */as /* @@ label2 */namespace mathLib {} + +/* @@@ label1 Error SyntaxError: Universal module definitions are not supported, please use ordinary import/export syntax instead. */ +/* @@@ label1 Error SyntaxError: Unexpected token 'as'. */ +/* @@@ label2 Error SyntaxError: Unexpected token 'namespace'. */ diff --git a/ets2panda/test/ast/parser/ets/export_assignment.ets b/ets2panda/test/ast/parser/ets/export_assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..7dc0bbfcc8fef31455835e3c8a417e11b8d73aba --- /dev/null +++ b/ets2panda/test/ast/parser/ets/export_assignment.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 /* @@ label1 */= /* @@ label2 */Point + +/* @@@ label1 Error SyntaxError: 'export = ...' syntax is not supported, use regular import/export instead! */ +/* @@@ label1 Error SyntaxError: Unexpected token '='. */ +/* @@@ label2 Error SyntaxError: Unexpected token 'Point'. */ +/* @@@ label2 Error TypeError: Unresolved reference Point */ diff --git a/ets2panda/test/ast/parser/ets/export_default_multiple_specifier.ets b/ets2panda/test/ast/parser/ets/export_default_multiple_specifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..dfd50255646a775c65a87af805c7af1afb6215e4 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/export_default_multiple_specifier.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 myFunc(): void {} +function foo(): void {} + +export default {myFunc as default, foo as default} + +/* @@? 22:1 Error SyntaxError: export default is not allowed to export multiple specifiers. */ diff --git a/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error1.ets b/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error1.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc07a979392b8b518cbf1c0fd1e5d8fe3f4e777b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error1.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. + */ + +@AnimatableExtend +function animatableWidth(this: TextAttribute, this { this.width(width); return this; +} + +/* @@? 16:2 Error TypeError: Cannot find type 'AnimatableExtend'. */ +/* @@? 17:32 Error TypeError: Cannot find type 'TextAttribute'. */ +/* @@? 17:52 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:52 Error SyntaxError: Unexpected token, expected ',' or ')'. */ diff --git a/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error2.ets b/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error2.ets new file mode 100644 index 0000000000000000000000000000000000000000..569109a6ae232c927b768b1b0ad0503b1a014a6a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/extension_function_tests/extension_function_error2.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let a = (this: TextAttribute, this { this.width(width); return this; +} + +/* @@? 16:9 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 16:14 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:16 Error SyntaxError: Unexpected token 'TextAttribute'. */ +/* @@? 16:16 Error TypeError: Unresolved reference TextAttribute */ +/* @@? 16:29 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:31 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 16:31 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 16:36 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:38 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 16:43 Error TypeError: Property 'width' does not exist on type 'ETSGLOBAL' */ +/* @@? 16:57 Error SyntaxError: return keyword should be used in function body. */ +/* @@? 16:64 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 16:64 Error TypeError: All return statements in the function should be empty or have a value. */ diff --git a/ets2panda/test/ast/parser/ets/fields.ets b/ets2panda/test/ast/parser/ets/fields.ets index 414efc3575499d93614f562d11a6059d086b8b90..31cdc48edbacaced6e755ac2afbb339edea4b54f 100644 --- a/ets2panda/test/ast/parser/ets/fields.ets +++ b/ets2panda/test/ast/parser/ets/fields.ets @@ -28,4 +28,3 @@ class C { } /* @@@ label Error TypeError: Variable 'f' has already been declared. */ -/* @@@ label Error TypeError: Static property 'f' must be accessed through it's class 'C' */ diff --git a/ets2panda/test/ast/parser/ets/forOfCustomIterator1.ets b/ets2panda/test/ast/parser/ets/forOfCustomIterator1.ets index 6da443d23f9e818bb37abee9b42bbb964d6f5fe1..83583c963ddb6645c42e4f1ca9d4a443e0e20a42 100644 --- a/ets2panda/test/ast/parser/ets/forOfCustomIterator1.ets +++ b/ets2panda/test/ast/parser/ets/forOfCustomIterator1.ets @@ -46,7 +46,7 @@ function main(): void { let res = ""; let a = new A(); for (let x of a) res += x; - assertEQ(res, "abc"); + arktest.assertEQ(res, "abc"); } /* @@? 48:19 Error TypeError: Iterator method must return an object which implements Iterator */ diff --git a/ets2panda/test/ast/parser/ets/forOfCustomIterator2.ets b/ets2panda/test/ast/parser/ets/forOfCustomIterator2.ets index a3e3c2ecf773080df81640bab5c856b4b8dd9ff4..6282df4a6f4eacb5f9983966dc7611735e9c0250 100644 --- a/ets2panda/test/ast/parser/ets/forOfCustomIterator2.ets +++ b/ets2panda/test/ast/parser/ets/forOfCustomIterator2.ets @@ -44,7 +44,7 @@ function main(): void { let res = ""; let a = new A(); for (let x of a) res += x; - assertEQ(res, "abc"); + arktest.assertEQ(res, "abc"); } /* @@? 46:19 Error TypeError: Iterator method must return an object which implements Iterator */ 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_await_of_loop.ets b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets index aad9c9401809caa3da8e5b68332cc89819854b07..9ec9ec14aeb8d130d70cef40cceb0aa686ff19b0 100644 --- a/ets2panda/test/ast/parser/ets/for_await_of_loop.ets +++ b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets @@ -17,9 +17,8 @@ for await (let k: int /* @@ label1 */= 0; /* @@ label2 */k < d.length; k++) { this.$_set_unsafe(k + 1, d[k]) } -/* @@@ label1 Error SyntaxError: for-await-of loop variable declaration may not have an initializer. */ -/* @@@ label2 Error SyntaxError: Unexpected token 'k'. */ -/* @@? 16:58 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 16:38 Error SyntaxError: for-await-of loop variable declaration may not have an initializer. */ +/* @@? 16:58 Error SyntaxError: Unexpected token 'k'. */ /* @@? 16:62 Error TypeError: Unresolved reference d */ -/* @@? 17:5 Error TypeError: Cannot reference 'this' in this context. */ -/* @@? 17:10 Error TypeError: Property '$_set_unsafe' does not exist on type 'Error' */ +/* @@? 17:5 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 17:10 Error TypeError: Property '$_set_unsafe' does not exist on type 'ETSGLOBAL' */ diff --git a/ets2panda/test/ast/parser/ets/for_in.ets b/ets2panda/test/ast/parser/ets/for_in.ets new file mode 100644 index 0000000000000000000000000000000000000000..922bde17d5a79170a098ebc31071f129909015d2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/for_in.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: number[] = [1.0, 2.0, 3.0] +for (let i /* @@ label */in a) { +} + +/* @@@ label Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@@ label Error SyntaxError: 'for ... in' loop is not supported, please use regular 'for' or 'for ... of ...' loop to iterate through arrays + and iterable objects. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_02.ets b/ets2panda/test/ast/parser/ets/for_of_02.ets index 2488cf4cd9b1e7557335954ae067d5354d5e7a93..b30a1e168da0563f008e4aae0ddf9f67330f4da5 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'. */ +/* @@@ label 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 1131b1d91f3555d3c28476ff467088eb53ca3bef..0b51c9f55cf40b74822d6ecb8756c425f4897172 100644 --- a/ets2panda/test/ast/parser/ets/for_of_04.ets +++ b/ets2panda/test/ast/parser/ets/for_of_04.ets @@ -28,17 +28,11 @@ for (i in 50) { /* @@? 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 'double'. */ /* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ -/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ -/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ -/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ -/* @@? 20:11 Error SyntaxError: Expected ')', got 'double'. */ -/* @@? 20:11 Error SyntaxError: Unexpected token '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: Unexpected token 'a'. */ +/* @@? 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: Object type doesn't have proper iterator method. */ /* @@? 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..58952390f714c6ef9b7d68e498d986c4613e9226 100644 --- a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets +++ b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets @@ -32,5 +32,5 @@ for (let value = 40 /* @@ label2 */of iterable2) { /* @@@ 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'. */ +/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/functionTypeParam_neg2.ets b/ets2panda/test/ast/parser/ets/functionTypeParam_neg2.ets index b397027c6bc09776e6276193f9c9a1419bf51a80..e781375637427b39b2f3a01cfc4c58d5d51629b7 100644 --- a/ets2panda/test/ast/parser/ets/functionTypeParam_neg2.ets +++ b/ets2panda/test/ast/parser/ets/functionTypeParam_neg2.ets @@ -23,13 +23,19 @@ declare class Environment { static foo7(props1: {key:string, value:int}[], props2: int[]): void; } -/* @@? 17:23 Error SyntaxError: Invalid Type. */ -/* @@? 18:25 Error SyntaxError: Invalid Type. */ +/* @@? 17:23 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 18:25 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ /* @@? 19:25 Error SyntaxError: Invalid Type. */ +/* @@? 21:16 Error TypeError: Native and Declare methods should have explicit return type. */ /* @@? 21:20 Error SyntaxError: Invalid Type. */ /* @@? 21:28 Error SyntaxError: Invalid Type. */ /* @@? 21:37 Error SyntaxError: Unexpected token, expected '=>'. */ -/* @@? 21:37 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 21:37 Error SyntaxError: Invalid Type. */ +/* @@? 21:39 Error SyntaxError: Unexpected token '--'. */ +/* @@? 21:41 Error SyntaxError: Unexpected token '-'. */ +/* @@? 21:42 Error SyntaxError: Unexpected token ','. */ +/* @@? 21:43 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:44 Error SyntaxError: Unexpected token ':'. */ +/* @@? 21:45 Error SyntaxError: void is a predefined type, cannot be used as an identifier */ /* @@? 22:20 Error SyntaxError: Invalid Type. */ -/* @@? 23:25 Error SyntaxError: Invalid Type. */ \ No newline at end of file +/* @@? 23:25 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 23:36 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/functionTypeRethrows.ets b/ets2panda/test/ast/parser/ets/functionTypeRethrows.ets index 78d713ba541703baf4477570efe18c8d8d13f9b9..97ae8eaf9d04cc628a91d08b821648e500ea654a 100644 --- a/ets2panda/test/ast/parser/ets/functionTypeRethrows.ets +++ b/ets2panda/test/ast/parser/ets/functionTypeRethrows.ets @@ -13,6 +13,8 @@ * limitations under the License. */ -let a: (c: int, b: int) => char rethrows/* @@ label */; +let a: (c: int, b: int) => char /* @@ label */rethrows; -/* @@@ label Error SyntaxError: Only 'throws' can be used with function types. */ + +/* @@@ label Error SyntaxError: Unexpected token 'rethrows'. */ +/* @@@ label Error TypeError: Unresolved reference rethrows */ diff --git a/ets2panda/test/ast/parser/ets/function_implicit_return_type.ets b/ets2panda/test/ast/parser/ets/function_implicit_return_type.ets index 7412439361696493516c2cbd301dc1f86d3f1f7e..08913b18bbb2685af2e80d1ca994034db08248eb 100644 --- a/ets2panda/test/ast/parser/ets/function_implicit_return_type.ets +++ b/ets2panda/test/ast/parser/ets/function_implicit_return_type.ets @@ -24,8 +24,6 @@ let void6: (i: int ) /* @@ label */= void1 /* @@ label1 */; // CTE; need function main() {} -/* @@@ label Error SyntaxError: Unexpected token, expected '=>'. */ -/* @@@ label Error SyntaxError: Unexpected token, expected '('. */ -/* @@@ label Error SyntaxError: Invalid Type. */ -/* @@@ label Error SyntaxError: Unexpected token '('. */ -/* @@@ label1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 23:43 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 23:43 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 23:45 Error SyntaxError: Unexpected token 'void1'. */ diff --git a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets index 2d256845c7d7ec41f92b2200882cf46d53c7e806..89efc28509de05402bb6315a6445fb2669123d2e 100644 --- a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets +++ b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets @@ -22,5 +22,5 @@ final class B extends A { public override fn(): int { return 42; } } -/* @@? 22:21 Error TypeError: fn(): int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ -/* @@? 22:21 Error TypeError: Method fn(): int in B not overriding any method */ +/* @@? 22:21 Error TypeError: fn(): Int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ +/* @@? 22:21 Error TypeError: Method fn(): Int in B not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/function_implicit_return_type7.ets b/ets2panda/test/ast/parser/ets/function_implicit_return_type7.ets index 8d24e6099b05e4d4bbc366798f5788d5e76a9977..81afa2b1e73c143e6087e0b70bd5d1fa1fa40d0c 100644 --- a/ets2panda/test/ast/parser/ets/function_implicit_return_type7.ets +++ b/ets2panda/test/ast/parser/ets/function_implicit_return_type7.ets @@ -18,12 +18,10 @@ function fn(i: int) { if (i > 0) { return true; } - return /* @@ label */0; + return 0; } function main() { let a = fn(0); } - -/* @@@ label Error TypeError: Function cannot have different primitive return types, require 'boolean', found 'int' */ diff --git a/ets2panda/test/ast/parser/ets/generator_function.ets b/ets2panda/test/ast/parser/ets/generator_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f865bb644004d26a4883231dd986a68aa88f577 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/generator_function.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* f() {} +/* @@? 16:11 Error SyntaxError: Generator functions are not supported, please use async/await mechanism for multitasking */ 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/generic_error.ets b/ets2panda/test/ast/parser/ets/generic_error.ets index 1f5ee0a2518182ced77802dff40c85bf45c597b3..195bb99fa68ac1963cc56e5125ac5d2ba0d50148 100644 --- a/ets2panda/test/ast/parser/ets/generic_error.ets +++ b/ets2panda/test/ast/parser/ets/generic_error.ets @@ -23,4 +23,4 @@ function main(): void { let m = new OldMap/* @@ label */(); } -/* @@@ label Error TypeError: Type C is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'C' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/generic_type_alias_clone_fix.ets b/ets2panda/test/ast/parser/ets/generic_type_alias_clone_fix.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3b1333ceefea9271b7c62ad021d0ff1f1e39602 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/generic_type_alias_clone_fix.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type MyMap = { + kind: K +}; + +type RecordMap = { n: number }; + +let myMap: MyMap<"n"> = { kind: "n" }; + +/* @@? 16:37 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 16:41 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 20:18 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ 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/generics_type_param_constraint_8.ets b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets index 9268e2c5eb7c79153d49585131d7704dc296f540..3b5e329f9125c419349f8fe197fa7d770b29c5d8 100644 --- a/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets +++ b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets @@ -19,4 +19,4 @@ function main(){ const myCharClass = new X/* @@ label */(); } -/* @@@ label Error TypeError: Type Char is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'Char' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/get_unexpected_void.ets b/ets2panda/test/ast/parser/ets/get_unexpected_void.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a698416952148b24f4b3c2561cf69d54104dd5e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/get_unexpected_void.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class SomeClass { + $_get (index: string, value: SomeClass) { } +} + +/* @@? 17:5 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ +/* @@? 17:11 Error TypeError: 'The special predefined method '$_get' shouldn't have void return type. */ diff --git a/ets2panda/test/ast/parser/ets/getter_not_abstract.ets b/ets2panda/test/ast/parser/ets/getter_not_abstract.ets new file mode 100644 index 0000000000000000000000000000000000000000..aca30c3be7474c95d31d9b5b06797131a1731b82 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/getter_not_abstract.ets @@ -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. + */ + +interface A { + color : string; + get color(): string { + return "red" + } +} + +/* @@? 17:5 Error TypeError: Function color is already declared. */ +/* @@? 18:9 Error TypeError: Variable 'color' has already been declared. */ +/* @@? 18:14 Error SyntaxError: Getter and setter methods must be abstracts in the interface body. */ diff --git a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets index d1fa3f8e04ff9d8e41534acce1e96c1b201221f7..ba846261acb7657783e6b5a2f7dd6235c0baff0e 100644 --- a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets +++ b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets @@ -39,7 +39,7 @@ class Hex extends Core { } } -/* @@? 33:22 Error TypeError: size(s: int): void in Hex cannot override size(s: int): void in Core because overridden method is final. */ -/* @@? 33:22 Error TypeError: Method size(s: int): void in Hex not overriding any method */ -/* @@? 37:22 Error TypeError: size(): int in Hex cannot override size(): int in Core because overridden method is final. */ -/* @@? 37:22 Error TypeError: Method size(): int in Hex not overriding any method */ +/* @@? 33:22 Error TypeError: size(s: Int): void in Hex cannot override size(s: Int): void in Core because overridden method is final. */ +/* @@? 33:22 Error TypeError: Method size(s: Int): void in Hex not overriding any method */ +/* @@? 37:22 Error TypeError: size(): Int in Hex cannot override size(): Int in Core because overridden method is final. */ +/* @@? 37:22 Error TypeError: Method size(): Int in Hex not overriding any method */ 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/getter_setter_modifier_limited.ets b/ets2panda/test/ast/parser/ets/getter_setter_modifier_limited.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb74e1bad8706a07fc92664706f8e14986981059 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/getter_setter_modifier_limited.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 Person { + private _age: number = 0; + async get age(): number { return this._age } +} + +/* @@? 18:11 Error SyntaxError: Modifiers of getter and setter are limited to ('abstract', 'static', 'final', 'override', 'native'). */ diff --git a/ets2panda/test/ast/parser/ets/global_const_vars4.ets b/ets2panda/test/ast/parser/ets/global_const_vars4.ets index f1d3d77aa9e8e3aadeaf80ed5fd67b0e33f99b77..5f80623d78dbe87c53149e547c7bfbc109312df3 100644 --- a/ets2panda/test/ast/parser/ets/global_const_vars4.ets +++ b/ets2panda/test/ast/parser/ets/global_const_vars4.ets @@ -14,17 +14,17 @@ */ class ABC { - public readonly /* @@ label */date: Date = new Date(); + public readonly date: Date = new Date(); constructor() { this.init() } private init(): void { - this.date = new Date(); + /* @@ label */this.date = new Date(); } public main(): void {} } -/* @@@ label Error TypeError: Cannot assign to a readonly variable date */ +/* @@@ label Error TypeError: Cannot assign to a readonly field date */ diff --git a/ets2panda/test/ast/parser/ets/illegal_line_after_throw.ets b/ets2panda/test/ast/parser/ets/illegal_line_after_throw.ets index 92ab4b4dd3c7bd2682db99ba19fc2a783acfc70d..de6228379823b9e17cec897619b56c7e804db3e8 100644 --- a/ets2panda/test/ast/parser/ets/illegal_line_after_throw.ets +++ b/ets2panda/test/ast/parser/ets/illegal_line_after_throw.ets @@ -17,7 +17,7 @@ try { } -catch(e: Error) +catch(e) { } 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 bb8deca84fc0c1f077e448832476e34f002919bd..d49ec5f228f819638682307d1cdb941dc4cde96f 100644 --- a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets @@ -19,7 +19,8 @@ function main(): void { s.toString() let a: int [] = [1, 2] let b = s ?? a; - /* @@ label */b.toString(); + b.toString(); } -/* @@@ label Error TypeError: Type String|int[] is illegal in union member expression. */ + +/* @@@ label Error TypeError: Type String|Int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/import_assertion.ets b/ets2panda/test/ast/parser/ets/import_assertion.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbf4ed4a28bea17c89c9a37aa2acf3f6143bb3bc --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_assertion.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. + */ + +import * as Pt from "mod" /* @@ label1 */assert /* @@ label2 */{ type: /* @@ label3 */"json" } + + +/* @@@ label1 Error SyntaxError: Import assertion is not supported, please use the ordinary import syntax instead! */ +/* @@@ label1 Error TypeError: Unresolved reference assert */ +/* @@@ label2 Error SyntaxError: Unexpected token '{'. */ +/* @@@ label3 Error SyntaxError: Label must be followed by a loop statement. */ diff --git a/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets b/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd2ff3124f685c3e2ecc51514d1e4a27b8f41f38 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.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 {/* @@ label1 */} /* @@ label2 */from /* @@ label3 */'module' + +/* @@@ label1 Error SyntaxError: Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import all objects declared in the module! */ +/* @@@ label2 Error TypeError: Unresolved reference from */ +/* @@@ label3 Error SyntaxError: Unexpected token 'module'. */ diff --git a/ets2panda/test/ast/parser/ets/import_no_side_effect.ets b/ets2panda/test/ast/parser/ets/import_no_side_effect.ets new file mode 100644 index 0000000000000000000000000000000000000000..cd4d80cab0b0de58957e3a3cec521d46be29cc37 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_no_side_effect.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 /* @@ label1 */'module' + +/* @@@ label1 Error SyntaxError: Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import all objects declared in the module! */ diff --git a/ets2panda/test/ast/parser/ets/import_require.ets b/ets2panda/test/ast/parser/ets/import_require.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad8766f57b15aa3ff127e8aa45c4e8fd08d393da --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_require.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 m /* @@ label1 */= /* @@ label2 */require("mod") + +/* @@@ label1 Error SyntaxError: Importing by 'require' and 'import' assignment is not supported, use 'import * as ... from ...' form instead! */ +/* @@@ label1 Error SyntaxError: Unexpected token '='. */ +/* @@@ label2 Error SyntaxError: Unexpected token 'require'. */ +/* @@@ label2 Error TypeError: Unresolved reference require */ 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/imported_module_1.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_1.ets index a9f16400cf3be90c9307b66fc3680b5f13041d88..ca4457f0f6d86f9b7211c95759fb43dc53172b3d 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_1.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_1.ets @@ -33,4 +33,3 @@ export function foo_1_1param(a : int) : int { } export default function foo_1_default() : void {} - diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets index b5508f11e48cfdb60591944353328bb4e1811050..cfbfbd87eddd1d49dff5130aca97e3ae7bf35e2d 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export const flt: float = 2.345; +export const flt: float = 2.345f; export let c: int = 3; diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_type_error_in_class.ets b/ets2panda/test/ast/parser/ets/import_tests/import_type_error_in_class.ets index 664385c11cbebd1d72ccaadabf38741906bb8ba4..eec369a4bf2e44807273ad3c16be2230f6855f20 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_type_error_in_class.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_type_error_in_class.ets @@ -24,4 +24,4 @@ export class InImport { // used to give wrong output: // TypeError: Type '"InImport"' cannot be assigned to type 'int' [export_and_import_class.ets:21:1] -/* @@@ label Error TypeError: Type '"InImport"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"InImport"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_type_error_top_level.ets b/ets2panda/test/ast/parser/ets/import_tests/import_type_error_top_level.ets index 1cf28091f3e6c5e4b35bf7a9c0f0d2e288f192b7..c22d2295148b94bd8bf2cb3b498fdcc5de568761 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_type_error_top_level.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_type_error_top_level.ets @@ -25,4 +25,4 @@ export function fooImport() { // used to give wrong output: // TypeError: Type 'int' cannot be assigned to type 'String' [export_and_import_top_level.ets:21:1] -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/modules/invalid_namespace_import2.ets b/ets2panda/test/ast/parser/ets/import_tests/modules/invalid_namespace_import2.ets new file mode 100644 index 0000000000000000000000000000000000000000..c61d893c63316b0db399820caa14a10e3ba4f4ee --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_tests/modules/invalid_namespace_import2.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 * \u0061s something from "./module" + +/* @@? 16:10 Error SyntaxError: Escape sequences are not allowed in keyword. */ +/* @@? 16:10 Error SyntaxError: Escape sequences are not allowed in 'as' keyword.*/ +/* @@? 16:10 Error SyntaxError: Expected 'as', got 'identification literal'. */ +/* @@? 16:18 Error SyntaxError: Unexpected token, expected 'from'. */ +/* @@? 16:28 Error SyntaxError: Unexpected token, expected string literal. */ +/* @@? 16:33 Error SyntaxError: Unexpected token './module'. */ 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..7cab79843aa6ea29448fdcacdafb4dc6a2275b8f 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,4 @@ export class A {} -export type {A as /* @@ label */AA}; - -/* @@@ label Error SyntaxError: Name 'A' cannot be exported and type exported at the same time. */ +export type {A as AA}; 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..ea9cf69480b354a22de4ce154b6d7bd83b015012 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,6 @@ 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: Cannot export two different names with the same export alias name 'foo'. */ 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 e3b52ed7aeb2e461a67468b93781a1b56ce68a38..76b9878b1c36fbd27e2062fd1970415712d7794a 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,8 @@ */ function main(){ let a = 1; - a/* @@ label */~/* @@ label1 */!/* @@ label2 */; + a/* @@ label */~/* @@ label2 */!/* @@ label3 */; } /* @@@ 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. */ +/* @@@ label2 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@@ label3 Error SyntaxError: Unexpected token ';'. */ 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 975a0fe9468d1ec9432809dcf607e841c59d8adf..8ff53d347d508bb5812c2e703ff534e6949cbfe0 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,6 +18,4 @@ } /* @@? 17:3 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ - /* @@? 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/index_not_support_such_type.ets b/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets index 9e696be3e9e2a2d898f05173c6dea00bcfb8aed2..c713e3133391f444913437cfa2c9202fed1f4723 100644 --- a/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets +++ b/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets @@ -18,4 +18,12 @@ function main() { console.log(/* @@ label */a[0]) } -/* @@@ label Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Boolean): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Byte): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Short): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Char): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Int): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/index_signature_error_1.ets b/ets2panda/test/ast/parser/ets/index_signature_error_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1b35a8935cd1cc2272f60787d375109beb7f69df --- /dev/null +++ b/ets2panda/test/ast/parser/ets/index_signature_error_1.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class StringArray { + [/* @@ label1 */index: number]: string +} +function getStringArray(): StringArray { + return /* @@ label2 */["a", "b", "c"] +} +let myArray: StringArray = getStringArray() +let secondItem = /* @@ label3 */myArray[1] + +/* @@@ label1 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label2 Error TypeError: Type 'Array' is not compatible with the enclosing method's return type 'StringArray' */ +/* @@@ label3 Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/index_signature_error_2.ets b/ets2panda/test/ast/parser/ets/index_signature_error_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..8eee907561bbfa0bce864432ac495e2390222ce0 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/index_signature_error_2.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface StringArray { + /* @@ label1 */[index: number]: string +} +function getStringArray(): StringArray { + return /* @@ label2 */["a", "b", "c"] +} +let myArray: StringArray = getStringArray() +let secondItem = /* @@ label3 */myArray[1] + +/* @@@ label1 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label2 Error TypeError: Type 'Array' is not compatible with the enclosing method's return type 'StringArray' */ +/* @@@ label3 Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/indexed_access_type_1.ets b/ets2panda/test/ast/parser/ets/indexed_access_type_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e61fe1d3fab1458a696e6e22bb016527c4ecfc77 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/indexed_access_type_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. + */ + +type Point = /* @@ label1 */{x: number = 0; y: number = 0} +type N = Point/* @@ label2 */["x"] + +/* @@@ label1 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@@ label2 Error SyntaxError: Indexed access types are not supported, use type name instead! */ diff --git a/ets2panda/test/ast/parser/ets/indexed_access_type_2.ets b/ets2panda/test/ast/parser/ets/indexed_access_type_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..479a44a0de92857745272bd7e96e12be612a355d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/indexed_access_type_2.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 Point {x: number = 0; y: number = 0} +type N = Point/* @@ label */["x"] + +/* @@@ label Error SyntaxError: Indexed access types are not supported, use type name instead! */ diff --git a/ets2panda/test/ast/parser/ets/instanceof_on_type.ets b/ets2panda/test/ast/parser/ets/instanceof_on_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb4b9dcc7b05ba006d5618998dd5107762e997e5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/instanceof_on_type.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 X {} +type B = X + +let a = (new X()) instanceof Object +let b = (new X()) instanceof X +let c = X instanceof Object +let d = X instanceof X +let f = B instanceof Object + +/* @@? 21:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ +/* @@? 22:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ +/* @@? 23:9 Error SyntaxError: The left operand of 'instanceof' operator cannot be a type. */ 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 3e3263a00113b3e4cde7f4b31d4290f7d9a6aa88..3e2f65ca14c6bc0efecfa9dd3ba1bd0e7870adf9 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 @@ -24,5 +24,4 @@ function main() b instanceof /* @@ label */a } -/* @@@ label Error TypeError: Cannot find type 'a'. */ -/* @@? 24:5 Error TypeError: Using the 'instance of' operator with non-object type 'b' */ +/* @@@ label Error TypeError: Cannot find type 'a'. */ 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_indexer_2.ets b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets index b8e57b5856ace9265904051f4df6c40303349890..6789f5f0985c114f39be7b3b0aaff4afdb74a515 100644 --- a/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets +++ b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets @@ -17,4 +17,15 @@ declare interface A { [index : string]: string } -/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ \ No newline at end of file +/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: ] expected in index signature. */ +/* @@? 17:20 Error SyntaxError: An index signature must have a type annotation. */ +/* @@? 17:20 Error SyntaxError: Expected ':', got ']'. */ +/* @@? 17:20 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:21 Error SyntaxError: Identifier expected. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Invalid Type. */ 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_extends_class.ets b/ets2panda/test/ast/parser/ets/interface_extends_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..6e88716f0c466a20fc1b95f31c4989e730b5f135 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_extends_class.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 {} + +interface BInterface extends /* @@ label */A {} + +/* @@@ label Error TypeError: Interfaces cannot extend classes, only other interfaces. */ 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 index d18aff410856f2183deefcae726070359e924d78..692ad1e69d4ade9781d63df8f98de9e965764e3d 100644 --- a/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets @@ -14,17 +14,16 @@ */ b: Geit { - t { - name(): + t {name(): - interface I { - readonly: boolean - } - inter +interface I { + readonly : boolean +} +inter - class A implements I { - reanstructor() { - this.a = f�ls +class A implements I { + reanstructor() { + this.a = f�ls s A { @ constructor() { this.a = ruO; @@ -38,41 +37,27 @@ function mdin() { let a = new A(); /* @@? 16:9 Error SyntaxError: Unexpected token '{'. */ /* @@? 17:2 Error TypeError: Unresolved reference t */ /* @@? 17:4 Error SyntaxError: Unexpected token '{'. */ -/* @@? 18:9 Error TypeError: Unresolved reference name */ -/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ':'. */ -/* @@? 21:13 Error SyntaxError: Identifier expected. */ -/* @@? 21:21 Error SyntaxError: Unexpected token, expected ','. */ -/* @@? 21:21 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ -/* @@? 21:23 Error SyntaxError: Identifier expected. */ -/* @@? 21:23 Error SyntaxError: Unexpected token, expected ','. */ -/* @@? 21:23 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ -/* @@? 22:9 Error SyntaxError: Identifier expected. */ -/* @@? 23:9 Error TypeError: Class literal is not yet supported. */ -/* @@? 23:9 Error TypeError: Cannot find type 'inter'. */ -/* @@? 25:15 Error SyntaxError: Unexpected token 'A'. */ -/* @@? 25:15 Error TypeError: Unresolved reference A */ -/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ -/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ -/* @@? 25:17 Error SyntaxError: Unexpected token 'implements'. */ -/* @@? 25:28 Error TypeError: Interface name 'I' used in the wrong context */ -/* @@? 25:30 Error SyntaxError: Unexpected token '{'. */ -/* @@? 26:13 Error TypeError: Unresolved reference reanstructor */ -/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 27:27 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 27:27 Error SyntaxError: Unexpected token '�ls'. */ -/* @@? 28:5 Error SyntaxError: Unexpected token 'A'. */ -/* @@? 28:7 Error SyntaxError: Unexpected token '{'. */ -/* @@? 29:5 Error SyntaxError: Identifier expected, got 'constructor'. */ -/* @@? 29:19 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 30:18 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 32:2 Error SyntaxError: Unexpected token '*'. */ -/* @@? 33:1 Error SyntaxError: Nested functions are not allowed. */ -/* @@? 33:1 Error SyntaxError: Unexpected token 'function'. */ -/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 78:60 Error SyntaxError: Expected '}', got 'eos'. */ \ No newline at end of file +/* @@? 17:5 Error TypeError: Unresolved reference name */ +/* @@? 17:11 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:1 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@? 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: Unresolved reference inter */ +/* @@? 24:1 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 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:5 Error SyntaxError: Hard keyword 'constructor' cannot be used as identifier */ +/* @@? 28:16 Error SyntaxError: Invalid annotation name. */ +/* @@? 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. */ +/* @@? 64: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 index bc6fdafb255e9d9312597951e21c00fa6b0074a1..b2f0dcd0902a63a54ab92a8ad400b76ac841b95e 100644 --- a/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets @@ -21,4 +21,4 @@ interface I { /* @@? 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. */ \ No newline at end of file +/* @@? 18:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/interface_private_function_1.ets b/ets2panda/test/ast/parser/ets/interface_private_function_1.ets index 3cc0073acd988bfd2606399253a76758ee25c5fc..237953a6ba7a66ef171a478631257c2135070422 100644 --- a/ets2panda/test/ast/parser/ets/interface_private_function_1.ets +++ b/ets2panda/test/ast/parser/ets/interface_private_function_1.ets @@ -34,5 +34,5 @@ function main(): void { i.xyz(); } -/* @@? 34:5 Error TypeError: Signature xyz(): int is not visible here. */ -/* @@? 34:5 Error TypeError: No matching call signature */ +/* @@? 34:5 Error TypeError: Signature xyz(): Int is not visible here. */ +/* @@? 34:5 Error TypeError: No matching call signature */ 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/intersection_types.ets b/ets2panda/test/ast/parser/ets/intersection_types.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b7cdb919c87bc4a25acac934401a32628531162 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/intersection_types.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 Identity { + id: number + name: string +} + +interface Contact { + email: string + phoneNumber: string +} + +type Employee = Identity & Contact + +/* @@? 26:28 Error SyntaxError: Intersection types are not supported, use inheritance instead! */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/invalidEnums.ets b/ets2panda/test/ast/parser/ets/invalidEnums.ets index 3da156a85b38017714d4e7cf6f66e4388d66129a..82a8b213907bcb988ec02f600c8fb54fa4dba0d2 100644 --- a/ets2panda/test/ast/parser/ets/invalidEnums.ets +++ b/ets2panda/test/ast/parser/ets/invalidEnums.ets @@ -60,19 +60,15 @@ 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 '}'. */ -/* @@? 37:10 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 37:10 Error SyntaxError: Invalid enum initialization value */ +/* @@? 32:1 Error SyntaxError: Unexpected token ']'. */ +/* @@? 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 276d27a280f2e44f04784445b96494c1663a1514..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 SyntaxError: Unexpected token 'int'. */ -/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 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 index 3299f8885389ef4d5a5c26439619ab6311c9b31b..b50d888aa835aed8c672a273c58d4cf8fe9cce72 100644 --- a/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets +++ b/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets @@ -20,16 +20,15 @@ /* @@? 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: Unexpected token, expected '=>'. */ -/* @@? 16:44 Error SyntaxError: Invalid Type. */ -/* @@? 16:46 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 16:46 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:46 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:46 Error SyntaxError: Invalid Type. */ /* @@? 16:48 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:66 Error SyntaxError: Unexpected token ')'. */ /* @@? 16:68 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:70 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets b/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets new file mode 100644 index 0000000000000000000000000000000000000000..826c56c07631a8182f7951235a6da189dc5de897 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const f = ({a: 1}) => {} + +/* @@? 16:20 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 16:20 Error SyntaxError: Invalid destructuring assignment target. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_lambda_parameter.ets b/ets2panda/test/ast/parser/ets/invalid_lambda_parameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc163f36e8b8b9c6a40666d4abb9f49c388ab318 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_lambda_parameter.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 {} +class A { + constructor(callback: (entries: I[]) => void) {} +} + +function foo(entry: I) { + const x = new A(/* @@ label1 */([entry]) /* @@ label2 */=> { + }); +} + +/* @@@ label1 Error TypeError: Invalid lambda parameter. Expected: 'identifier(: type)?', 'identifier?(: type)?' or '...identifier(: type)?'. */ +/* @@@ label2 Error SyntaxError: Unexpected token '=>'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_object_expression.ets b/ets2panda/test/ast/parser/ets/invalid_object_expression.ets new file mode 100644 index 0000000000000000000000000000000000000000..16850eb68271070dc0fd7ae73e2865ee262847c3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_object_expression.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 obj: Record = { + [this.viewModel.ads] : 123 +} + +/* @@? 18:5 Error SyntaxError: Unexpected token. */ +/* @@? 18:6 Error SyntaxError: Unexpected token. */ +/* @@? 18:6 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 18:11 Error TypeError: Property 'viewModel' does not exist on type 'ETSGLOBAL' */ +/* @@? 18:24 Error SyntaxError: Unexpected token. */ +/* @@? 18:26 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:28 Error SyntaxError: Unexpected token '123'. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_punctuator_format.ets b/ets2panda/test/ast/parser/ets/invalid_punctuator_format.ets new file mode 100644 index 0000000000000000000000000000000000000000..2eba0019b69d4a8da790cfad2bc98cd8fa23d3cc --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_punctuator_format.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 { +J* @@? +} + +/* @@? 17:2 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 17:4 Error SyntaxError: Unexpected token '@@'. */ +/* @@? 17:4 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:4 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:6 Error SyntaxError: Identifier expected. */ +/* @@? 17:6 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:6 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_recursive_generic_union_type.ets b/ets2panda/test/ast/parser/ets/invalid_recursive_generic_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbe7b44619d089abe9afdc7f092b9894a39d2a67 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_recursive_generic_union_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. + */ + +// Recursive generic union type test case migrated for ArkTS 1.2 + +// ArkTS does not support recursive type aliases or type declarations inside namespaces. +// We flatten the structure and define types globally to avoid unsupported features. + +type Container = T | { [i: string]: Container }; + +declare namespace Test1 { +} + +/* @@? 21:25 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 21:28 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 21:49 Error SyntaxError: Unexpected token '<'. */ +/* @@? 21:51 Error SyntaxError: Field type annotation expected. */ +/* @@? 21:51 Error SyntaxError: Unexpected token '>'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_syntax_in_object_literal.ets b/ets2panda/test/ast/parser/ets/invalid_syntax_in_object_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..11b608f9bcec649f98413bc81fab1a948510360d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_syntax_in_object_literal.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 a2: A2 = { + value: { + 'bbb': 222 / '. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets index d270acffb05684b31d748822d4fb95c3509dcd62..814b8ad67da037693c17f0a3aeb06aef2da51219 100644 --- a/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets +++ b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets @@ -20,15 +20,5 @@ 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:23 Error SyntaxError: Unexpected token ']'. */ -/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ -/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ -/* @@? 21:26 Error SyntaxError: Unexpected token ']'. */ -/* @@? 21:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 20:18 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 21:22 Error SyntaxError: Indexed access types are not supported, use type name instead! */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/keyof_annotation.ets b/ets2panda/test/ast/parser/ets/keyof_annotation.ets index 48584e69539a85e39aba5f429a16b001ca5835bc..4e64a018dd677e97b8e50ef5dbe93ceae4a751ad 100644 --- a/ets2panda/test/ast/parser/ets/keyof_annotation.ets +++ b/ets2panda/test/ast/parser/ets/keyof_annotation.ets @@ -41,10 +41,9 @@ function main():void{ let y6:keyof B = /* @@ label6 */100; } -/* @@@ label1 Error TypeError: Type '"other field"' cannot be assigned to type '"method1"|"field1"|"field2"' */ -/* @@@ label2 Error TypeError: Type '"other method"' cannot be assigned to type '"method1"|"field1"|"field2"' */ -/* @@@ label3 Error TypeError: Type 'int' cannot be assigned to type '"method1"|"field1"|"field2"' */ -/* @@@ label4 Error TypeError: Type '"other field"' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ -/* @@@ label5 Error TypeError: Type '"other method"' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ -/* @@@ label6 Error TypeError: Type 'int' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ - +/* @@@ label1 Error TypeError: Type '"other field"' cannot be assigned to type '"method1"|"field1"|"field2"' */ +/* @@@ label2 Error TypeError: Type '"other method"' cannot be assigned to type '"method1"|"field1"|"field2"' */ +/* @@@ label3 Error TypeError: Type 'Int' cannot be assigned to type '"method1"|"field1"|"field2"' */ +/* @@@ label4 Error TypeError: Type '"other field"' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ +/* @@@ label5 Error TypeError: Type '"other method"' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ +/* @@@ label6 Error TypeError: Type 'Int' cannot be assigned to type '"bmethod1"|"bfield1"|"bfield2"|"method1"|"field1"|"field2"' */ diff --git a/ets2panda/test/ast/parser/ets/keyof_applied_to_other.ets b/ets2panda/test/ast/parser/ets/keyof_applied_to_other.ets index 463724fb6127e3e03a2e90b7dc01b8aff54b62e0..d2585f5f7eab9b569f71c08a56b5f68481496fe5 100644 --- a/ets2panda/test/ast/parser/ets/keyof_applied_to_other.ets +++ b/ets2panda/test/ast/parser/ets/keyof_applied_to_other.ets @@ -22,20 +22,19 @@ class A{ function foo(){} function main():void{ - type UnionA = A|string|undefined - type keyofUnion = keyof /* @@ label1 */unionA/* @@ label2 */; + /* @@ label1 */type UnionA = A|string|undefined + /* @@ label2 */type keyofUnion = keyof unionA; - type keyofNever = keyof never/* @@ label3 */; + /* @@ label3 */type keyofNever = keyof never; - type keyofFunction = keyof /* @@ label4 */foo/* @@ label5 */; + /* @@ label4 */type keyofFunction = keyof foo; - type keyofVoid = keyof /* @@ label6 */void/* @@ label7 */; + /* @@ label5 */ type keyofVoid = keyof void; } -/* @@@ label1 Error TypeError: Cannot find type 'unionA'. */ -/* @@@ label2 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ -/* @@@ label3 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ -/* @@@ label4 Error TypeError: Cannot find type 'foo'. */ -/* @@@ label5 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ -/* @@@ label6 Error TypeError: 'void' used as type annotation. */ -/* @@@ label7 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@@ label1 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label2 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label3 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label4 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label5 Error SyntaxError: Illegal start of Type Alias expression. */ + diff --git a/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets b/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets index f4ffe47cc65d9f16ad447f6345c47c4dfa8e2f42..682e4caa7326d503c0fbe17c2a0ad83fc78ed20d 100644 --- a/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets +++ b/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets @@ -13,29 +13,31 @@ * limitations under the License. */ -class A{ - field1:number = 10; - private field2:number = 20; - foo(){} +class A { + field1: number = 10; + private field2: number = 20; + foo() { } } -function main():void{ - let a:A = new A(); +function main(): void { + let a: A = new A(); type keyofA = keyof A; - let x1:("abcd"|keyofA|number|A)[] = ["abcd",/* @@ label1 */"field2","foo",123,a]; - let x2:("abcd"|keyofA|number|A)[] = ["abcd",/* @@ label2 */"other field","foo",123,a]; + let x1: ("abcd" | keyofA | number | A)[] = ["abcd", "field2", "foo", 123, a]; + let x2: ("abcd" | keyofA | number | A)[] = ["abcd", "other field", "foo", 123, a]; - let x3:["abcd",keyofA,number,A] = ["abcd",/* @@ label3 */"field2",123,a]; - let x4:["abcd",keyofA,number,A] = ["abcd",/* @@ label4 */"other field",123,a]; + let x3: ["abcd", keyofA, number, A] = ["abcd", "field2", 123, a]; + let x4: ["abcd", keyofA, number, A] = ["abcd", "other field", 123, a]; - let x5:Array<"abcd"|keyofA|number|A> = /* @@ label5 */new Array<"abcd"|keyofA|number|A>("abcd","field2","foo",123,a); - let x6:Array<"abcd"|keyofA|number|A> = /* @@ label6 */new Array<"abcd"|keyofA|number|A>("abcd","other field","foo",123,a); + let x5: Array<"abcd" | keyofA | number | A> = new Array<"abcd" | keyofA | number | A>("abcd", "field2", "foo", 123, a); + let x6: Array<"abcd" | keyofA | number | A> = 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) */ +/* @@? 1:3 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 24:3 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 29:20 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 30:20 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 32:26 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 32:68 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 33:26 Error TypeError: Cannot find type 'keyofA'. */ +/* @@? 33:68 Error TypeError: Cannot find type 'keyofA'. */ diff --git a/ets2panda/test/ast/parser/ets/keyof_constraint.ets b/ets2panda/test/ast/parser/ets/keyof_constraint.ets index b3265d6059e936d087bce74e9ee3de3c85320853..ed208c3516b71adf4ed70bfc607134a90356aff4 100644 --- a/ets2panda/test/ast/parser/ets/keyof_constraint.ets +++ b/ets2panda/test/ast/parser/ets/keyof_constraint.ets @@ -30,6 +30,6 @@ function main():void{ /* @@ label2 */getProperty(/* @@ label3 */"field12345"); } -/* @@@ label1 Error TypeError: Type "field12345" is not assignable to constraint type "method1"|"field1"|"field2" */ +/* @@@ label1 Error TypeError: Type argument '"field12345"' should be a subtype of '"method1"|"field1"|"field2"'-constraint */ /* @@@ label2 Error TypeError: No matching call signature for getProperty("field12345") */ /* @@@ label3 Error TypeError: Type '"field12345"' is not compatible with type '"method1"|"field1"|"field2"' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/keyof_parameter.ets b/ets2panda/test/ast/parser/ets/keyof_parameter.ets index 2eeb874a71e1ee2c15b9c9ebbaef9fa661b4716f..5d3c9af6412b7c082545ea040f81108d3df6c407 100644 --- a/ets2panda/test/ast/parser/ets/keyof_parameter.ets +++ b/ets2panda/test/ast/parser/ets/keyof_parameter.ets @@ -28,9 +28,9 @@ function main():void{ /* @@ label5 */getProperty(a, /* @@ label6 */1); } -/* @@@ label1 Error TypeError: No matching call signature for getProperty(A, "other field") */ -/* @@@ label2 Error TypeError: Type '"other field"' is not compatible with type '"method1"|"field1"|"field2"' at index 2 */ -/* @@@ label3 Error TypeError: No matching call signature for getProperty(A, "other method") */ -/* @@@ label4 Error TypeError: Type '"other method"' is not compatible with type '"method1"|"field1"|"field2"' at index 2 */ -/* @@@ label5 Error TypeError: No matching call signature for getProperty(A, int) */ -/* @@@ label6 Error TypeError: Type 'int' is not compatible with type '"method1"|"field1"|"field2"' at index 2 */ \ No newline at end of file +/* @@@ label1 Error TypeError: No matching call signature for getProperty(A, "other field") */ +/* @@@ label2 Error TypeError: Type '"other field"' is not compatible with type '"method1"|"field1"|"field2"' at index 2 */ +/* @@@ label3 Error TypeError: No matching call signature for getProperty(A, "other method") */ +/* @@@ label4 Error TypeError: Type '"other method"' is not compatible with type '"method1"|"field1"|"field2"' at index 2 */ +/* @@@ label5 Error TypeError: No matching call signature for getProperty(A, Int) */ +/* @@@ label6 Error TypeError: Type 'Int' is not compatible with type '"method1"|"field1"|"field2"' 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..ceb6c262362bcecd9b9b97df63180c41e0a59c7c 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"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"add"|"toByte"|"floatValue"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"add"|"toByte"|"floatValue"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ diff --git a/ets2panda/test/ast/parser/ets/keyof_smartcast.ets b/ets2panda/test/ast/parser/ets/keyof_smartcast.ets index 81488e4cfedbf611068cc0b9689011d2b7cf7693..22ef6be9d47e999162b7a1de9dd4e544d9f82dbf 100644 --- a/ets2panda/test/ast/parser/ets/keyof_smartcast.ets +++ b/ets2panda/test/ast/parser/ets/keyof_smartcast.ets @@ -21,13 +21,13 @@ class A{ function foo(c: (keyof A)|"abcd"|A|undefined): string { if (c instanceof (keyof A)) { - assertEQ(c, "field1") + arktest.assertEQ(c, "field1") return "Case 1"; } else if (c instanceof "abcd") { - assertEQ(c, "abcd") + arktest.assertEQ(c, "abcd") return "Case 2"; } else if (c instanceof A) { - assertEQ(c.field1, 0) + arktest.assertEQ(c.field1, 0) return "Case 3"; } else { return "Case 4"; diff --git a/ets2panda/test/ast/parser/ets/keyof_union.ets b/ets2panda/test/ast/parser/ets/keyof_union.ets index 1708334bb45610966a5e31b9336861d45d320bda..fa9733238e5ae382a474890b6380ed92b56cdb33 100644 --- a/ets2panda/test/ast/parser/ets/keyof_union.ets +++ b/ets2panda/test/ast/parser/ets/keyof_union.ets @@ -24,18 +24,18 @@ function getProperty(key: K){} function main():void{ let a:A = new A(); - type keyofA = keyof A; - type keyofUnion = keyofA|number|A; - let x1:keyofUnion = /* @@ label1 */"foo2"; - let x2:keyofUnion = /* @@ label2 */"other field"; + /* @@ label1 */type keyofA = keyof A; + /* @@ label2 */type keyofUnion = keyofA|number|A; + let x1:/* @@ label3 */keyofUnion = "foo2"; + let x2:/* @@ label4 */keyofUnion = "other field"; - /* @@ label3 */getProperty(/* @@ label4 */"foo2") - /* @@ label5 */getProperty(/* @@ label6 */"other field") + getProperty("foo2") + getProperty("other field") } -/* @@@ label1 Error TypeError: Type '"foo2"' cannot be assigned to type 'Double|A|"foo"|"field1"' */ -/* @@@ label2 Error TypeError: Type '"other field"' cannot be assigned to type 'Double|A|"foo"|"field1"' */ -/* @@@ label3 Error TypeError: No matching call signature for getProperty("foo2") */ -/* @@@ label4 Error TypeError: Type '"foo2"' is not compatible with type '"foo"|"field1"' at index 1 */ -/* @@@ label5 Error TypeError: No matching call signature for getProperty("other field") */ -/* @@@ label6 Error TypeError: Type '"other field"' is not compatible with type '"foo"|"field1"' at index 1 */ +/* @@@ label1 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label2 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label3 Error TypeError: Cannot find type 'keyofUnion'. */ +/* @@@ label4 Error TypeError: Cannot find type 'keyofUnion'. */ +/* @@@ label5 Error TypeError: Cannot find type 'keyofA'. */ +/* @@@ label6 Error TypeError: Cannot find type 'keyofA'. */ 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/parser/ets/class_interface_enum_only_top_level_4.ets b/ets2panda/test/ast/parser/ets/labelled_for_of.ets similarity index 84% rename from ets2panda/test/parser/ets/class_interface_enum_only_top_level_4.ets rename to ets2panda/test/ast/parser/ets/labelled_for_of.ets index 75d8981a525476173a26d6c839d300e63dd58e06..882614cc8d9da10302208bec0ef343e56a12aa09 100644 --- a/ets2panda/test/parser/ets/class_interface_enum_only_top_level_4.ets +++ b/ets2panda/test/ast/parser/ets/labelled_for_of.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -function main() : void -{ - interface C { - foo(a: int): int; - } +function foo(){ + let arr1: int[] = [0,1,2] + loop1: for(let y of arr1){ + continue loop1; + } } 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/lambda-type-inference-neg.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets index c4248319400c6dca88a18040e725e3e3e3dc5329..75cc29a9124eff1f602cb0e682834e350602fbaf 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets @@ -20,10 +20,9 @@ function foo(callback: (x: boolean) => void): void { } function main(): void { - /* @@ label1 */foo((x) => { + foo((x) => { }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets index fbeb2cd8c74436edabc0350a32bdf2d7a302a3cc..be682f7d2f1445a16670690f5652e3df7f3f69f3 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets @@ -29,10 +29,11 @@ function main(): void { return y.length == x; }); // Should report an error - /* @@ label1 */foo((x, y) => { + foo((x, y) => /* @@ label1 */{ console.println("hello"); }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ +/* @@@ label1 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Boolean' */ +/* @@? 28:9 Error TypeError: Type '(x: Double, y: String) => Boolean' is not compatible with type '(x: Int, y: String) => Boolean' at index 1 */ 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..ef855e4383289ea8bafca7f8b23a5ab6e6c9ae1e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_function_index_access_neg.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 = (... ( () => { + +})) = : async () => { + +} [] + +/* @@? 16:9 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:10 Error SyntaxError: Unexpected token '...'. */ +/* @@? 16:10 Error TypeError: This expression is not callable. */ +/* @@? 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_infer_type_neg_1.ets b/ets2panda/test/ast/parser/ets/lambda_infer_type_neg_1.ets index 3d935ede822f67018005845d044aa51a48a4a74a..8e962a727f14fa5ea0e4c5c4a49b3985d125e7e3 100644 --- a/ets2panda/test/ast/parser/ets/lambda_infer_type_neg_1.ets +++ b/ets2panda/test/ast/parser/ets/lambda_infer_type_neg_1.ets @@ -16,5 +16,5 @@ let lam :(x:string, y:int) => void = (a,b) =>{} lam(2, 3) -/* @@? 17:1 Error TypeError: No matching call signature for (int, int) */ -/* @@? 17:5 Error TypeError: Type 'int' is not compatible with type 'String' at index 1 */ \ No newline at end of file +/* @@? 17:1 Error TypeError: No matching call signature for (Int, Int) */ +/* @@? 17:5 Error TypeError: Type 'Int' is not compatible with type 'String' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_1.ets b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e61d3b64e18f2ae1fdbf8dd176330282ad870078 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_1.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. + */ + +let fn = ( + str1: String, + str2: String, + str3: String, + str4: String, + str5: String, + str6: String, + str7: String, + str8: String, + str9: String, + str10: String, + str11: String, + str12: String, + str13: String, + str14: String, + str15: String, + str16: String, + str17: String, + str18: String +): void => { }; + + +function main(): void { + fn("hello", "world", "!", "!", "!", "!", "!", "!", "!"); +} + +/* @@? 39:4 Error TypeError: Expected 18 arguments, got 9. */ +/* @@? 39:4 Error TypeError: No matching call signature for ("hello", "world", "!", "!", "!", "!", "!", "!", "!") */ diff --git a/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_2.ets b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..74e21ab03d5558bbf38dbb1531d60a689c876d47 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_2.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. + */ + +let fn = ( + str1: String, + str2: String, + str3: String, + str4: String, + str5: String, + str6: String, + str7: String, + str8: String, + str9: String, + str10: String, + str11: String, + str12: String, + str13: String, + str14: String, + str15: String, + str16: String, + str17: String, + str18: String +): void => { }; + + +function main(): void { + fn("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"); +} + +/* @@? 39:4 Error TypeError: Expected 18 arguments, got 23. */ +/* @@? 39:4 Error TypeError: No matching call signature for ("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!") */ diff --git a/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_3.ets b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..20dbdd881835be56fa509ea3fd69eeb28e5e0779 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_3.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. + */ + +let fn = ( + str1: String, + str2: String, + str3: String, + str4: String, + str5: String, + str6: String, + str7: String, + str8: String, + str9: String, + str10: String, + str11: String, + str12: String, + str13: String, + str14: String, + str15: String, + str16: String, + str17?: String +): void => { }; + + +function main(): void { + fn("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"); +} + +/* @@? 38:4 Error TypeError: Expected 16 arguments, got 18. */ +/* @@? 38:4 Error TypeError: No matching call signature for ("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!") */ diff --git a/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_4.ets b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..57d60ac87968e7cfe94451d0a83aaf3642e33e76 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_4.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. + */ + +let fn = ( + str1: String, + str2: String, + str3: String, + str4: String, + str5: String, + str6: String, + str7: String, + str8: String, + str9: String, + str10: String, + str11: String, + str12: String, + str13: String, + str14: String, + str15: String, + str16: String, + str17?: String +): void => { }; + + +function main(): void { + fn("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"); +} + +/* @@? 38:4 Error TypeError: Expected 16 arguments, got 15. */ +/* @@? 38:4 Error TypeError: No matching call signature for ("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!") */ diff --git a/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_5.ets b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c97a6f8c33f3c0dffa2bb401e2ca78bd87957a6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_n/lambda_n_too_many_arg_neg_5.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. + */ + +let fn = ( + str1: String, + str2: String, + str3: String, + str4: String, + str5: String, + str6: String, + str7: String, + str8: String, + str9: String, + str10: String, + str11: String, + str12: String, + str13: String, + str14: String, + str15: String, + str16: String, + str17: String, + ...restStr: String[] +): void => { }; + +function main(): void { + fn("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"); +} + +/* @@? 38:4 Error TypeError: Expected 17 arguments, got 15. */ +/* @@? 38:4 Error TypeError: No matching call signature for ("hello", "world", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!") */ 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_parameter_neg_3.ets b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets index 9cf0b75d2cfad8acfe0abd9293b1ce7d0881c13f..eac89534ee468e652cb85bd7f0aa99ccc175ceb7 100644 --- a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets +++ b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets @@ -16,4 +16,4 @@ function func(fn:(x:int)=>string){} func((x)=>1) -/* @@? 17:11 Error TypeError: Type 'int' is not compatible with the enclosing method's return type 'String' */ \ No newline at end of file +/* @@? 17:11 Error TypeError: Type 'Int' is not compatible with the enclosing method's return type 'String' */ 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 b4952f183a6ea6613685d702d4608330a6ec312b..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,9 +16,4 @@ let a: int => void /* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ /* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/lambda_type_parameter_neg.ets b/ets2panda/test/ast/parser/ets/lambda_type_parameter_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..27a6cc326f8b80b5fa3cab609483ebb8b12b36ce --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_type_parameter_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 = Int>(reader); + +/* @@? 16:14 Error SyntaxError: Identifier expected, got '('. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 16:15 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 16:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:17 Error SyntaxError: Unexpected token '=>'. */ diff --git a/ets2panda/test/ast/parser/ets/lexer003.ets b/ets2panda/test/ast/parser/ets/lexer003.ets new file mode 100644 index 0000000000000000000000000000000000000000..6e9900937bba4668ec5615a8ec6df2a61ba96918 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lexer003.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. + */ + +/* @@? 24:1 Error SyntaxError: Unexpected token, expected '`'. */ +/* @@? 24:4 Error TypeError: Unresolved reference message */ +/* @@? 24:15 Error SyntaxError: Unterminated string. */ +/* @@? 24:19 Error SyntaxError: Unterminated string. */ +/* @@? 24:19 Error SyntaxError: Unexpected token, expected '${' or '`' */ +/* @@? 24:19 Error SyntaxError: Unexpected token, expected '`'. */ +/* @@? 24:19 Error SyntaxError: Expected '}', got 'end of stream'. */ + +`${message ?? 'ver \ 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/lexical_dec_not_allowed.ets similarity index 69% rename from ets2panda/test/ast/parser/ets/single_export/single_export_default_lambda.ets rename to ets2panda/test/ast/parser/ets/lexical_dec_not_allowed.ets index 1249a99832f29fdd14aae99219b350a0c88b274b..afbd9e8ed337000759d3d2d5d69ab65bbfbb06c5 100644 --- a/ets2panda/test/ast/parser/ets/single_export/single_export_default_lambda.ets +++ b/ets2panda/test/ast/parser/ets/lexical_dec_not_allowed.ets @@ -13,6 +13,8 @@ * limitations under the License. */ -export default /* @@ label */(a: int) => { return a } +while(true) function a (){}; -/* @@@ label Error SyntaxError: Export is allowed only for declarations. */ +/* @@? 16:13 Error SyntaxError: Nested functions are not allowed. */ +/* @@? 16:13 Error SyntaxError: Lexical declaration is not allowed in single statement context. */ +/* @@? 16:28 Error SyntaxError: Missing body in while statement */ diff --git a/ets2panda/test/ast/parser/ets/literals/float-literal_neg.ets b/ets2panda/test/ast/parser/ets/literals/float-literal_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d43515b3f14c29aca49f291d8fd92978bd256b6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/literals/float-literal_neg.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 decimalPointMissing = /* @@ label1 */0f +let decimalPointMissing2 = -/* @@ label2 */100f +let floatMAX = 3.4028235e+38f +let moreThanFloatMAX = /*@@ label3 */3.4028236e+38f + +/* @@@ label1 Error SyntaxError: Invalid number. */ +/* @@@ label2 Error SyntaxError: Invalid number. */ +/* @@@ label3 Error SyntaxError: Invalid number. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets index 43fd173a70806341c2c6dba8e55ba85729f4fdb8..2e523713b2080beba4c86bf6aa4ad7eaf19494b3 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets @@ -17,7 +17,8 @@ function foo() { class LocalClass { - /* @@ label */private property : int; + private property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets index 00c1422a83f5f616a574f7345426b4cc5922af6a..85dd9b2df4b39df25c45c2a629111e36230be502 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets @@ -17,8 +17,8 @@ function foo() { class LocalClass { - /* @@ label */private method() : void; + private method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:37 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets index 4091ddc869119bc3a1e8b189251605bea1daf63f..2e7a15b76051b8dd1bdc1babcbc6682660346392 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets @@ -17,7 +17,9 @@ function foo() { class LocalClass { - /* @@ label */protected property : int; + protected property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets index 3d9cee80d4b667ac1d9f2a21d7d344f12da85fa6..a320b25eb813baf3968b63b10c40eea7e582ce34 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets @@ -17,8 +17,9 @@ function foo() { class LocalClass { - /* @@ label */protected method() : void; + protected method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:39 Error TypeError: Only abstract or native methods can't have body. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets index 815ca264d023521421c5c7edcd8c10cab75d1bad..3b55135eb716a90729f5673ded62a3358b8da8ca 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets @@ -17,7 +17,8 @@ function foo() { class LocalClass { - /* @@ label */public property : int; + public property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets index d04ccf89ed5efacf4becfa5ace585314df6a16da..5bf531cf9fa4fca5def0c8b9b03321b2ba0f860b 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets @@ -17,8 +17,9 @@ function foo() { class LocalClass { - /* @@ label */public method() : void; + public method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:36 Error TypeError: Only abstract or native methods can't have body. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-enum.ets b/ets2panda/test/ast/parser/ets/local-enum.ets new file mode 100644 index 0000000000000000000000000000000000000000..2e3a21b49c2cfbf661f330b8c092f0c1b7db522a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/local-enum.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 A { + /* @@ label */enum E { + C + } +} + +/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ diff --git a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private1.ets b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private1.ets index 6a6186266b252947f343039e587b450c7a5fd198..490354a6199008db14aa92835199ca3b07a7e537 100644 --- a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private1.ets +++ b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private1.ets @@ -15,10 +15,11 @@ function foo() { - interface LocalInterface + /* @@ label1 */interface LocalInterface { - /* @@ label */private property : int; + /* @@ label2 */private property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@@ label1 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label2 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private2.ets b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private2.ets index 1083684e90c401c4f02826620138ba1bdee9c1ad..7f76e7b9909c883eb60e5618fdb2761c6edf2a5b 100644 --- a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private2.ets +++ b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-private2.ets @@ -15,10 +15,12 @@ function foo() { - interface LocalInterface + /* @@ label1 */interface LocalInterface { - /* @@ label */private method/* @@ label1 */() : void; + /* @@ label2 */private method/* @@ label3 */() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@@ label1 Error SyntaxError: Private interface methods must have body. */ + +/* @@@ label1 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label2 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@@ label3 Error SyntaxError: Private interface methods must have body. */ diff --git a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-protected1.ets b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-protected1.ets index 915df139ae7012d300941e4659766ef54fc6ec63..af6da8fe3b1d6a352b72da013ebc13ff4dfa389d 100644 --- a/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-protected1.ets +++ b/ets2panda/test/ast/parser/ets/local-interface-member-access-modifier-protected1.ets @@ -15,10 +15,11 @@ function foo() { - interface LocalInterface + /* @@ label1 */interface LocalInterface { - /* @@ label */protected property : int; + /* @@ label2 */protected property : int; } } -/* @@@ label Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@@ label1 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label2 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/ast/parser/ets/localTypeAlias_n.ets b/ets2panda/test/ast/parser/ets/localTypeAlias_n.ets index 9022a354c4b1d193005c579afa2b152f23dce4f6..fb98c611cf72e82dabf52ed5b9d8b9d8a005000b 100644 --- a/ets2panda/test/ast/parser/ets/localTypeAlias_n.ets +++ b/ets2panda/test/ast/parser/ets/localTypeAlias_n.ets @@ -14,9 +14,10 @@ */ function main(): void { - type a = Double; + /* @@ label1 */type a = Double; } -let outA : /* @@ label */a; +let outA : /* @@ label2 */a; -/* @@@ label Error TypeError: Cannot find type 'a'. */ +/* @@@ label1 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@@ label2 Error TypeError: Cannot find type 'a'. */ 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..3bfff8e7d3288fbea0c3a9f4ec5a33df29683023 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. */ +/* @@? 17:3 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_already_interface.ets b/ets2panda/test/ast/parser/ets/local_class_already_interface.ets index d7deaccf10461ce84259c621e2f520c70c6bb36d..64e86ea35fe8bc56389b747d4ac8285a438e4797 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. */ +/* @@? 17:3 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@? 20:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_already_variable.ets b/ets2panda/test/ast/parser/ets/local_class_already_variable.ets index f336717b7414f212bb40a3fcdb2d165aa2f634d2..c784418b2ce2170e9025b84e7b9455a1616f46cb 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,4 @@ function bar(): void { } } -/* @@? 18:9 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 18:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets b/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets index c81cd8a8b239834ba78f629234d4c72f04608d0f..7ae5c158dfa2c47475619c403868faad995102e6 100644 --- a/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets +++ b/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets @@ -49,13 +49,13 @@ class A_class{ } } -/* @@? 21:24 Error TypeError: Property 'localfield' of enclosing class 'A_class' is not allowed to be captured from the local class 'LocalClass' */ -/* @@? 21:24 Error TypeError: Property 'localfield' must be accessed through 'this' */ -/* @@? 26:29 Error TypeError: Property 'localfield' does not exist on type 'FinalLocalClass' */ -/* @@? 30:41 Error TypeError: Cannot inherit with 'final' modifier. */ -/* @@? 31:53 Error TypeError: Cannot use both 'final' and 'abstract' modifiers. */ -/* @@? 36:37 Error TypeError: AbstractLocalClass2 is abstract therefore cannot be instantiated. */ -/* @@? 39:13 Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ -/* @@? 40:31 Error TypeError: Native, Abstract and Declare methods cannot have body. */ -/* @@? 43:65 Error TypeError: FinalLocalClass2 is not abstract and does not override abstract method method3(): void in FinalLocalClass2 */ -/* @@? 45:13 Error TypeError: Non abstract class has abstract method. */ \ No newline at end of file +/* @@? 18:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 19:9 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 24:15 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 30:9 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 31:24 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 33:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 36:15 Error TypeError: Cannot find type 'AbstractLocalClass2'. */ +/* @@? 36:41 Error TypeError: Cannot find type 'AbstractLocalClass2'. */ +/* @@? 38:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 43:15 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_enum.ets b/ets2panda/test/ast/parser/ets/local_enum.ets new file mode 100644 index 0000000000000000000000000000000000000000..73d642975bb4a763b40034b959490894181294ea --- /dev/null +++ b/ets2panda/test/ast/parser/ets/local_enum.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 myAssertEqual = (actualValue: boolean, expectValue: boolean) => { + enum E {E1} +} + +function test() { + enum E {E1} + + if (true) { + enum E {E1} + } +} + +class C { + enum E {E1} + + foo(){ + enum E {E1} + } +} + +interface I{ + enum E {E1} +} + +/* @@? 17:3 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 21:3 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 24:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 29:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ +/* @@? 32:5 Error SyntaxError: Illegal start of ENUM expression. */ +/* @@? 37:4 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 37:11 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 37:12 Error TypeError: Cannot find type 'E1'. */ +/* @@? 38:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/local_interface.ets b/ets2panda/test/ast/parser/ets/local_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..e645260fcad3857939f27856abde2dde52820e17 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/local_interface.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. + */ + +let myAssertEqual = (actualValue: boolean, expectValue: boolean) => { + /* @@ label1 */interface LocalI { + pass: boolean + message: string + } + + /* @@ label2 */class LocalC { + pass: boolean = true + message: string = "123" + } +} + +function test() { + /* @@ label3 */interface LocalI { + pass: boolean + message: string + } + /* @@ label4 */class LocalC { + pass: boolean = true + message: string = "123" + } + + if (true) { + /* @@ label5 */interface LocalI { + pass: boolean + message: string + } + /* @@ label6 */class LocalC { + pass: boolean = true + message: string = "123" + } + } +} + +class C { + /* @@ label7 */interface LocalI { + pass: boolean + message: string + } + /* @@ label8 */class LocalC { + pass: boolean = true + message: string = "123" + } + + foo(){ + /* @@ label9 */interface LocalI { + pass: boolean + message: string + } + /* @@ label10 */class LocalC { + pass: boolean = true + message: string = "123" + } + } +} + +/* @@@ label1 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label2 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@@ label3 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label4 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@@ label5 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label6 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@@ label7 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ +/* @@@ label8 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ +/* @@@ label9 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@@ label10 Error SyntaxError: Illegal start of CLASS expression. */ \ No newline at end of file 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..df8b96452f5280fe3a0fff4b26417033aeac07a9 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. */ +/* @@? 17:3 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:3 Error SyntaxError: Illegal start of INTERFACE expression. */ \ No newline at end of file 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..67952a2acfbbc7d4cddad6651e69ba25b4ffd959 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. */ +/* @@? 17:3 Error SyntaxError: Illegal start of INTERFACE expression. */ +/* @@? 20:3 Error SyntaxError: Illegal start of INTERFACE expression. */ 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..0660c505d4bda4e94018cb0e8e5c690c1d5458d8 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,4 @@ function bar(): void { } } -/* @@? 18:3 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 18:3 Error SyntaxError: Illegal start of INTERFACE expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_type_alias.ets b/ets2panda/test/ast/parser/ets/local_type_alias.ets new file mode 100644 index 0000000000000000000000000000000000000000..9060686ac9d3a95d6b7f809b8adbf2f9d312e3f5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/local_type_alias.ets @@ -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. + */ + +class A{} + +let myAssertEqual = (actualValue: boolean, expectValue: boolean) => { + type a = A; +} + +function test() { + type a = A; + + if (true) { + type a = A; + } +} + +class C { + type a = A; + + foo(){ + type a = A; + } +} + +interface I{ + type a = A; +} + +/* @@? 19:3 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 23:3 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 26:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 31:7 Error SyntaxError: Field type annotation expected. */ +/* @@? 31:12 Error SyntaxError: Class cannot be used as object. */ +/* @@? 34:5 Error SyntaxError: Illegal start of Type Alias expression. */ +/* @@? 39:9 Error TypeError: Cannot find type 'a'. */ +/* @@? 39:11 Error SyntaxError: Interface member initialization is prohibited. */ +/* @@? 39:13 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 39:13 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 39:14 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/loops.ets b/ets2panda/test/ast/parser/ets/loops.ets index 027c90e68219b347b2d236cfc8a803342e5fadeb..b615b0ecd600ac2732f80cbc1f4a68c4f34c2dc3 100644 --- a/ets2panda/test/ast/parser/ets/loops.ets +++ b/ets2panda/test/ast/parser/ets/loops.ets @@ -65,4 +65,3 @@ function labeledcontinue(): void { } /* @@? 19:15 Error TypeError: Unresolved reference i */ -/* @@? 19:15 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ 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/method_modifier_check_1.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_1.ets index 821072dfef8ecb6b586e14f210a86ea62a9ff95c..b7dc7a4833f999c95fc9f1b6e430c54e82a2bc65 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_1.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_1.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */abstract static foo(): void /* @@ label1 */{} + abstract static /* @@ label */foo(): void /* @@ label1 */{} } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_10.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_10.ets index ab3775e63a7b25cec0a8292ddc8b18da286ce065..213f10bfdbfbd63f7d45218df474325752c772ce 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_10.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_10.ets @@ -14,8 +14,8 @@ */ class A { - final static foo() : void {} + final static /* @@ label */foo() : void {} } -/* @@? 17:5 Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ -/* @@? 17:5 Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ +/* @@@ label Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ +/* @@@ label Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_13.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_13.ets index a4d21bce0211f78840d9e85f5a7700b35ad24558..8d596511c737d3cd9feb5fb66cff685908561fa5 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_13.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_13.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */native abstract foo() : void; + native abstract /* @@ label */foo() : void; } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_15.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_15.ets index d9ddd68e777a9ddf6d08733ded11600ff7d20a48..2ce06b448a72e6fb62ec17e7cfad9a9b68101a14 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_15.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_15.ets @@ -15,8 +15,8 @@ class A { native final foo() : void; - static final foo2() : void {}; + static final /* @@ label */foo2() : void {}; } -/* @@? 18:5 Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ -/* @@? 18:5 Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ \ No newline at end of file +/* @@@ label Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ +/* @@@ label Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_2.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_2.ets index 134d8fae47d1e1430ed6271aeb3f8e3d77050ec9..2f3b401762b1dd4d30b226eff78593d9dad3bd1f 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_2.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_2.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */abstract final foo(): void /* @@ label1 */{} + abstract final /* @@ label */foo(): void /* @@ label1 */{} } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_3.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_3.ets index 04ca1b3e84298d65e80fee13269c30ecafb5365a..477dbe2f37e9ac9d37e77f71761a7c9bfb1de7a9 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_3.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_3.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */abstract override foo(): void /* @@ label1 */{} + abstract override /* @@ label */foo(): void /* @@ label1 */{} } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_4.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_4.ets index 35b31adb7e074f7f80f1e8135616b1aa8f5b8bc6..a2c56ede0044af09fe0be00c77ced7f88dd46a30 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_4.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_4.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */abstract native foo(): void /* @@ label1 */{} + abstract native /* @@ label */foo(): void /* @@ label1 */{} } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_5.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_5.ets index fd5a2f56352d9cd81f83b83c568e605b4fcc1695..cc9f684ee9ed943fe71459dfdcf1229785a6991d 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_5.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_5.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */static abstract foo(): void /* @@ label1 */{} + static abstract /* @@ label */foo(): void /* @@ label1 */{} } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_6.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_6.ets index 43793d5207b5c7eaae16bab38b2fae5980694f99..8b927eca6b07c8e478bdb52917ce7bdba0538d7d 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_6.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_6.ets @@ -14,8 +14,8 @@ */ class A { - static final foo(): void {} + static final /* @@ label */foo(): void {} } -/* @@? 17:5 Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ -/* @@? 17:5 Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ +/* @@@ label Error TypeError: Invalid method modifier(s): a final method can't have abstract or static modifier. */ +/* @@@ label Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_7.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_7.ets index eb889baf013cbf6ce938c01bb1b1e349908231a6..8ade4654402857b27cf2bc694c549c843bf3c743 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_7.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_7.ets @@ -14,7 +14,7 @@ */ class A { - /* @@ label */static override foo(): void {} + static override /* @@ label */foo(): void {} } /* @@@ label Error TypeError: Invalid method modifier(s): a static method can't have abstract, final or override modifier. */ diff --git a/ets2panda/test/ast/parser/ets/method_modifier_check_9.ets b/ets2panda/test/ast/parser/ets/method_modifier_check_9.ets index 4b48b2eb56c4709bd1de5beb0365c99b0916ac06..b8203667590acf961aeea74a80a0899f277b9804 100644 --- a/ets2panda/test/ast/parser/ets/method_modifier_check_9.ets +++ b/ets2panda/test/ast/parser/ets/method_modifier_check_9.ets @@ -14,7 +14,7 @@ */ abstract class A { - /* @@ label */final abstract foo() : void; + final abstract /* @@ label */foo() : void; } /* @@@ label Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ 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 index 3f2ffefd8c24ff34159ecdcedadd356dcc3fc8d2..64b36ca55053a67f67347272d8d507de9c521045 100644 --- a/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets +++ b/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets @@ -19,7 +19,6 @@ class URIError extends WebAssembly {WebAssembly : WeakMap [-6]} /* @@? 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: Identifier 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/missing_in_for_statement_1.ets b/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.ets index e348adfa0feb8994a6125e8c7a7f5d281cf1bc66..88b0f45e72ce723f258eddb38b5a49290db90dd0 100644 --- a/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.ets +++ b/ets2panda/test/ast/parser/ets/missing_in_for_statement_1.ets @@ -18,8 +18,7 @@ for /* @@ label */let i = 0; i < count; ++i) { } /* @@@ label Error SyntaxError: Expected '(', got 'let'. */ -/* @@? 16:30 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 16:34 Error TypeError: Function name 'count' used in the wrong context */ +/* @@? 16:34 Error TypeError: Unresolved reference count */ /* @@? 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/missing_in_for_statement_2.ets b/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.ets index b8ba1653ee8cca8f51b788bd45299ad85775ead9..a290ef8d7d4adfc1ae456c352bc5deac651335f1 100644 --- a/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.ets +++ b/ets2panda/test/ast/parser/ets/missing_in_for_statement_2.ets @@ -17,8 +17,7 @@ for (let i = 0; i < count; ++i /* @@ label */{ result = result + p[i]!.awaitResolution() * /* @@label1 */a[i]; } -/* @@? 16:21 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 16:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 16:21 Error TypeError: Unresolved reference count */ /* @@@ label Error SyntaxError: Expected ')', got '{'. */ /* @@? 17:5 Error TypeError: Unresolved reference result */ /* @@? 17:23 Error TypeError: Unresolved reference p */ 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_bad_token.ets b/ets2panda/test/ast/parser/ets/namespace_bad_token.ets index 2b279dceae922adf414b83d7989d4b169ba60f3e..5576913d3324f063cc44624d95b259aba988a9d9 100644 --- a/ets2panda/test/ast/parser/ets/namespace_bad_token.ets +++ b/ets2panda/test/ast/parser/ets/namespace_bad_token.ets @@ -17,5 +17,5 @@ declare namespace uiObserver { function on(options: { a: number }, callback: ): void; } -/* @@? 17:26 Error SyntaxError: Invalid Type. */ +/* @@? 17:26 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ /* @@? 17:51 Error SyntaxError: Invalid Type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets index b7ddfb7d672ad4072cb9c20ca2127ed9fdb61a7d..f5dd2523aa7cf6bb2ad41a302f47289a40e598ca 100644 --- a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets +++ b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets @@ -17,7 +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'. */ /* @@? 17:11 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/parser/ets/new_object_1.ets b/ets2panda/test/ast/parser/ets/new_object_1.ets index 0fcda02a6f0d48d457385f6a8b51ec8fd9422079..b1804b5d425ed77698124883f1d3c0e694fd8467 100644 --- a/ets2panda/test/ast/parser/ets/new_object_1.ets +++ b/ets2panda/test/ast/parser/ets/new_object_1.ets @@ -15,7 +15,6 @@ function main() : void { - let x : int = /* @@ label */new int(); + let x : int = new int(); } -/* @@@ label Error TypeError: This expression is not constructible. */ diff --git a/ets2panda/test/ast/parser/ets/new_object_2.ets b/ets2panda/test/ast/parser/ets/new_object_2.ets index 5c7e9c6a0e4fa652067c5b88b758e5d47b399413..6ae4a96bc894771566e5b6550beb7e2e7a77d0ab 100644 --- a/ets2panda/test/ast/parser/ets/new_object_2.ets +++ b/ets2panda/test/ast/parser/ets/new_object_2.ets @@ -15,7 +15,5 @@ function main() : void { - let x = /* @@ label */new boolean(); + let x = new boolean(); } - -/* @@@ label Error TypeError: This expression is not constructible. */ diff --git a/ets2panda/test/ast/parser/ets/no-call-signatures.ets b/ets2panda/test/ast/parser/ets/no-call-signatures.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2758cb7fc4ea4903d2c84301c56126f491bd424 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/no-call-signatures.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 DescribableFunction { + description: string + /* @@ label */(someArg: number): string { + return someArg.toString() + } +} +function doSomething(fn: DescribableFunction) { + fn(6) +} + +/* @@@ label Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ +/* @@? 23:5 Error TypeError: No static $_invoke method and static $_instantiate method in fn. fn() is not allowed. */ +/* @@? 23:5 Error TypeError: Type 'DescribableFunction' has no call signatures. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/no-constructor-signatures.ets b/ets2panda/test/ast/parser/ets/no-constructor-signatures.ets new file mode 100644 index 0000000000000000000000000000000000000000..d0f5d9193ac71e92920c8f2f80fed687db5ff02f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/no-constructor-signatures.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class SomeObject {} +class SomeConstructor { + new (s: string): SomeObject +} +function fn(ctor: SomeConstructor) { + return new ctor("hello") +} + +/* @@? 18:7 Error SyntaxError: Constructor signatures in object types are not supported. Use '$_invoke' method instead. */ +/* @@? 21:14 Error TypeError: Cannot find type 'ctor'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/no-generic-lambda.ets b/ets2panda/test/ast/parser/ets/no-generic-lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..3f19f5974ab588f34638937c4b1072753c758828 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/no-generic-lambda.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let foo = (i: T) : void => { } +let bar = () => { } + +foo(1.0); +bar(); + +/* @@? 16:11 Error SyntaxError: Generic lambda expressions are not supported. */ +/* @@? 17:11 Error SyntaxError: Generic lambda expressions are not supported. */ +/* @@? 19:1 Error TypeError: This expression is not callable. */ +/* @@? 20:1 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/parser/ets/no_prototype.ets b/ets2panda/test/ast/parser/ets/no_prototype.ets new file mode 100644 index 0000000000000000000000000000000000000000..2f70cb7112e9d176b0c326e6865da24e13facf2e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/no_prototype.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 {} + +C.prototype = Object.prototype + +C.prototype = { + m() { + console.log("C.m()") + } +} + +/* @@? 18:3 Error TypeError: Property 'prototype' does not exist on type 'C' */ +/* @@? 18:13 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 18:22 Error TypeError: Property 'prototype' does not exist on type 'Object' */ +/* @@? 20:1 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 20:3 Error TypeError: Property 'prototype' does not exist on type 'C' */ +/* @@? 20:13 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 21:4 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 21:5 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:7 Error SyntaxError: Unexpected token. */ +/* @@? 22:12 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/nolint_bad.ets b/ets2panda/test/ast/parser/ets/nolint_bad.ets new file mode 100644 index 0000000000000000000000000000000000000000..b4aa54d09744e878c4403a61fc3792f11e0aa11d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/nolint_bad.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. + */ + + +// ETSNOLINT(definitely-not-a-real-etsnolint-argument) +// ETSNOLINT(@) +function main() {} +/* @@? 1:3 Error SyntaxError: Invalid argument for ETSNOLINT! */ +/* @@? 1:3 Error SyntaxError: Unexpected character for ETSNOLINT argument! [VALID ONLY: a-z, '-']. */ +/* @@? 1:3 Error SyntaxError: Invalid argument for ETSNOLINT! */ 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 a2ab27116b790369f9c63c526746bc63492b5dc9..ede2ed654fee6430d96ff7c4d0020330910bf925 100644 --- a/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets +++ b/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets @@ -14,11 +14,7 @@ */ class A{ - /* @@ label */(a:number/* @@ label1 */)/* @@ label2 */:number -/* @@ label3 */} + /* @@ label */(a:number) :number +} -/* @@@ 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. */ +/* @@@ label Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ diff --git a/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets b/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets index 1d7295d53c26d921d22f94e6613a6f0256535053..51b76e0ed88c97fa52fa4eefc299c8f1c338b5ba 100644 --- a/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets +++ b/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets @@ -15,8 +15,6 @@ export class Test { private static fn(u: double[], i: double): void { - u[/* @@ label */i] = 0.0 + u[/* @@ label */i.toInt()] = 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_constant_expression.ets b/ets2panda/test/ast/parser/ets/non_constant_expression.ets index 80ca9574cfd119718d06e79cf2690dd0704edeb3..edb49055eba17dc00fac81b5d84cd69269860c90 100644 --- a/ets2panda/test/ast/parser/ets/non_constant_expression.ets +++ b/ets2panda/test/ast/parser/ets/non_constant_expression.ets @@ -22,4 +22,4 @@ let cc = 1 function foo() {} -/* @@? 21:14 Error SyntaxError: Only constant expression is expected in the field */ +/* @@? 21:14 Error TypeError: Invalid value for annotation field, expected a constant literal. */ 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..49fbed1717f6f4501e8770972ccbcfa9f7480e15 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,12 @@ function main() { console.log(/* @@ label */a["a"]) } -/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Boolean): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Byte): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Short): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Char): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Int): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ +/* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/notnullable_neg.ets b/ets2panda/test/ast/parser/ets/notnullable_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..b48602f1bba30a4d60cd486fd6cfea721695a62b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/notnullable_neg.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 main() { + let foo = (p: T): NonNullable<<<<<<<<<<<<<<<<<<<<<<<<<< =>p; +} + +/* @@? 17:15 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token 'T'. */ +/* @@? 17:22 Error TypeError: Unresolved reference T */ +/* @@? 17:23 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:24 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:26 Error SyntaxError: Unexpected token 'NonNullable'. */ +/* @@? 17:26 Error TypeError: Unresolved reference NonNullable */ +/* @@? 17:37 Error SyntaxError: Expected '>', got '<<'. */ +/* @@? 17:37 Error SyntaxError: Expected '<', got '<<'. */ +/* @@? 17:37 Error SyntaxError: Expected '>', got '<<'. */ +/* @@? 17:37 Error SyntaxError: Expected '<', got '<<'. */ +/* @@? 17:39 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:43 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:47 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:51 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:55 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:59 Error SyntaxError: Unexpected token '<<'. */ +/* @@? 17:63 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 17:67 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 17:69 Error SyntaxError: Unexpected token 'p'. */ +/* @@? 17:69 Error TypeError: Unresolved reference p */ diff --git a/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets b/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets index c18b63da2fed45933efb68d66a5d5eb2dd2262cb..12ccf8b28d020a100e60e49be19f9ec6c860acb0 100644 --- a/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets +++ b/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets @@ -16,9 +16,9 @@ interface A { foo(): void} const x: A = {foo() {}} -/* @@? 17:15 Error TypeError: Method 'foo' cannot be used as a key of object literal. */ +/* @@? 17:15 Error TypeError: Class or interface methods cannot be initialized within an 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/ast/parser/ets/optional-chaining-array.ets b/ets2panda/test/ast/parser/ets/optional-chaining-array.ets index b945402b507141e302f524eca37758d4b0b10d9f..fd1f441713577e5d01ba1621480a93c0f5c07440 100644 --- a/ets2panda/test/ast/parser/ets/optional-chaining-array.ets +++ b/ets2panda/test/ast/parser/ets/optional-chaining-array.ets @@ -19,4 +19,4 @@ let test = arr?.[1] ?? "unknown"; let arr2: String[] | null; let test2 = arr2?.[100] ?? "unknown2"; -/* @@? 20:13 Warning Warning: Variable 'arr2' is used before being assigned. */ +/* @@? 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/runtime/ets/optional_field.ets b/ets2panda/test/ast/parser/ets/optional_field.ets similarity index 67% rename from ets2panda/test/runtime/ets/optional_field.ets rename to ets2panda/test/ast/parser/ets/optional_field.ets index 3190aa7e6ef9dd4d0766796b826bdb4aa141ebfa..de1c1e5af0968cd6efff8304dddf08a43931420c 100644 --- a/ets2panda/test/runtime/ets/optional_field.ets +++ b/ets2panda/test/ast/parser/ets/optional_field.ets @@ -42,14 +42,17 @@ function main() : int let var2? = O; let var3? = goo(); - assertEQ(c.method('blablabla'), 1) - assertEQ(c.method(undefined), 2) - assertEQ(c.method(), 2) - assertTrue(c.field === undefined) + arktest.assertEQ(c.method('blablabla'), 1) + arktest.assertEQ(c.method(undefined), 2) + arktest.assertEQ(c.method(), 2) + arktest.assertTrue(c.field === undefined) - assertTrue(var1 === undefined) - assertTrue(var2 === O) - assertTrue(var3 === I) + arktest.assertTrue(var1 === undefined) + arktest.assertTrue(var2 === O) + arktest.assertTrue(var3 === I) return 0; } + +/* @@? 27:4 Error TypeError: Function method with this assembly signature already declared. */ +/* @@? 41:14 Error SyntaxError: Optional variable is deprecated and no longer supported. */ \ No newline at end of file diff --git a/ets2panda/test/parser/ets/optional_field_variable.ets b/ets2panda/test/ast/parser/ets/optional_field_variable.ets similarity index 81% rename from ets2panda/test/parser/ets/optional_field_variable.ets rename to ets2panda/test/ast/parser/ets/optional_field_variable.ets index 47da757660366c0f4be55075d4b511a3bc98c0da..36a1540c411d2201827b16032f1d8b1fd6d2b043 100644 --- a/ets2panda/test/parser/ets/optional_field_variable.ets +++ b/ets2panda/test/ast/parser/ets/optional_field_variable.ets @@ -25,3 +25,6 @@ function foo(param? : Object) let var3? = goo(); for (let i? : Number = 1;;) { break; } } + +/* @@? 23:14 Error SyntaxError: Optional variable is deprecated and no longer supported. */ +/* @@? 26:16 Error SyntaxError: Optional variable is deprecated and no longer supported. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/overload_class_method_test.ets b/ets2panda/test/ast/parser/ets/overload_class_method_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad83ee5240433016f1f52b24115d3c94499b553b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_class_method_test.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 A{} +class B{} +class C{} + +class Test1 { + foo111(a: A): A { + return a; + } + foo112(a: B): B { + return a; + } + + foo113(a: C): C { + console.log(a) + return a; + } + overload foo{foo111,foo112,foo113} +} diff --git a/ets2panda/test/ast/parser/ets/overload_constructor.ets b/ets2panda/test/ast/parser/ets/overload_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a250cf986b737ae048585980c43fbb3da60672d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_constructor.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 { } +class B { } +class C { } + +class Test1 { + constructor fromA(a: A){ } + constructor fromB(a: B){ } + constructor fromC(a: C){ } + + overload constructor { fromA, fromB, fromC } +} + +class Test2 { + constructor() { } + constructor fromA(a: A){ } + constructor fromB(a: B){ } + + overload constructor { fromA, fromB } +} diff --git a/ets2panda/test/ast/parser/ets/overload_function_match_neg.ets b/ets2panda/test/ast/parser/ets/overload_function_match_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a8f71cfc45be1021836652c8a65f7d440dfbe58 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_function_match_neg.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 { + constructor withName(name: string) {} + constructor withTask(name: string, task: ()=>void) {} + overload constructor {withName, withTask} +} + +class DummyArray { + pushArray(...val: T[]): void {} + pushOne(value: T): void {} + overload push { pushOne, pushArray } +} + +let props: DummyArray = new DummyArray() + +/* @@ label1 */props.push( + /* @@ label2 */new A('eaw1', () => { + let s: string = /* @@ label3 */1 + }) +) + +/* @@@ label1 Error TypeError: No matching call signature for push(...) */ +/* @@@ label2 Error TypeError: No matching construct signature for A("eaw1", () => void) */ +/* @@@ label3 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/overload_global_function_our_style_test.ets b/ets2panda/test/ast/parser/ets/overload_global_function_our_style_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..4237ee173fe32d600fea491d4a54d84d0d73636d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_global_function_our_style_test.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{} +class C{} + +function foo111(a: A): A { + return a; +} +function foo112(a: B): B { + return a; +} + +function foo113(a: C): C { + console.log(a) + return a; +} + +overload foo{ foo111, foo112, foo113 } diff --git a/ets2panda/test/ast/parser/ets/overload_interface_method_test.ets b/ets2panda/test/ast/parser/ets/overload_interface_method_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..d418c4eacffb623bda292132dbc986cacecf0064 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_interface_method_test.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{} +class B{} +class C{} + +interface Test1 { + foo111(a: A): A; + foo112(a: B): B; + foo113(a: C): C; + overload foo{foo111,foo112,foo113}; +} diff --git a/ets2panda/test/ast/parser/ets/overload_modifier_overloaddefinition.ets b/ets2panda/test/ast/parser/ets/overload_modifier_overloaddefinition.ets new file mode 100644 index 0000000000000000000000000000000000000000..c261c9fca064292a75c71abde16959b74be1ebd6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overload_modifier_overloaddefinition.ets @@ -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. + */ + +class A{} +class B{} +class C{} +class TempAny{} + +class Test1 { + async foo111(a: A): Promise { + return a; + } + async foo112(a: B): Promise { + return a; + } + + async foo113(a: C): Promise { + console.log(a) + return a; + } + async overload foo{foo111,foo112,foo113} +} + +class Test2 { + static foo111(a: A): A { + return a; + } + static foo112(a: B): B { + return a; + } + + static foo113(a: C): C { + console.log(a) + return a; + } + static overload foo{foo111,foo112,foo113} +} + +class Test3 { + private foo111(a: A): A { + return a; + } + private foo112(a: B): B { + return a; + } + + private foo113(a: C): C { + console.log(a) + return a; + } + private overload foo{foo111,foo112,foo113} +} 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..1f80043685998b862aae7445b7088d1bb1512c28 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overloaded_method_as_value_neg.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. + */ + +interface"actual : " + actual.result[i] + +/* @@? 16:10 Error SyntaxError: Number, string or computed value property name 'actual : ' is not allowed, use classes to access data by property names that are identifiers */ +/* @@? 16:10 Error SyntaxError: Identifier expected, got 'string literal'. */ +/* @@? 16:22 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 16:30 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 16:38 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:38 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 16:38 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 16:39 Error SyntaxError: Identifier expected. */ +/* @@? 16:39 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 16:39 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 30:1 Error SyntaxError: Identifier expected. */ +/* @@? 30:1 Error SyntaxError: Unexpected token, expected '}'. */ diff --git a/ets2panda/test/ast/parser/ets/overrideFuncWithGetter_n.ets b/ets2panda/test/ast/parser/ets/overrideFuncWithGetter_n.ets index e5d7a91b23ddf7f9ef0919db71ef3508a069c97b..30982b269a131212016fea60daa5a5c850b0f2e4 100644 --- a/ets2panda/test/ast/parser/ets/overrideFuncWithGetter_n.ets +++ b/ets2panda/test/ast/parser/ets/overrideFuncWithGetter_n.ets @@ -23,6 +23,6 @@ class C implements A /* @@ label1 */{ } } -/* @@@ label Error TypeError: Cannot inherit from interface A because method length is inherited with a different declaration type */ -/* @@@ label1 Error TypeError: C is not abstract and does not override abstract method length(): double in A */ -/* @@@ label2 Error TypeError: Method length(): double in C not overriding any method */ +/* @@@ label Error TypeError: Cannot inherit from interface A because method length is inherited with a different declaration type */ +/* @@@ label1 Error TypeError: C is not abstract and does not override abstract method length(): Double in A */ +/* @@@ label2 Error TypeError: Method length(): Double in C not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/override_method.ets b/ets2panda/test/ast/parser/ets/override_method.ets index da4068990365c9f2dd5b67caf74d570cdd211f25..e13c36a4168974051d2f3e08123d61ce3195d856 100644 --- a/ets2panda/test/ast/parser/ets/override_method.ets +++ b/ets2panda/test/ast/parser/ets/override_method.ets @@ -25,6 +25,6 @@ final class T extends P { } } -/* @@? 22:23 Error TypeError: Cannot inherit with 'final' modifier. */ -/* @@? 23:24 Error TypeError: foo(): int in T cannot override foo(): int in P because overridden method is final. */ -/* @@? 23:24 Error TypeError: Method foo(): int in T not overriding any method */ +/* @@? 22:23 Error TypeError: Cannot inherit with 'final' modifier. */ +/* @@? 23:24 Error TypeError: foo(): Int in T cannot override foo(): Int in P because overridden method is final. */ +/* @@? 23:24 Error TypeError: Method foo(): Int in T not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets b/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets index f500f49c6ead8d9ea094ce644cc46358622f75a2..622f2e74d6e20e856c1d1254502b95821c663357 100644 --- a/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets +++ b/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets @@ -35,5 +35,5 @@ function foa(b: Partial>): void { /* @@ label */foo(/* @@ label1 */b); } -/* @@@ label1 Error TypeError: Type 'Partial>' is not compatible with type 'Partial>' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(Partial>) */ +/* @@? 35:16 Error TypeError: No matching call signature for foo(Partial) */ +/* @@? 35:35 Error TypeError: Type 'Partial' is not compatible with type 'Partial' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/partialPrimitiveConversion_n.ets b/ets2panda/test/ast/parser/ets/partialPrimitiveConversion_n.ets index 4561851b2b3f309e4779b53b2e6c25412ad6c8de..f795d5d709fc46305a5191693439a41f02d2e4e2 100644 --- a/ets2panda/test/ast/parser/ets/partialPrimitiveConversion_n.ets +++ b/ets2panda/test/ast/parser/ets/partialPrimitiveConversion_n.ets @@ -13,6 +13,4 @@ * limitations under the License. */ -function foo(b: Partial/* @@ label */): void {} - -/* @@@ label Error TypeError: Only reference types can be converted to utility types. */ \ No newline at end of file +function foo(b: Partial): void {} diff --git a/ets2panda/test/ast/parser/ets/partialType_4.ets b/ets2panda/test/ast/parser/ets/partialType_4.ets index 8cf429864d6297082d81862624ed49379eee2e35..138a81089d6ff0da4679186406e0ce935caab563 100644 --- a/ets2panda/test/ast/parser/ets/partialType_4.ets +++ b/ets2panda/test/ast/parser/ets/partialType_4.ets @@ -79,4 +79,9 @@ class A>{ bar(initializers: Partial): void {} } -/* @@@ label Error TypeError: Type 'S' cannot be assigned to type 'T|undefined' */ +/* @@? 39:142 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 49:55 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 51:51 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 53:86 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 75:55 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 79:30 Error TypeError: T in Partial must be a class or an interface type. */ diff --git a/ets2panda/test/ast/parser/ets/partial_not_reference_type.ets b/ets2panda/test/ast/parser/ets/partial_not_reference_type.ets index 72ec0cf62def4bba153d458a5b4c8a64da727cdd..e6a0fc3ec7ef882ca5337621b6434bf3f5eba4ff 100644 --- a/ets2panda/test/ast/parser/ets/partial_not_reference_type.ets +++ b/ets2panda/test/ast/parser/ets/partial_not_reference_type.ets @@ -14,6 +14,4 @@ */ -function foo(a:Partial/* @@ label */){} - -/* @@@ label Error TypeError: Only reference types can be converted to utility types. */ \ No newline at end of file +function foo(a:Partial){} diff --git a/ets2panda/test/compiler/ets/override19.ets b/ets2panda/test/ast/parser/ets/partial_type_param1.ets similarity index 43% rename from ets2panda/test/compiler/ets/override19.ets rename to ets2panda/test/ast/parser/ets/partial_type_param1.ets index f8eedea38df4eeeb988ef6dae2b919801e7ef9b8..0ff07bf635902a8bde714b6eae5170e586c9577a 100644 --- a/ets2panda/test/compiler/ets/override19.ets +++ b/ets2panda/test/ast/parser/ets/partial_type_param1.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-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,19 +13,29 @@ * limitations under the License. */ -class O{ - override toString(): String { - return ""; - } - override $_hashCode(): int { - return 4; - } +interface I { + i: number; + j: string; } -class OExt extends O{ +class CI implements I { + _i: number = 0; + _j: string = ""; + + set i(i: number) { this._i = i; } + get i(): number { return this._i; } + + set j(j: string) { this._j = j; } + get j(): string { return this._j; } } -function main(): void { - let o: OExt = new OExt() - assertEQ(o.$_hashCode(), 4); +function generic(t: Partial): boolean { + return t !== null && t !== undefined; } + +function main() { + // Test that {i: 1} is accepted as Partial + generic({i: 1}); +}/* @@? 32:41 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 38:5 Error TypeError: No matching call signature for generic(...) */ +/* @@? 38:17 Error TypeError: need to specify target type for class composite */ diff --git a/ets2panda/test/ast/compiler/ets/override18.ets b/ets2panda/test/ast/parser/ets/partial_type_param2.ets similarity index 47% rename from ets2panda/test/ast/compiler/ets/override18.ets rename to ets2panda/test/ast/parser/ets/partial_type_param2.ets index 11678d420ee898da59ebb4ad2b1f913565986f27..7dbb5c559d86caf893bcae792c7a25b24ee8142a 100644 --- a/ets2panda/test/ast/compiler/ets/override18.ets +++ b/ets2panda/test/ast/parser/ets/partial_type_param2.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-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,19 +13,27 @@ * limitations under the License. */ -interface J{ - toString(): String { - return ""; - } - $_hashCode():int{ - return 4; - } +export interface I { + i: number; + j: string; } -class JImpl implements J{ +function foo(i: Partial): number { + let v: number = 0; + if (typeof i === 'object') { + if (i.j !== undefined) { + v += 1; + } + if (i.i !== undefined && i.i !== 0) { + v += 2; + } + } + return v; } -function main(): void { - let o: JImpl = new JImpl() - assertEQ(o.$_hashCode(), 4); -} +function main() { + // Test case: only 'i' is provided, 'j' is omitted + foo({ i: 5 }); +}/* @@? 21:37 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 36:3 Error TypeError: No matching call signature for foo(...) */ +/* @@? 36:10 Error TypeError: need to specify target type for class composite */ diff --git a/ets2panda/test/ast/parser/ets/predefined_non_primitive_types.ets b/ets2panda/test/ast/parser/ets/predefined_non_primitive_types.ets index 4f1dabc0bf115d091862df85e32ccc23c4337901..5c7ce150be2d84087744c22776ac19daaddf8541 100644 --- a/ets2panda/test/ast/parser/ets/predefined_non_primitive_types.ets +++ b/ets2panda/test/ast/parser/ets/predefined_non_primitive_types.ets @@ -35,6 +35,7 @@ let s: String = "abc"; // see 3.2.2 Array types let a: int[] = new int[5]; -/* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ +/* @@? 23:25 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ +/* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 27:31 Error TypeError: Cannot find type 'Bool'. */ -/* @@? 27:38 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ +/* @@? 27:38 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ diff --git a/ets2panda/test/ast/parser/ets/primitive_type_method_1.ets b/ets2panda/test/ast/parser/ets/primitive_type_method_1.ets index 92e7d3f50715df1ea9972da442efee189666001d..8f30a8fe806dce5762ae77996e5199d4f39a5f6d 100644 --- a/ets2panda/test/ast/parser/ets/primitive_type_method_1.ets +++ b/ets2panda/test/ast/parser/ets/primitive_type_method_1.ets @@ -15,7 +15,6 @@ function main(): void { let value: byte = 0; - /* @@ label */value.toString() + value.toString() } -/* @@@ label Error TypeError: Property 'toString' does not exist on type 'byte' */ diff --git a/ets2panda/test/ast/parser/ets/primitive_type_method_2.ets b/ets2panda/test/ast/parser/ets/primitive_type_method_2.ets index e71249dfec8fba9c3f8137794e64f6ed44503da4..1589f0d5ad19bf755e5e7a832679e68edf366fa2 100644 --- a/ets2panda/test/ast/parser/ets/primitive_type_method_2.ets +++ b/ets2panda/test/ast/parser/ets/primitive_type_method_2.ets @@ -14,9 +14,8 @@ */ function toString1(value: number): string { - return /* @@ label */value.toString(value); + return value.toString(value); } function main(): void {} -/* @@@ label Error TypeError: Property 'toString' does not exist on type 'double' */ diff --git a/ets2panda/test/ast/parser/ets/privateSuperConstructorCall.ets b/ets2panda/test/ast/parser/ets/privateSuperConstructorCall.ets index 70e64c12b9aab8d0053c650a8878c7878efceadd..fcf1050921731b38280481e1c63e3065af348567 100644 --- a/ets2panda/test/ast/parser/ets/privateSuperConstructorCall.ets +++ b/ets2panda/test/ast/parser/ets/privateSuperConstructorCall.ets @@ -28,8 +28,8 @@ class Banana extends Alma { function main(): void { let instance: Banana = new Banana(); - assertEQ(instance.x, 5); + arktest.assertEQ(instance.x, 5); } -/* @@? 25:5 Error TypeError: Signature constructor(alma: int): void is not visible here. */ -/* @@? 25:5 Error TypeError: No matching call signature for privateSuperConstructorCall.Alma(int) */ +/* @@? 25:5 Error TypeError: Signature constructor(alma: Int): void is not visible here. */ +/* @@? 25:5 Error TypeError: No matching call signature for privateSuperConstructorCall.Alma(Int) */ 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/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 index e98c8fe2301552a787b7cbf41a270334ad439deb..b1a52b384dbf900828570cab1846a26daaf836d6 100644 --- a/ets2panda/test/ast/parser/ets/re_export/re_export_16.ets +++ b/ets2panda/test/ast/parser/ets/re_export/re_export_16.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,4 +13,5 @@ * limitations under the License. */ -export {test2} from './export_6' \ No newline at end of file +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/re_export/re_export_circular.ets b/ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets new file mode 100644 index 0000000000000000000000000000000000000000..bfc5c191e694bbc02f5ecd1d56f2b6f74f475c7c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {foo} from "./re_export_circular.ets" + +/* @@? 16:8 Error SyntaxError: Re-exporting local bindings is not allowed */ diff --git a/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-arg.ets b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-arg.ets new file mode 100644 index 0000000000000000000000000000000000000000..2f8f222ce1e5c93af33ed56be2b6b643d3d96e7b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-arg.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. + */ + +function foo(arr: readonly int[]) { + arr./* @@ extendTo */extendTo(2, 0); + arr./* @@ shrinkTo */shrinkTo(2); + arr./* @@ sort */sort(); + arr./* @@ shift */shift(); + arr./* @@ pop */pop(); + arr./* @@ push */push(2, 3); + arr./* @@ pushECMA */pushECMA(4, 5); + arr./* @@ splice */splice(0,1,2,3); + arr./* @@ unshift */unshift(-1); + arr./* @@ copyWithin */copyWithin(0,0,0); + arr./* @@ fill */fill(3); + arr./* @@ toSpliced */toSpliced(); + arr./* @@ reverse */reverse(); + arr./* @@ with */with(0, 5); +} + +/* @@@ extendTo Error TypeError: Property 'extendTo' does not exist on type 'ReadonlyArray' */ +/* @@@ shrinkTo Error TypeError: Property 'shrinkTo' does not exist on type 'ReadonlyArray' */ +/* @@@ sort Error TypeError: Property 'sort' does not exist on type 'ReadonlyArray' */ +/* @@@ shift Error TypeError: Property 'shift' does not exist on type 'ReadonlyArray' */ +/* @@@ pop Error TypeError: Property 'pop' does not exist on type 'ReadonlyArray' */ +/* @@@ push Error TypeError: Property 'push' does not exist on type 'ReadonlyArray' */ +/* @@@ pushECMA Error TypeError: Property 'pushECMA' does not exist on type 'ReadonlyArray' */ +/* @@@ splice Error TypeError: Property 'splice' does not exist on type 'ReadonlyArray' */ +/* @@@ unshift Error TypeError: Property 'unshift' does not exist on type 'ReadonlyArray' */ +/* @@@ copyWithin Error TypeError: Property 'copyWithin' does not exist on type 'ReadonlyArray' */ +/* @@@ fill Error TypeError: Property 'fill' does not exist on type 'ReadonlyArray' */ +/* @@@ toSpliced Error TypeError: Property 'toSpliced' does not exist on type 'ReadonlyArray' */ +/* @@@ reverse Error TypeError: Property 'reverse' does not exist on type 'ReadonlyArray' */ +/* @@@ with Error TypeError: Property 'with' does not exist on type 'ReadonlyArray' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-field.ets b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-field.ets new file mode 100644 index 0000000000000000000000000000000000000000..49c10b6b192d71f2db90cc26672ea9b611a49505 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-field.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 A { + arr: readonly int[] = [1]; + foo() { + this.arr./* @@ extendTo */extendTo(2, 0); + this.arr./* @@ shrinkTo */shrinkTo(2); + this.arr./* @@ sort */sort(); + this.arr./* @@ shift */shift(); + this.arr./* @@ pop */pop(); + this.arr./* @@ push */push(2, 3); + this.arr./* @@ pushECMA */pushECMA(4, 5); + this.arr./* @@ splice */splice(0,1,2,3); + this.arr./* @@ unshift */unshift(-1); + this.arr./* @@ copyWithin */copyWithin(0,0,0); + this.arr./* @@ fill */fill(3); + this.arr./* @@ toSpliced */toSpliced(); + this.arr./* @@ reverse */reverse(); + this.arr./* @@ with */with(0, 5); + } +} + +/* @@@ extendTo Error TypeError: Property 'extendTo' does not exist on type 'ReadonlyArray' */ +/* @@@ shrinkTo Error TypeError: Property 'shrinkTo' does not exist on type 'ReadonlyArray' */ +/* @@@ sort Error TypeError: Property 'sort' does not exist on type 'ReadonlyArray' */ +/* @@@ shift Error TypeError: Property 'shift' does not exist on type 'ReadonlyArray' */ +/* @@@ pop Error TypeError: Property 'pop' does not exist on type 'ReadonlyArray' */ +/* @@@ push Error TypeError: Property 'push' does not exist on type 'ReadonlyArray' */ +/* @@@ pushECMA Error TypeError: Property 'pushECMA' does not exist on type 'ReadonlyArray' */ +/* @@@ splice Error TypeError: Property 'splice' does not exist on type 'ReadonlyArray' */ +/* @@@ unshift Error TypeError: Property 'unshift' does not exist on type 'ReadonlyArray' */ +/* @@@ copyWithin Error TypeError: Property 'copyWithin' does not exist on type 'ReadonlyArray' */ +/* @@@ fill Error TypeError: Property 'fill' does not exist on type 'ReadonlyArray' */ +/* @@@ toSpliced Error TypeError: Property 'toSpliced' does not exist on type 'ReadonlyArray' */ +/* @@@ reverse Error TypeError: Property 'reverse' does not exist on type 'ReadonlyArray' */ +/* @@@ with Error TypeError: Property 'with' does not exist on type 'ReadonlyArray' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-var.ets b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-var.ets new file mode 100644 index 0000000000000000000000000000000000000000..bf24504eaaf22b79febf30b73510b592238fe115 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonly-array/readonly-array-var.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. + */ + +let arr: readonly int[] = [1]; + +arr./* @@ extendTo */extendTo(2, 0); +arr./* @@ shrinkTo */shrinkTo(2); +arr./* @@ sort */sort(); +arr./* @@ shift */shift(); +arr./* @@ pop */pop(); +arr./* @@ push */push(2, 3); +arr./* @@ pushECMA */pushECMA(4, 5); +arr./* @@ splice */splice(0,1,2,3); +arr./* @@ unshift */unshift(-1); +arr./* @@ copyWithin */copyWithin(0,0,0); +arr./* @@ fill */fill(3); +arr./* @@ toSpliced */toSpliced(); +arr./* @@ reverse */reverse(); +arr./* @@ with */with(0, 5); + +/* @@@ extendTo Error TypeError: Property 'extendTo' does not exist on type 'ReadonlyArray' */ +/* @@@ shrinkTo Error TypeError: Property 'shrinkTo' does not exist on type 'ReadonlyArray' */ +/* @@@ sort Error TypeError: Property 'sort' does not exist on type 'ReadonlyArray' */ +/* @@@ shift Error TypeError: Property 'shift' does not exist on type 'ReadonlyArray' */ +/* @@@ pop Error TypeError: Property 'pop' does not exist on type 'ReadonlyArray' */ +/* @@@ push Error TypeError: Property 'push' does not exist on type 'ReadonlyArray' */ +/* @@@ pushECMA Error TypeError: Property 'pushECMA' does not exist on type 'ReadonlyArray' */ +/* @@@ splice Error TypeError: Property 'splice' does not exist on type 'ReadonlyArray' */ +/* @@@ unshift Error TypeError: Property 'unshift' does not exist on type 'ReadonlyArray' */ +/* @@@ copyWithin Error TypeError: Property 'copyWithin' does not exist on type 'ReadonlyArray' */ +/* @@@ fill Error TypeError: Property 'fill' does not exist on type 'ReadonlyArray' */ +/* @@@ toSpliced Error TypeError: Property 'toSpliced' does not exist on type 'ReadonlyArray' */ +/* @@@ reverse Error TypeError: Property 'reverse' does not exist on type 'ReadonlyArray' */ +/* @@@ with Error TypeError: Property 'with' does not exist on type 'ReadonlyArray' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test1.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test1.ets index 1b87bffb76dd983e1fb7db37f2d00945275475d8..a4cba4c0ae9bc6c2f4cdf283eca736656fa13703 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test1.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test1.ets @@ -19,4 +19,4 @@ function foo(x : readonly Array) let x1 : Array x1 = /* @@ label */x } -/* @@@ label Error TypeError: Type 'Readonly>' cannot be assigned to type 'Array' */ +/* @@@ label Error TypeError: Type 'readonly Array' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test3.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test3.ets index f7b0cff0a5a33d73103af7a07e0dd73fe8fc5398..2d5de9a3dfdfefd19b92b70c94fc8d0f0e302ac3 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test3.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-Array-test3.ets @@ -19,5 +19,5 @@ function foo (p: Array) { let x: readonly Array /* @@ label */foo(/* @@ label1 */x) -/* @@@ label Error TypeError: No matching call signature for foo(Readonly>) */ -/* @@@ label1 Error TypeError: Type 'Readonly>' is not compatible with type 'Array' at index 1 */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly Array) */ +/* @@@ label1 Error TypeError: Type 'readonly Array' is not compatible with type 'Array' at index 1 */ 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..5865989d84229a0d5ff02d8b26dcbfb82578aa1e 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[]) */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly Array) */ +/* @@@ label1 Error TypeError: Type 'readonly Array' 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 7fbea40572514d454dd7dd155ae43746e2c46a2e..e6e6e1759a06268cdcf5e6961f14950d7523c259 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 @@ -16,8 +16,9 @@ function foo (p: [int, string]) { } -let x: Readonly<[int, string]> = [] +let x: Readonly<[int, string]> = /* @@ label2 */[] /* @@ 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]) */ +/* @@@ label2 Error TypeError: Initializer has 0 elements, but tuple requires 2 */ 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 0953054d474f4d57fee200f49df0951afa76a56d..1d321b90e4c8c89fcfe3c7f036f06e63f0993d80 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..1f44493fba932b6e4552365cd500ae4353550a14 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[]' */ +/* @@@ label Error TypeError: Type 'readonly Array' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test1.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test1.ets index 001e6dd5d9710dbb0a5fc110ccaadf2d144a3328..900402788108baae0efb5e44956f959fefaff1d1 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test1.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test1.ets @@ -14,11 +14,11 @@ */ -function foo (tuple: Readonly<[number, string, boolean]>, arr: Readonly) { +function foo (tuple: Readonly<[number, string, boolean]>, arr: ReadonlyArray) { } /* @@ label */function foo (tuple: readonly [number, string, boolean], arr: readonly int[]) { } -/* @@@ label Error TypeError: Function foo is already declared. */ +/* @@@ label Error TypeError: Function foo is already declared. */ 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..9a5de252bdd79888be26407a19c118c2a251e65e 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 @@ -35,19 +35,13 @@ let x2 : Readonly = [0] let y2 : Readonly<[int, string]> /* @@ label9 */y2[1] = "b" -/* @@@ label6 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 */ -/* @@@ label8 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 */ -/* @@@ label Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ /* @@@ 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 */ /* @@@ 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 */ +/* @@@ label6 Error TypeError: Object type doesn't have proper index access method. */ /* @@@ label7 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ +/* @@@ label8 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 fd6e6d841963f901bc18f99637d0a7901557daaf..12e4c37feda06db8e2dc233337fc66b095ca17bf 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..c19b5d8a1349594e581ffd05eb71434c29de9991 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[]' */ +/* @@@ label Error TypeError: Type 'ReadonlyArray' 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..d65a0c683f791006671f22c7a9f684f16585f4b2 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[]) */ +/* @@@ label Error TypeError: No matching call signature for foo(ReadonlyArray) */ +/* @@@ label1 Error TypeError: Type 'ReadonlyArray' 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 448f5ebcdb2c075250bdc23c61e164df822a64f9..1434abd64149fe606b64f3a8b78fe5129bd571d2 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 @@ -16,8 +16,9 @@ function foo (p: [int, string]) { } -let x: readonly [int, string] = [] +let x: readonly [int, string] = /* @@ label2 */[] /* @@ 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]) */ +/* @@@ 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 */ +/* @@@ label2 Error TypeError: Initializer has 0 elements, but tuple requires 2 */ 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..a792cb4bdde514333c1ea69eeae3a2f9c4bcc683 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 @@ -27,6 +27,5 @@ let arr = foo1() let tuple = foo2() /* @@ label1 */tuple[1] = "c" -/* @@@ 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 */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ /* @@@ 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 index b36e68e76effbfd270e363ae7267f223fdfb321c..686f313ee070e7f322ff87ed868b7a484d8be38d 100644 --- a/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets +++ b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets @@ -18,15 +18,10 @@ 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:20 Error SyntaxError: Unexpected token ':'. */ -/* @@? 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:39 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ /* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment1.ets b/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment1.ets index 573f050eacd986eb58873b6b2cd4e3ec2cacfcea..9576c6e5dca877c7bd49cd37630481f83462afc5 100644 --- a/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment1.ets +++ b/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment1.ets @@ -32,7 +32,7 @@ class B extends A { function main() { let a = new A(); - assertEQ(a.a, false); + arktest.assertEQ(a.a, false); } /* @@@ label Error TypeError: Cannot assign to this property because it is readonly. */ diff --git a/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment2.ets b/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment2.ets index 04dc1297a59d92f53f624dfae3d4741f05741b45..f97561d5aa2d11de3fa195e3704b3834573614e5 100644 --- a/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment2.ets +++ b/ets2panda/test/ast/parser/ets/readonlyGetterSetterReassignment2.ets @@ -19,7 +19,7 @@ interface I { class A implements I { readonly a: boolean - b: boolean = this.a = true; + b: boolean = /* @@ warn */this.a = true; constructor() { this./* @@ label */a = false } @@ -27,7 +27,8 @@ class A implements I { function main() { let a = new A(); - assertEQ(a.a, false); + arktest.assertEQ(a.a, false); } -/* @@@ label Error TypeError: Readonly field already initialized at declaration. */ +/* @@@ warn Warning Warning: The instance field initializer expression cannot use the this. */ +/* @@@ label Error TypeError: Readonly field already initialized at declaration. */ diff --git a/ets2panda/test/ast/parser/ets/readonly_interface_method.ets b/ets2panda/test/ast/parser/ets/readonly_interface_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..418b6c6ef1cc2ddca151538b9ab231979abba143 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonly_interface_method.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. + */ + +interface A { + readonly(): void {} +} + +/* @@? 17:5 Error SyntaxError: Modifier 'readonly' cannot be applied to an interface method. */ +/* @@? 17:13 Error SyntaxError: Expected 'method name', got '('. */ 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..bc30adc771f5a6cb3e0f7e02a2bdb6e4fb0526aa 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 @@ -14,7 +14,7 @@ */ class A { - /* @@ label */x: int = 444 + x: int = 444 } let changeAbleVar = new A(); @@ -22,11 +22,12 @@ let changeAbleVar = new A(); changeAbleVar.x=333 function bar(a:Readonly){ - a.x=111 + /* @@ label */a.x=111 console.log(a) } bar(changeAbleVar) -/* @@@ label Error TypeError: Cannot assign to a readonly variable x */ +/* @@@ label Error TypeError: Cannot assign to a readonly field x */ +/* @@@ label Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/parser/ets/readonly_union_negative.ets b/ets2panda/test/ast/parser/ets/readonly_union_negative.ets new file mode 100644 index 0000000000000000000000000000000000000000..e260f1e32d3c6fa3bf70372258603e36276ed8dd --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonly_union_negative.ets @@ -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. + */ + +// Negative test cases for readonly union types - these should fail compilation + +// Error: readonly on a non-applicable primitive type in a union +function test_negative_1(param: readonly number | string): void { +} + +// Error: readonly on a non-applicable object type in a union +class MyObject {} +function test_negative_2(param: readonly MyObject | string): void { +} + +// Error: readonly on a non-applicable type, even if another member is applicable +function test_negative_5(param: readonly boolean | string[]): void { +} + +// Error: readonly on void type +function test_negative_6(param: readonly void | number): void { +} + +// Error: readonly on function type +function test_negative_7(param: readonly (() => void) | string): void { +} + +function main(): void { + // Function calls to trigger parsing of parameter types + test_negative_1(42, "test"); + test_negative_2(new MyObject(), "test"); + test_negative_5(true, ["test"]); + test_negative_6(undefined, 42); + test_negative_7(() => {}, "test"); +} + + +/* @@? 19:49 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 24:51 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 28:50 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 32:33 Error TypeError: 'void' used as type annotation. */ +/* @@? 32:47 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 36:55 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 41:5 Error TypeError: Expected 1 arguments, got 2. */ +/* @@? 41:5 Error TypeError: No matching call signature for test_negative_1(Int, "test") */ +/* @@? 42:5 Error TypeError: Expected 1 arguments, got 2. */ +/* @@? 42:5 Error TypeError: No matching call signature for test_negative_2(MyObject, "test") */ +/* @@? 43:5 Error TypeError: Expected 1 arguments, got 2. */ +/* @@? 43:5 Error TypeError: No matching call signature for test_negative_5(Boolean, Array) */ +/* @@? 44:5 Error TypeError: Expected 1 arguments, got 2. */ +/* @@? 44:5 Error TypeError: No matching call signature for test_negative_6(undefined, Int) */ +/* @@? 45:5 Error TypeError: Expected 1 arguments, got 2. */ +/* @@? 45:5 Error TypeError: No matching call signature for test_negative_7(() => void, "test") */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/recordIndexing.ets b/ets2panda/test/ast/parser/ets/recordIndexing.ets index 15b3ad58ba68200f6dcee3ae27d871ab20e5335f..082f69e7b7736645a39549780b4702655df12d89 100644 --- a/ets2panda/test/ast/parser/ets/recordIndexing.ets +++ b/ets2panda/test/ast/parser/ets/recordIndexing.ets @@ -22,4 +22,14 @@ console.log(x[/* @@ label */0]) } -/* @@@ label Error TypeError: Cannot find index access method with the required signature. */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Boolean): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Byte): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Short): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Char): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Int): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ +/* @@? 23:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ +/* @@? 23:17 Error TypeError: No matching indexing signature for $_get(Int) */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with type 'String' at index 1 */ +/* @@@ label Error TypeError: Cannot find index access method with the required signature. */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets index 982bba0c4eaa18916905dae1346f730da524f81e..aa08c98e228a4680db9434a7ba145d4714de524d 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets @@ -17,6 +17,6 @@ function main(){ let a: Record/* @@ label */ = { "key1": 1, "key2": 2 - } + } } -/* @@@ label Error TypeError: Type Char|String is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'Char|String' should be a subtype of 'Numeric|String|BaseEnum|BaseEnum|BaseEnum'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets index 71687363c509000dd2c5b2be74b2690af8fb1d13..d65646705f1c1b92083273927b1714233eebfc16 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets @@ -19,6 +19,6 @@ function main(){ let a: Record/* @@ label */ = { 1: 1, 2: 2 - } + } } -/* @@@ label Error TypeError: Type A|Double is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'A|Double' should be a subtype of 'Numeric|String|BaseEnum|BaseEnum|BaseEnum'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets index 316c66534305e56a0e33031f5bb9c956389e0abb..5d863c0d03274bc22ff7ccfad74f884258d62fdb 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets @@ -18,4 +18,4 @@ class A{} function main(){ let a: Record/* @@ label */ } -/* @@@ label Error TypeError: Type BigInt is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'BigInt' should be a subtype of 'Numeric|String|BaseEnum|BaseEnum|BaseEnum'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/record_object_value.ets b/ets2panda/test/ast/parser/ets/record_object_value.ets index c691052402fa30d5e77b23b9ffda3b128e746831..387f895fc826f96bd7b2c93cf2968037ca72d6f8 100644 --- a/ets2panda/test/ast/parser/ets/record_object_value.ets +++ b/ets2panda/test/ast/parser/ets/record_object_value.ets @@ -48,8 +48,8 @@ function main(){ }; let errormap2:Record = { - "john":{/* @@ label2 */agee:10, salary:10}, - "Mary":{age:21, salary:10, /* @@ label3 */other:10} + "john":/* @@ label2 */{/* @@ label3 */agee:10, salary:10}, + "Mary":{age:21, salary:10, /* @@ label4 */other:10} }; let stringarraymap:Record = { @@ -57,7 +57,9 @@ function main(){ "Mary":["20", "30"] }; } -/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'double' at property 'age' */ -/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'double' at property 'salary' */ -/* @@@ label2 Error TypeError: type PersonInfoInterface has no property named agee */ -/* @@@ label3 Error TypeError: type PersonInfoInterface has no property named other */ +/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'Double' at property 'age' */ +/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'Double' at property 'salary' */ +/* @@@ label2 Error TypeError: Non-optional property 'salary' in type 'PersonInfoInterface' is missing in object literal. */ +/* @@@ label2 Error TypeError: Non-optional property 'age' in type 'PersonInfoInterface' is missing in object literal. */ +/* @@@ label3 Error TypeError: type PersonInfoInterface has no property named agee */ +/* @@@ label4 Error TypeError: type PersonInfoInterface has no property named other */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/recursive_clousre_reference_error.ets b/ets2panda/test/ast/parser/ets/recursive_clousre_reference_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..5f8630844170b3ab3329e00396dfdefa282ff038 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/recursive_clousre_reference_error.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 foo() { + let x = () => y(); + let y = () => x(); + x(); +} + +/* @@? 17:19 Error TypeError: Variable 'y' is accessed before it's initialization. */ +/* @@? 18:9 Error TypeError: Circular dependency detected for identifier: y */ diff --git a/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets b/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets new file mode 100644 index 0000000000000000000000000000000000000000..20a5b6416fbc342948adc8c88e57bb7ffd8dd2c9 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 TopLevelSym: string = "TopLevelSym"; +const InnerSym: string = "InnerSym"; + +const _topLevelFunc = (x: number | undefined): number => { + if (x === undefined) { + return 12; + } + return x; +}; + +const _innerFunc = (arg: { x: number } | undefined): number => { + if (arg === undefined) { + return 12; + } + return arg.x; +}; + +type NumberFunc = () => number; + +// Indexable type for items +type IndexableType = Record; + +// Explicitly typed indexable object +const _items: IndexableType = {}; +const innerFunction: NumberFunc = () => { + return _innerFunc({ x: 12 }); +}; + +// Fix: Assign computed property safely (done after object creation) +_items[InnerSym] = innerFunction; + +const topLevelWrapper: NumberFunc = () => { + return _topLevelFunc(12); +}; + +// Inner map using the same indexable type +const innerMap: IndexableType = {}; +const innerMapFunction: NumberFunc = () => { + const result = _innerFunc({ x: 12 }); + return result; +}; + +innerMap[InnerSym] = innerMapFunction; + +// Define the exported structure explicitly +type ExportedType = Record & { + items: IndexableType; +}; + +// Create a base object without computed properties +class ExportedStructure implements ExportedType { + items: IndexableType; + + constructor() { + this.items = innerMap; + } + + [key: string]: NumberFunc | IndexableType; + + static createBase(): ExportedType { + return new ExportedStructure() as ExportedType; + } +} + +// Create the exported structure and assign dynamic keys safely +const baseExportedStructure: ExportedType = ExportedStructure.createBase(); +const _exportedStructure: ExportedType = { ...baseExportedStructure }; + +// Assign computed key after object creation (not in literal) +_exportedStructure[TopLevelSym] = topLevelWrapper; + +const _exported: ExportedType = _exportedStructure; + +export default _exported; + +/* @@? 26:26 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 41:12 Error TypeError: No matching call signature for (...) */ +/* @@? 41:23 Error TypeError: need to specify target type for class composite */ +/* @@? 54:20 Error TypeError: No matching call signature for (...) */ +/* @@? 54:31 Error TypeError: need to specify target type for class composite */ +/* @@? 61:66 Error SyntaxError: Intersection types are not supported, use inheritance instead! */ +/* @@? 62:12 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 62:12 Error TypeError: Type name 'IndexableType' used in the wrong context */ +/* @@? 66:36 Error TypeError: Interface expected here. */ +/* @@? 73:6 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 85:1 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/required_multiple_fields.ets b/ets2panda/test/ast/parser/ets/required_multiple_fields.ets index 4f68534936f6b404b20392eb61eb942f3f66debb..4b509c3fc17962c5ad0a61db92f5cf3ea207c88a 100644 --- a/ets2panda/test/ast/parser/ets/required_multiple_fields.ets +++ b/ets2panda/test/ast/parser/ets/required_multiple_fields.ets @@ -35,6 +35,9 @@ function main() { /* @@@ label1 Error TypeError: Class property 'k' needs to be initialized for Required. */ /* @@@ label2 Error TypeError: Class property 'j' needs to be initialized for Required. */ /* @@@ label2 Error TypeError: Class property 'k' needs to be initialized for Required. */ +/* @@@ label3 Error TypeError: Non-optional property 'k' in type 'Required' is missing in object literal. */ /* @@@ label3 Error TypeError: Class property 'k' needs to be initialized for Required. */ +/* @@@ label4 Error TypeError: Non-optional property 'j' in type 'Required' is missing in object literal. */ +/* @@@ label4 Error TypeError: Non-optional property 'k' in type 'Required' is missing in object literal. */ /* @@@ label4 Error TypeError: Class property 'j' needs to be initialized for Required. */ /* @@@ label4 Error TypeError: Class property 'k' needs to be initialized for Required. */ diff --git a/ets2panda/test/ast/parser/ets/rest_never.ets b/ets2panda/test/ast/parser/ets/rest_never.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd17382ea1f90f1d379b532f9dd9097708c6ef38 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_never.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 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(...nums: number[]) { +} + +function main() { + sum(...null!) +} + +/* @@? 20:9 Error TypeError: Spread expression can be applied only to array or tuple type, but 'never' is provided */ +/* @@? 20:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/rest_no_default.ets b/ets2panda/test/ast/parser/ets/rest_no_default.ets new file mode 100644 index 0000000000000000000000000000000000000000..2964b29db0ba9ddcadaddf38749d9bf5b9c8ba51 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_no_default.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 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 = 0): number {} + +/* @@? 16:35 Error SyntaxError: Rest parameter cannot have the default value. */ +/* @@? 16:36 Error SyntaxError: Identifier is needed here. */ diff --git a/ets2panda/test/ast/parser/ets/rest_no_optional.ets b/ets2panda/test/ast/parser/ets/rest_no_optional.ets new file mode 100644 index 0000000000000000000000000000000000000000..2fe5e0e584e2cfc06bfa61e32080238af0599ef4 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_no_optional.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 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 {} + +/* @@? 17:24 Error SyntaxError: Rest parameter cannot have the default value. */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_04.ets b/ets2panda/test/ast/parser/ets/rest_parameter_04.ets index 1e574c661ded0e6b86ffb5d2adc24d69bcd3de0a..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 SyntaxError: Unexpected token 'void'. */ +/* @@@ 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 index 07cdd8b2dfe5dcd52d4b3033bcc865b0a1286e1b..53d71208a0886248013a2c68ab4204e05f1e5f78 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_05.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_05.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -19,4 +19,5 @@ function sum(...numbers: [number, number, number]): number { /* @@ 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 index 969c4fc10f95b3c5e3bc5e20d0f24d1a8fc1e208..2d75bc751833a693d8bbd69a5f7a52c8eec98461 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -19,4 +19,5 @@ function sum(...numbers: [number, number, number]): number { /* @@ label */sum(10, 20, 30, 40) -/* @@@ label Error TypeError: No matching call signature for sum(int, int, int, int) */ +/* @@@ 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 index 922f5eeac935f299b0d4ffedf6ade63efe010a42..ac4c0fed73bf20d39a094c0413a303287c2fc910 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -19,4 +19,5 @@ function sum(...numbers: [number, number, number]): number { /* @@ label1 */sum(10, 20, /* @@ label2 */"one") -/* @@@ label1 Error TypeError: No matching call signature for sum(int, int, "one") */ +/* @@@ label1 Error TypeError: No matching call signature for sum(Double, Double, "one") */ +/* @@@ label2 Error TypeError: Type '"one"' is not compatible with type 'Double' at index 3 */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets index 9d882858460e1591c26af2644159a13cb207de4c..b81323e196d5a38eb30156dd2559cbe4e92e7df8 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -22,7 +22,12 @@ function sum(a: int, ...numbers: [number, number, number]): number { /* @@ 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: No matching call signature for sum(int) */ -/* @@@ label3 Error TypeError: No matching call signature for sum(int, int, int) */ -/* @@@ label4 Error TypeError: No matching call signature for sum(int, int, int, int, int) */ +/* @@@ 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 index db49515272580f195352d5fc6fbf43f1372a47eb..c958b2efe1158870f943ef205ec0ea298cf49f8f 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_09.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_09.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -22,4 +22,5 @@ class C { /* @@ 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 index 29860c344939e6d29e8c8f667ce7367eaa50b69a..db95f4b9b072594eeaef434067e33c86eee8179a 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_10.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_10.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -22,4 +22,5 @@ class C { /* @@ 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 index 2d79df71a7415f37d2bcc309e759a9c4c9a82038..5750476b45c61d017f30953572399f04db80f51d 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_11.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_11.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -22,4 +22,5 @@ class C { /* @@ 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 index 7f8d2e5e4da93675c8dca1545f5dfa460fcf7171..5b519005961a3ddb39329fe51fa1de4cec476a01 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_12.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_12.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -24,6 +24,9 @@ class C { /* @@ 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 index 70ae141ee79208fc4d760a6faa832d4ced30bb5d..46f794926f745d3fcf69c72449cc26f3095e3e87 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_13.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_13.ets @@ -2,10 +2,10 @@ * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* +* 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. @@ -22,7 +22,7 @@ class C { constructor(...p: [A, B]) { this.field = p[0] == p[1] } - + constructor(a: int, ...p: [A, B]) { this.field = p[0] == p[1] } @@ -34,6 +34,14 @@ function main() { /* @@ 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/return_null_and_type_not_match.ets b/ets2panda/test/ast/parser/ets/return_null_and_type_not_match.ets index 33e287dff3a26cbf7b49efb7199fc1b2890d8a08..f67d3dbe0d94a7839866c8ce1335344eb5084cb7 100644 --- a/ets2panda/test/ast/parser/ets/return_null_and_type_not_match.ets +++ b/ets2panda/test/ast/parser/ets/return_null_and_type_not_match.ets @@ -22,5 +22,5 @@ function main(): int { function test():string { /* @@ label1 */return; } -/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'int' */ -/* @@@ label1 Error TypeError: Missing return value. */ +/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'Int' */ +/* @@@ label1 Error TypeError: Missing return value. */ diff --git a/ets2panda/test/ast/parser/ets/return_type_non_match.ets b/ets2panda/test/ast/parser/ets/return_type_non_match.ets index 87a0ed05ccfecf47ff5ab45b6d4617283065d164..5a8539550bb3bf72ced49fc066920bd5c765b5e3 100644 --- a/ets2panda/test/ast/parser/ets/return_type_non_match.ets +++ b/ets2panda/test/ast/parser/ets/return_type_non_match.ets @@ -15,6 +15,5 @@ function main():undefined { return false; } - /* @@? 16:4 Error TypeError: Bad return type, main enable only void or int type. */ - /* @@? 16:11 Error TypeError: Type 'boolean' is not compatible with the enclosing method's return type 'undefined' *//* @@? 16:4 Error TypeError: Bad return type, main enable only void or int type. */ -/* @@? 16:11 Error TypeError: Type 'boolean' is not compatible with the enclosing method's return type 'undefined' */ + /* @@? 16:4 Error TypeError: Bad return type, main enable only void or int type. */ +/* @@? 16:11 Error TypeError: Type 'Boolean' is not compatible with the enclosing method's return type 'undefined' */ diff --git a/ets2panda/test/ast/parser/ets/return_while_warning.ets b/ets2panda/test/ast/parser/ets/return_while_warning.ets index 5c9a15296e79a347f8dad57fdc18238f944c8f3f..08ae4d2f3a52b082999c9208b622ec843bb4c28c 100644 --- a/ets2panda/test/ast/parser/ets/return_while_warning.ets +++ b/ets2panda/test/ast/parser/ets/return_while_warning.ets @@ -15,7 +15,7 @@ function main(): void { while (false) { - assertTrue( false ); + arktest.assertTrue( false ); } } diff --git a/ets2panda/test/ast/parser/ets/segmentation_fault_test1.ets b/ets2panda/test/ast/parser/ets/segmentation_fault_test1.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5e9ad05f304c09b03cb90a973e47c8b9efd1113 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/segmentation_fault_test1.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 A(a: string) { + let b = /* @@ label */c.a; + switch (a) { + case b: + case "aa": + } +} + +/* @@@ label Error TypeError: Unresolved reference c */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/set_unexpected_nonvoid.ets b/ets2panda/test/ast/parser/ets/set_unexpected_nonvoid.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7e6f36d169ddfde8cb64ddeddccbfeb788108a2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/set_unexpected_nonvoid.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class SomeClass { + $_set (index: string): SomeClass { return this } +} + +/* @@? 17:5 Error SyntaxError: The special predefined method '$_set' should have exactly two required parameter. */ +/* @@? 17:11 Error TypeError: 'The special predefined method '$_set' should have void return type. */ diff --git a/ets2panda/test/ast/parser/ets/setter_with_return_type.ets b/ets2panda/test/ast/parser/ets/setter_with_return_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f0423da780a3e6082a00e8ad41abcf57f8fe0940 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/setter_with_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 C{ + n: number = 42 +} + +interface I{ + get n(): number + set n(v:number):void +} + +class D extends C implements I{ +} + +/* @@? 22:9 Error SyntaxError: Setter must not have return type even if it is void. */ 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/single_statement_1.ets b/ets2panda/test/ast/parser/ets/single_statement_1.ets index 7d039b4a859fad8c12fb22aa0336c889b0178e66..64d355e22c7b69d900061a2c1f7e5d21333f481e 100644 --- a/ets2panda/test/ast/parser/ets/single_statement_1.ets +++ b/ets2panda/test/ast/parser/ets/single_statement_1.ets @@ -21,5 +21,13 @@ function main(): int { } /* @@@ label1 Error SyntaxError: Lexical declaration is not allowed in single statement context. */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Boolean): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Byte): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Short): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Char): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Int): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ /* @@? 18:17 Error TypeError: Unresolved reference aaaa */ /* @@@ label2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/single_statement_2.ets b/ets2panda/test/ast/parser/ets/single_statement_2.ets index fff3b16dd2904b126ef50b6eac21e664fe0b7c7f..996fdd7fd487845d70c35809a94386d0a4b8ea2b 100644 --- a/ets2panda/test/ast/parser/ets/single_statement_2.ets +++ b/ets2panda/test/ast/parser/ets/single_statement_2.ets @@ -21,5 +21,13 @@ function main(): int { } /* @@@ label1 Error SyntaxError: Lexical declaration is not allowed in single statement context. */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Boolean): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Byte): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Short): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Char): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Int): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ +/* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ /* @@? 18:17 Error TypeError: Unresolved reference aaaa */ /* @@@ label2 Error SyntaxError: Unexpected token ')'. */ 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/spreadExpressionNotArrayType.ets b/ets2panda/test/ast/parser/ets/spreadExpressionNotArrayType.ets index b3ff23aa0882f4250bfd95c84147145b5405d453..2259dc49208c8e5bfe0fe9ea0cde14e0c51e9ed8 100644 --- a/ets2panda/test/ast/parser/ets/spreadExpressionNotArrayType.ets +++ b/ets2panda/test/ast/parser/ets/spreadExpressionNotArrayType.ets @@ -16,8 +16,8 @@ let a1: Object|null|undefined = new Object function main() { - assertEQ([...a1, new Object].length, 2); + arktest.assertEQ([...a1, new Object].length, 2); } -/* @@? 19:15 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Object|null|undefined' is provided */ +/* @@? 19:23 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Object|null|undefined' is provided */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..26483b2780137c4e697099b19173c07c0e83d3ab --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(x: number) { + console.log(x) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(1, ...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(4, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo(Int, [Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Int, Double) */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5407b76f91f8ed4787688a74ea581267c105884 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.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. + */ + +function foo(x: number) { + console.log(x) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(...args_array) + +function moo(x: number, y: number) { + console.log(x, y) +} +args_tuple = [0, 1] +/* @@ label3 */moo(1, ...args_tuple) +args_array = [2, 3] +/* @@ label4 */moo(2, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo([Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Double) */ +/* @@@ label3 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label3 Error TypeError: No matching call signature for moo(Int, [Double, Double]) */ +/* @@@ label4 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label4 Error TypeError: No matching call signature for moo(Int, Double) */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..89d5215fd1226415488589ea8be4a8376171f4aa --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.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. + */ + +function foo(x: number, y: number) { + console.log(x, y) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(...args_array) + +function moo(x: number, y: number, z: number) { + console.log(x, y, z) +} +args_tuple = [0, 1] +/* @@ label3 */moo(1, ...args_tuple) +args_array = [2, 3] +/* @@ label4 */moo(2, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo([Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Double) */ +/* @@@ label3 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label3 Error TypeError: No matching call signature for moo(Int, [Double, Double]) */ +/* @@@ label4 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label4 Error TypeError: No matching call signature for moo(Int, Double) */ diff --git a/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.ets b/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.ets index 2a6b971d872d7eac87a6a3dfe1b4be0454b952f7..346e038a118c139cdee0e38a75a5b3360deb2467 100644 --- a/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.ets +++ b/ets2panda/test/ast/parser/ets/spreadexpr_in_newexpr_neg01.ets @@ -33,6 +33,5 @@ function main() { /* @@? 19:9 Error SyntaxError: Unexpected token 'this'. */ /* @@? 19:13 Error SyntaxError: Unexpected token '.'. */ /* @@? 19:14 Error TypeError: Variable 'fld' has already been declared. */ -/* @@? 19:14 Error TypeError: Property 'fld' must be accessed through 'this' */ /* @@? 19:20 Error TypeError: Unresolved reference p */ -/* @@? 21:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 21:1 Error SyntaxError: Unexpected token '}'. */ \ No newline at end of file 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..d265e8555759d3a03bc205f29f3fe93f97c5d11f 100644 --- a/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets +++ b/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets @@ -15,9 +15,8 @@ let x = "literal str" as const -/* @@? 16:26 Error SyntaxError: Invalid Type. */ +/* @@? 16:26 Error SyntaxError: 'as const' assertion is not supported. */ /* @@? 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/switch_const_int_compare_char_duplicate.ets b/ets2panda/test/ast/parser/ets/switch_const_int_compare_char_duplicate.ets index c66c1a686aab78459026b60434c1ba90a8d2cea7..9cee2e20154530a252cefefb5aec3d02672829a5 100644 --- a/ets2panda/test/ast/parser/ets/switch_const_int_compare_char_duplicate.ets +++ b/ets2panda/test/ast/parser/ets/switch_const_int_compare_char_duplicate.ets @@ -26,4 +26,4 @@ function main() { } } -/* @@@ label Error TypeError: Variable has same value with another switch case */ +/* @@? 20:28 Error TypeError: Switch case type 'int' is not comparable to discriminant type 'char' */ diff --git a/ets2panda/test/ast/parser/ets/switch_invalid.ets b/ets2panda/test/ast/parser/ets/switch_invalid.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c72bea595dfbcfaeb807895046d27a9dddf8110 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/switch_invalid.ets @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +switch:[11](q): [12]{: [13]case: [14]1:: [15]{: [16]q: [17] +=: [18]2;: +[38]try: [39]{: [40]s: [41] +=: [42]"cba";: [43]q: [44] +=: [45]5;: [46]throw: [98] + +/* @@? 16:7 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:7 Error SyntaxError: Expected '(', got ':'. */ +/* @@? 16:7 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:7 Error TypeError: Incompatible types. Found: *ERROR_TYPE*, required: char , byte , short , int, long , Char , Byte , Short , Int, Long , String or an enum type */ +/* @@? 16:15 Error SyntaxError: Expected '{', got ':'. */ +/* @@? 16:15 Error SyntaxError: Expected ')', got ':'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token ':', expected 'case' or 'default'. */ +/* @@? 16:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:22 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:32 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:38 Error SyntaxError: Unexpected token '1'. */ +/* @@? 16:39 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:40 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:40 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:46 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:47 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:47 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:53 Error SyntaxError: Unexpected token 'q'. */ +/* @@? 16:56 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:56 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:61 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 16:63 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:69 Error SyntaxError: Unexpected token '2'. */ +/* @@? 16:71 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:71 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 17:5 Error SyntaxError: Unexpected token 'try'. */ +/* @@? 17:5 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ +/* @@? 17:8 Error SyntaxError: Expected '{', got ':'. */ +/* @@? 17:8 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token 's'. */ +/* @@? 17:24 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:29 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 17:31 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:37 Error SyntaxError: Unexpected token 'cba'. */ +/* @@? 17:43 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:49 Error SyntaxError: Unexpected token 'q'. */ +/* @@? 17:52 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:57 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 17:59 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:65 Error SyntaxError: Unexpected token '5'. */ +/* @@? 17:67 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:73 Error SyntaxError: Unexpected token 'throw'. */ +/* @@? 17:78 Error SyntaxError: Unexpected token ':'. */ +/* @@? 68:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/switch_readonly_member_enum.ets b/ets2panda/test/ast/parser/ets/switch_readonly_member_enum.ets index feec0190736ae7f2090a877dc71a61efed0d03e9..e39201f362628a0556c3179e3bb7d92a3b1ff858 100644 --- a/ets2panda/test/ast/parser/ets/switch_readonly_member_enum.ets +++ b/ets2panda/test/ast/parser/ets/switch_readonly_member_enum.ets @@ -40,5 +40,6 @@ function main() { } } + /* @@@ label Error TypeError: Enum switch case must be unqualified name of an enum constant */ /* @@@ label1 Error TypeError: Enum switch case must be unqualified name of an enum constant */ diff --git a/ets2panda/test/ast/parser/ets/switch_readonly_member_number_duplicate.ets b/ets2panda/test/ast/parser/ets/switch_readonly_member_number_duplicate.ets index f31619e73f90e6d4398b181f62067bd7c48a081d..74b1b4f4a64d1c0676faa1258c7cf49cebe0d085 100644 --- a/ets2panda/test/ast/parser/ets/switch_readonly_member_number_duplicate.ets +++ b/ets2panda/test/ast/parser/ets/switch_readonly_member_number_duplicate.ets @@ -32,4 +32,4 @@ function main() { } } -/* @@@ label Error TypeError: Variable has same value with another switch case */ +/* @@? 27:28 Error TypeError: Switch case type 'int' is not comparable to discriminant type 'char' */ 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 deleted file mode 100644 index 192d1154022dc04e469442696ee24cede0f1c252..0000000000000000000000000000000000000000 --- a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_1.ets +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function fn(): void { - let v: JSValue; - let new_prop_value: JSValue; - /* @@ 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. */ 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/this_as_array_element.ets b/ets2panda/test/ast/parser/ets/this_as_array_element.ets index 14a917048f8185047c923cf182315d32cdbdfeb4..d566aeab3fd758c01cd18b28d8b45a88529ca3b6 100644 --- a/ets2panda/test/ast/parser/ets/this_as_array_element.ets +++ b/ets2panda/test/ast/parser/ets/this_as_array_element.ets @@ -14,5 +14,8 @@ */ class Link { - a: Link[] = [this]; + a: Link[]; + constructor() { + this.a = [this]; + } } diff --git a/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets b/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b96d94e59b46f9cde64ffb081c20bbda9f22d09 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type F = () => number; + +interface I { + goo(){ + if("string" instanceof this){ + return 1 + } + return 0 + } +} + +class C { + a: T; + b: F; + constructor(a: T, b: F) { + this.a = a; + this.b = b; + } + + static hoo(){ + if (5 instanceof this) { + return 0; + } + return 1; + } + + static koo(){ + if (F instanceof this) { + return 0; + } + return 1; + } + + foo() { + if (this.a instanceof this.b) { + return 0; + } + return 1; + } + + joo() { + if (G instanceof this) { + return 0; + } + return 1; + } +} + +/* @@? 20:28 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 36:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 43:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 50:27 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 50:31 Error SyntaxError: Expected ')', got '.'. */ +/* @@? 50:31 Error SyntaxError: Unexpected token '.'. */ +/* @@? 50:32 Error SyntaxError: Unexpected token 'b'. */ +/* @@? 50:32 Error TypeError: Property 'b' must be accessed through 'this' */ +/* @@? 50:33 Error SyntaxError: Unexpected token ')'. */ +/* @@? 50:35 Error SyntaxError: Unexpected token '{'. */ +/* @@? 57:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ diff --git a/ets2panda/test/ast/parser/ets/too_many_expression.ets b/ets2panda/test/ast/parser/ets/too_many_expression.ets index 6b51d785426e8a069a4a9ce562edf78440ce24f6..3588b1597785bc417f2e55bfbf2565768b8caee3 100644 --- a/ets2panda/test/ast/parser/ets/too_many_expression.ets +++ b/ets2panda/test/ast/parser/ets/too_many_expression.ets @@ -15,1028 +15,5 @@ (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( -/* @@? 16:1025 Error SyntaxError: Maximum allowed nesting level exceeded. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 1043:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:513 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..d2ec51613e8280210c80070ec230b269e16271a1 100644 --- a/ets2panda/test/ast/parser/ets/trailing_comma_2.ets +++ b/ets2panda/test/ast/parser/ets/trailing_comma_2.ets @@ -19,8 +19,8 @@ class C { let a = new C(12,) -/* @@@ label1 Error SyntaxError: Unexpected token ','. */ +/* @@@ 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: 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) */ +/* @@? 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..f4837d017aa5bb4e1be686cf73810c7baf22894c --- /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(Double, "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/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await.ets new file mode 100644 index 0000000000000000000000000000000000000000..d027186f56b1d9756629052fd19ff1497bc70cfc --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await.ets @@ -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. + */ + +async WeakMap => ...delete const { } + +/* @@? 16:7 Error SyntaxError: 'async' flags must be used for functions only at top-level. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:28 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 16:28 Error SyntaxError: Rest parameter must be the last formal parameter. */ diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await_fuzz.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await_fuzz.ets new file mode 100644 index 0000000000000000000000000000000000000000..6cf13fb5c69a9f6874db79babbf3b307eca7fd3e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_await_fuzz.ets @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +async WeakMap => ...delete const { Intl } = [ { opt } = [({} ? 4 : Array[-=])]; +, ... || new ({.: 0}[])(,{: 88}["-1"]), ...opt, (7 ? : null)][true[( ? 5 : {}.arity.E)]]; + >>>= sub(await delete await ArrayBuffer ^= await delete ) __a:be +} + + +/* @@? 16:7 Error SyntaxError: 'async' flags must be used for functions only at top-level. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 16:15 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:28 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 16:28 Error SyntaxError: Rest parameter must be the last formal parameter. */ +/* @@? 16:43 Error SyntaxError: Unexpected token '='. */ +/* @@? 16:43 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:74 Error SyntaxError: Unexpected token '-='. */ +/* @@? 16:79 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 17:1 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:3 Error SyntaxError: Unexpected token '...'. */ +/* @@? 17:15 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 17:16 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:17 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:19 Error SyntaxError: Unexpected token '0'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:23 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:23 Error TypeError: This expression is not callable. */ +/* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 17:25 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:27 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:29 Error SyntaxError: Unexpected token '88'. */ +/* @@? 17:38 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:39 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:41 Error SyntaxError: Unexpected token '...'. */ +/* @@? 17:44 Error SyntaxError: Unexpected token 'opt'. */ +/* @@? 17:44 Error TypeError: Unresolved reference opt */ +/* @@? 17:47 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:47 Error TypeError: This expression is not callable. */ +/* @@? 17:55 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:57 Error SyntaxError: Unexpected token. */ +/* @@? 17:62 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:62 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 17:71 Error SyntaxError: Unexpected token '?'. */ +/* @@? 17:73 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 17:75 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 17:77 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 17:78 Error SyntaxError: Unexpected token '}'. */ +/* @@? 17:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:88 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:89 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:2 Error SyntaxError: Unexpected token '>>>='. */ +/* @@? 18:7 Error SyntaxError: Unexpected token 'sub'. */ +/* @@? 18:7 Error TypeError: Unresolved reference sub */ +/* @@? 18:24 Error SyntaxError: Unexpected token 'await'. */ +/* @@? 18:24 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:24 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 18:24 Error TypeError: Type 'ArrayBuffer' can not be awaited, it is not a Promise. */ +/* @@? 18:30 Error SyntaxError: Class cannot be used as object. */ +/* @@? 18:42 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 18:58 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:60 Error TypeError: Unresolved reference missing */ +/* @@? 18:68 Error SyntaxError: Unexpected token ''. */ +/* @@? 18:68 Error SyntaxError: Newline is not allowed in strings */ +/* @@? 18:69 Error SyntaxError: Unexpected token '}'. */ +/* @@? 18:69 Error SyntaxError: Unexpected token '> __a:be'. */ +/* @@? 18:69 Error SyntaxError: Newline is not allowed in strings */ diff --git a/ets2panda/test/ast/parser/ets/launch_unresolved.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_rest_as_trailing_lambda.ets similarity index 80% rename from ets2panda/test/ast/parser/ets/launch_unresolved.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_rest_as_trailing_lambda.ets index 7f687e888e2ca9a9617285dc4e4917ecc7420826..ac028631f889e1cf65524e219120082ad86f174a 100644 --- a/ets2panda/test/ast/parser/ets/launch_unresolved.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/invalid_rest_param_for_rest_as_trailing_lambda.ets @@ -13,8 +13,9 @@ * limitations under the License. */ -function main(): void { - launch /* @@ label */foo(5); +class A { + foo(...n: (()=>void)[] ) {} } +new A().foo( ()=>{} ){} -/* @@@ label Error TypeError: Unresolved reference foo */ +/* @@? 19:1 Error TypeError: No matching call signature with trailing lambda */ diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw.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/trailing_lambda_tests/trailing_lambda_with_throw.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_2.ets index e47cfcff81eccc717ce9ee1bc6b7ed5366d67bbc..90b3b80d959b2bfe5490e434999877e930b197af 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_2.ets @@ -13,22 +13,14 @@ * limitations under the License. */ -function foo(c: ()=>void throws) { -} - -function foo2(c: ()=>void) { +function f(c?: ()=>void) { + c?.(); } function main() { - foo() { - throw new Error(); + f() { + return /* @@ label */1 } - - foo() {} - - foo2() { - throw new Error(); - } - - foo2() {} } + +/* @@@ label Error TypeError: Unexpected return value, enclosing method return type is void. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_1_neg.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.ets similarity index 74% rename from ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_1_neg.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.ets index c29473759b9c2c045f362a56710bf22a2a7fafb5..295914248459f181e41b669cb37920770fca774b 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_1_neg.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.ets @@ -13,9 +13,14 @@ * limitations under the License. */ +class A { + constructor (a0?: () => void){ + + } +} + function main(): void { - const tuple: [number, number, boolean] = [1, 3.14, true] - const array: (number|boolean) [] = tuple + new A() { console.print(2); }; // It is forbidden to extend a class by an anonymous class } -/* @@? 18:40 Error TypeError: Type '[double, double, boolean]' cannot be assigned to type '(Double|Boolean)[]' */ +/* @@? 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/runtime/ets/optional_primitive.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets similarity index 85% rename from ets2panda/test/runtime/ets/optional_primitive.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets index 3ef1125541bbd29788940eb132d3b67562c95008..17fcdb4c5028d31447aaac1d9a719451073ea734 100644 --- a/ets2panda/test/runtime/ets/optional_primitive.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets @@ -13,7 +13,12 @@ * limitations under the License. */ +function f(c?: ()=>void) { + c?.(); +} + function main() { - let a ?: number = 1 - assertEQ(a, 1) -} \ No newline at end of file + f(); { + console.println("I am call back!") + } +} diff --git a/ets2panda/test/ast/parser/ets/variable_throw_function_2.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets similarity index 77% rename from ets2panda/test/ast/parser/ets/variable_throw_function_2.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets index 1c151d7bb23fa0b4504f5a71f429c0f69e830deb..b80f49af56e3aee922324335216786f159c1d086 100644 --- a/ets2panda/test/ast/parser/ets/variable_throw_function_2.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets @@ -13,11 +13,14 @@ * limitations under the License. */ -function foo() : void throws {} +class A { + constructor (a0?: () => void){ -function main(): void { - let non_throwing: () => void = foo; + } } -/* @@? 19:36 Error TypeError: Type '() => void throws' cannot be assigned to type '() => 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/runtime/ets/statement_after_local_class.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets similarity index 78% rename from ets2panda/test/runtime/ets/statement_after_local_class.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets index 6b000813b015b274e3349a7932f7262794fd96c0..b168957e53cb22071af037a4ae3e4ea00ebc405b 100644 --- a/ets2panda/test/runtime/ets/statement_after_local_class.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets @@ -13,17 +13,14 @@ * limitations under the License. */ -function main(): void { - class MyClass { - constructor() { - } +class A { + constructor (a0?: () => void){ - foo(): number { - return 1.0 - } } +} - let m = new MyClass() - - assertEQ(m.foo(), 1.0) +function main(): void { + new A {}; // It is forbidden to extend a class by an anonymous class } + +/* @@? 23:11 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_1.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_1.ets index ed9a71e41b2f629280be0f58336c00f3a163916d..7bf5655f13fa10d9d5b3835204fd0e6d792b6d0b 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_1.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_1.ets @@ -36,10 +36,14 @@ function foo2(): int { function foo3(): int { try { return 0; - } catch (e: ArithmeticError) { - return 1; - } catch (e: ClassCastError) { - return 2; + } catch (e) { + if (e instanceof ArithmeticError) { + return 1; + } else if (e instanceof ClassCastError) { + return 2; + } else { + return 3; + } } } diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_4.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_4.ets index 902d8511e6396423e26357d6c944828ba96795ad..f578fdd2cf7ed54641f7bf16d6bae77840580ec2 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_4.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_4.ets @@ -16,10 +16,11 @@ function /* @@ label */foo(): int { try { return 0; - } catch (e: ArithmeticError) { - - } catch (e: ClassCastError) { - return 2; + } catch (e) { + if (e instanceof ArithmeticError) { + } else if (e instanceof ClassCastError) { + return 2; + } } } 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 efd161568ce1a49ade7948dc0034b2cc98aff744..f2328e1f53d21dc457c263e3ed53622b4ff577dc 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets @@ -16,11 +16,13 @@ function foo(): int { try { return 0; - } catch (e: ArithmeticError) { - return 1; - /* @@ label */let a = 2; // unreachable statement - } catch (e: ClassCastError) { - return 2; + } catch (e) { + if (e instanceof ArithmeticError) { + return 1; + /* @@ label */let a = 2; // unreachable statement + } else { + return 2; + } } } diff --git a/ets2panda/test/ast/parser/ets/ts-type-assertion.ets b/ets2panda/test/ast/parser/ets/ts-type-assertion.ets new file mode 100644 index 0000000000000000000000000000000000000000..19a04aa602008f3e88724508f6c9eb865a393832 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/ts-type-assertion.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. + */ + +const a = 1; +type t = number; +const b = a; +const c = foo; +const d = (foo); +const e = (foo); +const f = foo; +/* @@? 18:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 19:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 20:12 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 21:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 22:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 22:14 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ diff --git a/ets2panda/test/ast/parser/ets/tsas_binop.ets b/ets2panda/test/ast/parser/ets/tsas_binop.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bf78fdde5bb57698fd840c812006329b50382ed --- /dev/null +++ b/ets2panda/test/ast/parser/ets/tsas_binop.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. + */ + +enum test{ + a, +} + +function main():void{ + (1.0 as test) == test.a +} + +/* @@? 21:6 Error TypeError: Type 'Double' is not compatible with type 'Int' at index 1 */ +/* @@? 21:6 Error TypeError: No matching call signature for fromValue(Double) */ +/* @@? 21:6 Warning Warning: Enum cast is deprecated. Cast support from 'Double' to 'test' will be removed. */ 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_alias_invalid_name.ets b/ets2panda/test/ast/parser/ets/type_alias_invalid_name.ets new file mode 100644 index 0000000000000000000000000000000000000000..9caf26990c93f8ae4566dd5537faf3f4118016d9 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_alias_invalid_name.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. + */ + +type var = number[] + +/* @@? 16:6 Error SyntaxError: Type alias name cannot be 'var'. */ 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_decution_unnecessary_boxing.ets b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets index 6504bba42380f004042a2ae22abfef9c389c33c6..dd9a087cf63df08ba64a74a2b68fe8c20f289887 100644 --- a/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets +++ b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets @@ -19,5 +19,6 @@ x = true ? x:():long=>32 let y:()=>int = ()=>16 as int y = true ? y:():int=>32 y = true ? ():int=>32:y -x = /* @@ label */true ? x:"apple" -/* @@@ label Error TypeError: Type '() => Long|"apple"' cannot be assigned to type '() => Long' */ \ No newline at end of file +x = /* @@ forbid_aggresive_constf */true ? x:"apple" + +/* @@@ forbid_aggresive_constf Error TypeError: Type '() => Long|"apple"' cannot be assigned to type '() => Long' */ 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..302df199c40c3d41f1b57b8ee0dc5297a3133463 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_never_literal_keyof.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 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(); + } + + /* @@? 18:4 Error SyntaxError: Illegal start of Type Alias expression. */ + /* @@? 19:30 Error TypeError: Cannot find type 'keyofType'. */ \ 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..dd7dd59374f7b8d5957cc0806b7d318a3f341edd --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_utility_type.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 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>>(); + } + + /* @@? 30:19 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 17:37 Error TypeError: T in Partial must be a class or an interface type. */ +/* @@? 21:39 Error TypeError: T in Required must be a class or an interface type. */ +/* @@? 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 argument 'Array' should be a subtype of 'Numeric|String|BaseEnum|BaseEnum|BaseEnum'-constraint */ +/* @@? 32:38 Error TypeError: Type argument 'Array' should be a subtype of 'Numeric|String|BaseEnum|BaseEnum|BaseEnum'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/type_node_clone_assertion_fix.ets b/ets2panda/test/ast/parser/ets/type_node_clone_assertion_fix.ets new file mode 100644 index 0000000000000000000000000000000000000000..911938c62612630527a555580a31ace6a126b3d1 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_node_clone_assertion_fix.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. + */ + +// Minimal test case for TypeNode::Clone() fix +// Previously caused: ASSERTION FAILED: clonedNode != typeAliasNode->TypeAnnotation() +// in ValidateGenericTypeAliasForClonedNode at validateHelpers.cpp:242 + +// This specific pattern triggered the assertion failure because TypeNode::Clone() +// was returning 'this' instead of creating a proper clone when TsType() was nullptr +type MyMap = { + kind: K +}; + +type RecordMap = { n: number }; + +// Expected compilation errors for unsupported TypeScript features in ETS: +/* @@? 22:37 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 22:41 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 26:18 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/type_param_contraint_override.ets b/ets2panda/test/ast/parser/ets/type_param_contraint_override.ets index 5df4c88d2f91fdeae8fd5ee2cc2d82aa48eed1a1..e679c92132e889c86487d773268d828a44bbc027 100644 --- a/ets2panda/test/ast/parser/ets/type_param_contraint_override.ets +++ b/ets2panda/test/ast/parser/ets/type_param_contraint_override.ets @@ -29,7 +29,7 @@ class B extends A { function main() { new B().foo(new B()) - assertEQ(res, 2); + arktest.assertEQ(res, 2); } /* @@? 25:17 Error TypeError: foo(x: T): void in B cannot override foo(x: T): void in A because overriding type parameter's conatraints are not compatible with type parameter constraints of the overridden method. */ diff --git a/ets2panda/test/ast/parser/ets/type_references.ets b/ets2panda/test/ast/parser/ets/type_references.ets index b02b398e0f6154314e44eb33677ad5968785093c..4659ad2318d3ba2c6233d479ebf8516b534424c4 100644 --- a/ets2panda/test/ast/parser/ets/type_references.ets +++ b/ets2panda/test/ast/parser/ets/type_references.ets @@ -20,16 +20,4 @@ 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: 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: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 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'. */ +/* @@? 19:10 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ diff --git a/ets2panda/test/ast/parser/ets/type_variance2.ets b/ets2panda/test/ast/parser/ets/type_variance2.ets index 67d7a48464199ebb03ddf3328a46bac9afb687b6..c7b077b0b6d2ae67d8c467c912f2edf81e0ec8e9 100644 --- a/ets2panda/test/ast/parser/ets/type_variance2.ets +++ b/ets2panda/test/ast/parser/ets/type_variance2.ets @@ -18,3 +18,4 @@ class C { } /* @@@ label Error SyntaxError: Variance modifier is not allowed here. */ +/* @@? 17:35 Error SyntaxError: Constructor should not have type parameters. */ diff --git a/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets b/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe8f7863b73df4a4f792977e2cb8fb7ac5b987de --- /dev/null +++ b/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Focused test case for BrokenTypeNode::Clone() implementation +// This test specifically exercises the BrokenTypeNode cloning that was causing +// the "ASSERTION FAILED: clonedNode != typeAliasNode->TypeAnnotation()" crash + +// This creates BrokenTypeNode instances during parsing due to invalid TypeScript syntax +type BrokenType = { + kind: K +}; + +// Multiple instances to test different patterns +type AnotherBroken = T; +type YetAnother = U; + +// Nested broken types +type NestedBroken = { + nested: K, + value: UndefinedType[K] +}; + +// Function with broken parameter types +type BrokenFunc = (param: T) => void; + +// Test instantiation to trigger ValidateGenericTypeAliasForClonedNode +declare const broken1: BrokenType; +declare const broken2: AnotherBroken; + +/* @@? 21:33 Error TypeError: Cannot find type 'UndefinedMap'. */ +/* @@? 21:45 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 21:49 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 26:36 Error TypeError: Cannot find type 'NonExistent'. */ +/* @@? 26:47 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 27:27 Error TypeError: Cannot find type 'InvalidInterface'. */ +/* @@? 30:52 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 31:14 Error SyntaxError: Unexpected token ','. */ +/* @@? 32:26 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 32:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 32:27 Error SyntaxError: Unexpected token ']'. */ +/* @@? 36:27 Error TypeError: Cannot find type 'UndefinedInterface'. */ +/* @@? 39:35 Error TypeError: Cannot find type 'xny'. */ +/* @@? 40:38 Error TypeError: Cannot find type 'xny'. */ diff --git a/ets2panda/test/ast/parser/ets/typenode_clone_comprehensive.ets b/ets2panda/test/ast/parser/ets/typenode_clone_comprehensive.ets new file mode 100644 index 0000000000000000000000000000000000000000..069c51fb2f2b65c77959c4bb1af9b5001bce86c7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/typenode_clone_comprehensive.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. + */ + +// Comprehensive test case for TypeNode::Clone() implementations +// This test covers all TypeNode subclasses that were missing Clone implementations +// and caused assertion failures in ValidateGenericTypeAliasForClonedNode + +// Test 1: TSTypeLiteral Clone +type ObjectType = { n: number, s: string, b: boolean }; + +// Test 2: TSNumberKeyword, TSStringKeyword, TSBooleanKeyword Clone +type NumType = number; +type StrType = string; +type BoolType = boolean; + +// Test 3: TSVoidKeyword Clone (in function types) +type VoidFunc = () => void; + +// Test 4: TSTypeOperator Clone (keyof operations) +type KeyofType = T; + +// Test 5: TSIndexedAccessType Clone +type IndexedType = ObjectType[K]; + +// Test 6: TSTupleType Clone +type TupleType = [a: number, b: string]; + +// Test 7: TSMappedType Clone +type MappedType = { [K in keyof ObjectType]: string }; + +// Test 8: TSFunctionType Clone +type FuncType = (v: ObjectType[K]) => void; + +// Test 9: TSLiteralType Clone (string literals) +type LiteralType = K; + +// Test 10: TSUnionType Clone +type UnionType = string | number | boolean; + +// Test 11: BrokenTypeNode Clone (created for invalid syntax) +// This will create BrokenTypeNode instances that need proper cloning +type InvalidType = K; + +// Test 12: Complex nested type with multiple Clone implementations +type ComplexType = { + kind: K, + value: ObjectType[K], + handler: (v: ObjectType[K]) => void, + tuple: [K, ObjectType[K]], + mapped: { [P in K]: ObjectType[P] } +}; + +// Test instantiation to trigger ValidateGenericTypeAliasForClonedNode +declare const test1: ComplexType<'n'>; +declare const test2: ComplexType<'s'>; +declare const test3: ComplexType<'b'>; + +/* @@? 1:3 Error TypeError: Class 'TupleType' is already defined with different type. */ +/* @@? 1:3 Error TypeError: Class 'UnionType' is already defined with different type. */ +/* @@? 21:19 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 21:30 Error SyntaxError: Unexpected token ','. */ +/* @@? 21:41 Error SyntaxError: Unexpected token ','. */ +/* @@? 32:42 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 35:44 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 35:59 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 35:59 Error SyntaxError: Unexpected token ']'. */ +/* @@? 35:60 Error SyntaxError: Unexpected token ']'. */ +/* @@? 38:19 Error TypeError: Cannot find type 'a'. */ +/* @@? 38:20 Error SyntaxError: Unexpected token ':'. */ +/* @@? 38:20 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 38:22 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 38:22 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 38:28 Error SyntaxError: Unexpected token ','. */ +/* @@? 38:30 Error SyntaxError: Unexpected token 'b'. */ +/* @@? 38:33 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 38:33 Error TypeError: Type name 'string' used in the wrong context */ +/* @@? 38:39 Error SyntaxError: Unexpected token ']'. */ +/* @@? 41:19 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 41:22 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 41:26 Error SyntaxError: Field type annotation expected. */ +/* @@? 41:32 Error SyntaxError: Field type annotation expected. */ +/* @@? 41:43 Error SyntaxError: Unexpected token ']'. */ +/* @@? 41:43 Error SyntaxError: Field type annotation expected. */ +/* @@? 41:44 Error SyntaxError: Unexpected token ':'. */ +/* @@? 41:46 Error SyntaxError: string is a predefined type, cannot be used as an identifier */ +/* @@? 44:41 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 44:60 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 54:34 Error TypeError: Cannot find type 'InvalidMap'. */ +/* @@? 54:44 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 57:45 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 57:63 Error TypeError: The `keyof` keyword can only be used for class or interface type. */ +/* @@? 57:67 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 58:12 Error SyntaxError: Unexpected token ','. */ +/* @@? 59:23 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 59:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 59:24 Error SyntaxError: Unexpected token ']'. */ +/* @@? 59:25 Error SyntaxError: Unexpected token ','. */ +/* @@? 60:29 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 60:40 Error SyntaxError: Unexpected token ','. */ +/* @@? 61:27 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 61:28 Error SyntaxError: Unexpected token ']'. */ +/* @@? 61:29 Error SyntaxError: Unexpected token ']'. */ +/* @@? 61:30 Error SyntaxError: Unexpected token ','. */ +/* @@? 62:13 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 62:16 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 62:20 Error SyntaxError: Field type annotation expected. */ +/* @@? 62:22 Error SyntaxError: Unexpected token ']'. */ +/* @@? 62:22 Error SyntaxError: Field type annotation expected. */ +/* @@? 62:23 Error SyntaxError: Unexpected token ':'. */ +/* @@? 62:35 Error SyntaxError: Field type annotation expected. */ +/* @@? 62:36 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 62:37 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/typenode_clone_primitives.ets b/ets2panda/test/ast/parser/ets/typenode_clone_primitives.ets new file mode 100644 index 0000000000000000000000000000000000000000..2cce27da50794b50a4af00d6506dadd9a932e9fd --- /dev/null +++ b/ets2panda/test/ast/parser/ets/typenode_clone_primitives.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. + */ + +// Focused test case for primitive TypeNode Clone implementations +// Tests TSNumberKeyword, TSStringKeyword, TSBooleanKeyword, TSVoidKeyword cloning + +// Simple primitive type aliases that exercise Clone +type NumAlias = T; +type StrAlias = T; +type BoolAlias = T; +type VoidAlias = T; + +// Generic constraints using primitives +type NumericConstraint = T; +type StringConstraint = T; +type BooleanConstraint = T; + +// Function types with primitive returns (exercises TSVoidKeyword) +type VoidFunction = (param: T) => void; +type NumberFunction = (param: T) => number; +type StringFunction = (param: T) => string; +type BooleanFunction = (param: T) => boolean; + +// Complex types mixing primitives +type MixedType = { + numField: N, + strField: S, + boolField: B, + voidMethod: () => void +}; + +// Test instantiation to trigger ValidateGenericTypeAliasForClonedNode +declare const num: NumAlias<42>; +declare const str: StrAlias<"test">; +declare const bool: BoolAlias; + +/* @@? 37:73 Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@? 38:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 39:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 40:17 Error SyntaxError: Unexpected token ','. */ +/* @@? 45:29 Error SyntaxError: Invalid Type. */ +/* @@? 45:29 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 45:29 Error SyntaxError: Unexpected token '>'. */ +/* @@? 45:32 Error SyntaxError: Unexpected token ';'. */ +/* @@? 47:31 Error SyntaxError: Invalid Type. */ +/* @@? 47:31 Error SyntaxError: Unexpected token, expected '>'. */ +/* @@? 47:31 Error SyntaxError: Unexpected token '>'. */ +/* @@? 47:36 Error SyntaxError: Unexpected token ';'. */ diff --git a/ets2panda/test/ast/parser/ets/typeof_in_annotation.ets b/ets2panda/test/ast/parser/ets/typeof_in_annotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ab98e4b5510f88e510b477c9f16a13dacdfec91 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/typeof_in_annotation.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. + */ + +let n1 = 42 +let s1 = "foo" +let n2: typeof n1 +let s2: typeof s1 + +/* @@? 18:16 Error SyntaxError: Result of 'typeof' operator is not supported to be used as type annotation. */ +/* @@? 18:16 Error SyntaxError: Unexpected token 'n1'. */ +/* @@? 19:16 Error SyntaxError: Result of 'typeof' operator is not supported to be used as type annotation. */ +/* @@? 19:16 Error SyntaxError: Unexpected token 's1'. */ diff --git a/ets2panda/test/ast/parser/ets/types_decls.ets b/ets2panda/test/ast/parser/ets/types_decls.ets index f9455917b72f59db97f4f2db022d91dbe05255c8..07eedb43d239c1de61878bc418c86c7169727375 100644 --- a/ets2panda/test/ast/parser/ets/types_decls.ets +++ b/ets2panda/test/ast/parser/ets/types_decls.ets @@ -56,9 +56,11 @@ let non_prim_c: Char = c'b'; // see 3.1.5 Void type function v(): void {} -/* @@@ label Error TypeError: Variable 'prim_b' has already been declared. */ +/* @@? 35:21 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ +/* @@? 36:25 Error TypeError: Type 'Double' cannot be assigned to type 'Float' */ +/* @@@ label Error TypeError: Variable 'prim_b' has already been declared. */ /* @@? 45:27 Error TypeError: Cannot find type 'bool'. */ -/* @@? 45:34 Error TypeError: Type 'boolean' cannot be assigned to type 'byte' */ +/* @@? 45:34 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ /* @@? 46:5 Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 46:17 Error TypeError: Cannot find type 'Bool'. */ -/* @@? 46:24 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ +/* @@? 46:24 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ diff --git a/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl.ets b/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl.ets new file mode 100644 index 0000000000000000000000000000000000000000..633a00e7acf11705dee0444b85999910e74c4dfb --- /dev/null +++ b/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl.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 o: /* @@ label */{ x: number/* @@ label2 */, y: number } = { x: 2, y: 3 } + +/* @@@ label Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@@ label2 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl_2.ets b/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..dbbd45161ef1d205c44b95782ab7aa0df2c03554 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/types_no_object_lit_to_decl_2.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. + */ + +type S = Set + +/* @@@ label Error SyntaxError: Using object literals to declare types in place is not supported. Please declare types and interfaces explicitly! */ +/* @@@ label2 Error SyntaxError: Unexpected token ','. */ 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_16.ets b/ets2panda/test/ast/parser/ets/unexpected_token_16.ets index 0107468659b21a9249154ef3ce324a3a6b97bbee..4ed6781a78e42174017e681abed4f011348056da 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_16.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_16.ets @@ -26,7 +26,7 @@ function main(): void { /* @@ label */break case 2: break - default: assertTrue(false, "Not expected execution here"); + default: arktest.assertTrue(false, "Not expected execution here"); } } } diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_17.ets b/ets2panda/test/ast/parser/ets/unexpected_token_17.ets index f7f768078f2c8724544a518f5f9b900011e6360c..436b195007b1ed2820ca7323ecbc7afc55d77cdd 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_17.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_17.ets @@ -26,7 +26,7 @@ function main(): void { break case 2: break - default: assertTrue(false, "Not expected execution here"); + default: arktest.assertTrue(false, "Not expected execution here"); } } } diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_18.ets b/ets2panda/test/ast/parser/ets/unexpected_token_18.ets index 13f623d0590814de37a3aaec2bff3beb4cc2b536..9ca9cf1006f7ef9a110da298f2bdc73709ab8173 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_18.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_18.ets @@ -13,8 +13,6 @@ * limitations under the License. */ -try {} catch (e: number) /* @@ label */} +try {} catch (e) /* @@ 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_20.ets b/ets2panda/test/ast/parser/ets/unexpected_token_20.ets index c6d1838c2db549c89a240fd9540b5f315a1264b3..916eadf031f33e454509f83bf76db591d822e53b 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_20.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_20.ets @@ -13,7 +13,6 @@ * limitations under the License. */ -try {} catch /* @@ label */e: number) {} finally {} +try {} catch /* @@ label */e) {} finally {} /* @@@ label Error SyntaxError: Expected '(', got 'identification literal'. */ -/* @@? 16:28 Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_22.ets b/ets2panda/test/ast/parser/ets/unexpected_token_22.ets index 156fad0c17fc3641010fbaf422355d0944cc7814..19b5147c4de18673c8d759894dbfbfc38afa47a0 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_22.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_22.ets @@ -27,9 +27,9 @@ function callAsyncLambda(): void { is_call_async_lambda = true; } - assertEQ(is_call_async_lambda, false); + arktest.assertEQ(is_call_async_lambda, false); await async_lambda(); - assertEQ(is_call_async_lambda, true); + arktest.assertEQ(is_call_async_lambda, true); } function main(): void { @@ -40,6 +40,3 @@ function main(): void { /* @@? 25:43 Error TypeError: Type '(_: Promise) => Promise' cannot be assigned to type '() => Promise' */ /* @@? 25:44 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 25:60 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 31:11 Error TypeError: Expected 1 arguments, got 0. */ -/* @@? 31:11 Error TypeError: No matching call signature */ -/* @@? 31:11 Error TypeError: 'await' expressions require Promise object as argument. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_24.ets b/ets2panda/test/ast/parser/ets/unexpected_token_24.ets index 268f21486c0fd11ef3bb33e72914e08aea73e14b..e2d0fa6af69635727945be0c8de612c57d282ad0 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_24.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_24.ets @@ -22,7 +22,7 @@ function main(): void { break case 2: break - default: assertTrue(false, "Not expected execution here"); + default: arktest.assertTrue(false, "Not expected execution here"); } } } 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..b2c42936faed3a9b1d79437fe74fe213f925a6b3 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. */ +/* @@? 17:44 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 3d6c57802d136ff181810d00a4d676d699e82929..01374410c399cf735780f40ecf9857927f864423 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets @@ -18,15 +18,14 @@ function foo(...^number: int[]): int { } /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 16:17 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 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 SyntaxError: Unexpected token '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 */ /* @@? 17:12 Error TypeError: Indexed access is not supported for such expression type. */ 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_33.ets b/ets2panda/test/ast/parser/ets/unexpected_token_33.ets index 7962f1d583dacf19f693a693de78de91ad621067..4041748031eb3917e2e8a0a0333a1d1d1c8a3a27 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_33.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_33.ets @@ -17,8 +17,8 @@ class G /* @@ label */T/* @@ label1 */, S /* @@ label2 */extends T/* @@ label3 * /* @@@ label Error SyntaxError: Expected '{', got 'identification literal'. */ /* @@@ label1 Error SyntaxError: Unexpected token ','. */ -/* @@@ label2 Error SyntaxError: Field type annotation expected. */ +/* @@? 16:42 Error SyntaxError: Field type annotation expected. */ /* @@@ label2 Error SyntaxError: Unexpected token 'extends'. */ -/* @@@ label3 Error SyntaxError: Field type annotation expected. */ +/* @@? 16:67 Error SyntaxError: Field type annotation expected. */ /* @@@ label3 Error SyntaxError: Unexpected token '>'. */ /* @@@ label4 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_35.ets b/ets2panda/test/ast/parser/ets/unexpected_token_35.ets index 92a6f2526e978b24d7b4202409bfd30b84c00fa8..c9915a5fa696322dd2c6ec6c24cc148a94884033 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_35.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_35.ets @@ -25,11 +25,9 @@ let sector: float }; } -/* @@? 20:12 Error TypeError: Target type for class composite needs to be an object type, found 'float' */ +/* @@? 21:5 Error TypeError: type Float has no property named radius */ /* @@? 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 d9bc05814bdace6e19962dc2acde91403958f861..742ce91981051144e90a977664d73ad99940f48f 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_36.ets @@ -36,15 +36,7 @@ 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 SyntaxError: Expected ')', got 'int'. */ /* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 29:20 Error SyntaxError: Unexpected token '='. */ -/* @@? 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..780e05d9629c60f9001974f4d2513e40cda83429 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_38.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_38.ets @@ -23,12 +23,9 @@ 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 '('. */ -/* @@? 22:51 Error SyntaxError: Invalid Type. */ -/* @@? 22:51 Error SyntaxError: Unexpected token '('. */ +/* @@? 22:51 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 22:53 Error SyntaxError: Unexpected token 'number'. */ /* @@? 22:62 Error SyntaxError: Unexpected token '=>'. */ /* @@? 22:62 Error SyntaxError: Unexpected token. */ -/* @@? 22:96 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_41.ets b/ets2panda/test/ast/parser/ets/unexpected_token_41.ets index a0c32d6a6f75165377c524a79cb84f1d8ee3f086..40e2093999804fc0de7c2be2c6f293e4f1a95d2f 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_41.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_41.ets @@ -17,9 +17,8 @@ for (let i: int = 0; i < d?length/* @@ label */; ++i/* @@ label1 */) { arr.push(d[i]); } -/* @@? 16:22 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 16:26 Error TypeError: Unresolved reference d */ /* @@? 16:28 Error TypeError: Unresolved reference length */ -/* @@? 16:48 Error SyntaxError: Unexpected token, expected ':'. */ -/* @@? 16:68 Error SyntaxError: Expected ';', got ')'. */ +/* @@@ label Error SyntaxError: Unexpected token, expected ':'. */ +/* @@@ label1 Error SyntaxError: Expected ';', got ')'. */ /* @@? 17:5 Error TypeError: Unresolved reference arr */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_42.ets b/ets2panda/test/ast/parser/ets/unexpected_token_42.ets index 13d4a9c28345ded93a24b8c70f2f453fb4865017..7d02e8a0d86580dace30a943bda8d11d344f709a 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 'Array' 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..28f196a0b8551588190a7e8d924353e9d892a7a7 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 '}'. */ +/* @@? 16:71 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_52.ets b/ets2panda/test/ast/parser/ets/unexpected_token_52.ets index b447ab92d520874dc11995c29a7c4d1c8fd66ce7..9b65b55ca6dfc69334e73db9fd863823f19ec76a 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_52.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_52.ets @@ -13,11 +13,21 @@ * limitations under the License. */ -let /* @@ label1 */a = { - get [/* @@ label2 */b/* @@ label3 */)(){}, - ...a, +let a = { + get [b)(){}, + ...a, } -/* @@@ label1 Error TypeError: Cannot infer type for a because class composite needs an explicit target type */ -/* @@@ label2 Error SyntaxError: Object pattern can't contain methods. */ -/* @@@ label3 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:5 Error TypeError: Cannot infer type for a because class composite needs an explicit target type */ +/* @@? 17:9 Error SyntaxError: Unexpected token. */ +/* @@? 17:10 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 17:10 Error SyntaxError: Object pattern can't contain methods. */ +/* @@? 17:12 Error SyntaxError: Expected '{', got '('. */ +/* @@? 17:12 Error SyntaxError: Unexpected token. */ +/* @@? 17:13 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 18:5 Error SyntaxError: Unexpected token '...'. */ +/* @@? 18:8 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_53.ets b/ets2panda/test/ast/parser/ets/unexpected_token_53.ets index 70bf658604269b790f7f76e435609ec8659ee11e..da3f06e4cb2d8eb192d3942705f586e01a6871f4 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_53.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_53.ets @@ -26,17 +26,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..17ccd7464285434ae8ad3f976820d979401f83d1 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_55.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_55.ets @@ -27,21 +27,11 @@ export class MathSpectralNorm { /* @@? 19:16 Error TypeError: Unresolved reference i */ /* @@? 19:18 Error SyntaxError: Unexpected token '='. */ -/* @@? 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 95e865545debaff1ee53abb9b5e3cbdd8ab51f34..7b68324c196dd725b88a8dd4bea2f34043942cf2 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_56.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_56.ets @@ -13,22 +13,21 @@ * limitations under the License. */ -for await (/* @@ label1 */;/* @@ label2 */;/* @@ label3 */i < /* @@ label4 */count/* @@ label5 */; ++i/* @@ label6 */) { +for await (/* @@ label1 */;/* @@ label2 */;/* @@ label3 */i < /* @@ label4 */count/* @@ label5 */; ++i/* @@ label6 */) /* @@ label7 */{ /* @@ label8 */result = result + /* @@ label9 */p[i]!.awaitResolution() * /* @@ label10 */a[i]; } -for (let i?: Number = 1;;) { break; } +for (let i? /* @@ label11 */: Number = 1;;) { break; } /* @@@ label1 Error SyntaxError: Unexpected token ';'. */ /* @@@ label2 Error SyntaxError: Unexpected token ';'. */ /* @@@ label3 Error TypeError: Unresolved reference i */ -/* @@@ label3 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@@ label4 Error TypeError: Function name 'count' used in the wrong context */ +/* @@@ label4 Error TypeError: Unresolved reference count */ /* @@@ label5 Error SyntaxError: Expected ')', got ';'. */ /* @@@ label6 Error SyntaxError: Unexpected token ')'. */ -/* @@@ label6 Error SyntaxError: Unexpected token ')'. */ -/* @@@ label6 Error SyntaxError: Unexpected token ')'. */ +/* @@@ label7 Error SyntaxError: Unexpected token '{'. */ /* @@@ label8 Error TypeError: Unresolved reference result */ /* @@@ label9 Error TypeError: Unresolved reference p */ /* @@@ label9 Error TypeError: Indexed access is not supported for such expression type. */ /* @@@ label10 Error TypeError: Unresolved reference a */ /* @@@ label10 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@@ label11 Error SyntaxError: Optional variable is deprecated and no longer supported. */ 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_61.ets b/ets2panda/test/ast/parser/ets/unexpected_token_61.ets index b367484b9cf043382f8e873cba7908947a3853f1..76c41c3aa432f2414e2e4c27053c8a3c7f2d55c7 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_61.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_61.ets @@ -14,10 +14,10 @@ */ function main(): void { - for (const i : int = 0 /* @@ label1 */i < 10; i++) { + for (const i : int = 0 /* @@ label1 */i < 10; /* @@ label */i++) { console.log("a") } } -/* @@? 17:16 Error TypeError: Cannot assign to a constant variable i */ +/* @@@ label Error TypeError: Cannot assign to a constant variable i */ /* @@@ label1 Error SyntaxError: Expected ';', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_62.ets b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets index e4a3e105d136f21c9068e33b8a646f49e26d6cec..78b6905b98b63eab7f505d42823d74c880bd42c7 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_62.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets @@ -32,47 +32,36 @@ int = 10 /* @@? 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 SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 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:10 Error SyntaxError: Class cannot be used as object. */ /* @@? 20:12 Error SyntaxError: Unexpected token '{'. */ /* @@? 22:11 Error SyntaxError: Unexpected token 'Nu'. */ /* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 24:1 Error SyntaxError: Unexpected token ')'. */ /* @@? 24:2 Error SyntaxError: Unexpected token 'void'. */ -/* @@? 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:16 Error SyntaxError: Unexpected token ','. */ -/* @@? 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:23 Error SyntaxError: Class cannot be used as object. */ /* @@? 24:25 Error SyntaxError: Unexpected token '{'. */ /* @@? 25:1 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 25:5 Error SyntaxError: Unexpected token '='. */ /* @@? 26:1 Error SyntaxError: Unexpected token ')'. */ /* @@? 26:3 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 26:3 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 26:13 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 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:15 Error SyntaxError: Unexpected token ')'. */ -/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ -/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ /* @@? 26:16 Error SyntaxError: Unexpected token ':'. */ -/* @@? 26:16 Error SyntaxError: Unexpected token ':'. */ -/* @@? 26:18 Error TypeError: The type of parameter 'A6' cannot be inferred */ +/* @@? 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 */ @@ -81,4 +70,4 @@ int = 10 /* @@? 26:36 Error TypeError: Type 'B' has no call signatures. */ /* @@? 26:40 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 27:2 Error TypeError: Unresolved reference ó */ -/* @@? 85:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 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 index 833cf39392af4e1f38e1c0aec5594b1c876f67c9..2cc94b998aaf2f7ba42a98f43c6e4fc8792aa8c6 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_63.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets @@ -26,6 +26,7 @@ class A { } } + /* @@? 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 ')'. */ @@ -33,26 +34,29 @@ class A { /* @@? 17:29 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:31 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ /* @@? 17:37 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:37 Error SyntaxError: Field type annotation expected. */ /* @@? 17:39 Error SyntaxError: Unexpected token '{'. */ /* @@? 18:3 Error SyntaxError: Unexpected token 'while'. */ -/* @@? 18:8 Error SyntaxError: Unexpected token '('. */ +/* @@? 18:8 Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ +/* @@? 18:9 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 18:9 Error SyntaxError: Unexpected token 'true'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:9 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 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:6 Error SyntaxError: Call signatures in object types are not supported. Use '$_invoke' method instead. */ +/* @@? 19:7 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 19:7 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 19:7 Error SyntaxError: Unexpected token 'false'. */ +/* @@? 19:7 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 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:6 Error SyntaxError: Unexpected token 'else'. */ -/* @@? 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'. */ -/* @@? 23:21 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 21:11 Error SyntaxError: Unexpected token '{'. */ +/* @@? 23:5 Error TypeError: 'this' cannot be referenced from a static context */ +/* @@? 23:10 Error TypeError: Property 'func' does not exist on type 'ETSGLOBAL' */ /* @@? 23:21 Error SyntaxError: Unexpected token 'final'. */ -/* @@? 23:39 Error SyntaxError: Expected '{', got ')'. */ +/* @@? 25:3 Error SyntaxError: Unexpected token '}'. */ /* @@? 26:2 Error SyntaxError: Unexpected token '}'. */ /* @@? 27:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_8.ets b/ets2panda/test/ast/parser/ets/unexpected_token_8.ets index fcef5ef0227e6e8494c716ed7d53d5367acc983c..0e1150386e3952250fcc0a9e5660d176c480a06d 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_8.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_8.ets @@ -15,7 +15,6 @@ try { -} catch (e: number /* @@ label1 */{} +} catch (e /* @@ label1 */{} -/* @@? 18:10 Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ /* @@@ label1 Error SyntaxError: Expected ')', got '{'. */ diff --git a/ets2panda/test/ast/parser/ets/unionFieldSameType_1.ets b/ets2panda/test/ast/parser/ets/unionFieldSameType_1.ets index dd5fdd90acbbce30dd389f1a8f89b9fcaef14f27..658c74dd23707ecbebc3c6c5aecfb7f36ccdcc30 100644 --- a/ets2panda/test/ast/parser/ets/unionFieldSameType_1.ets +++ b/ets2panda/test/ast/parser/ets/unionFieldSameType_1.ets @@ -23,6 +23,6 @@ let u1: A|B = new A let u2: A|B = new B function main() { - assertEQ(u1.fld[0], 42.0) - assertEQ(u2.fld[1], 'b') + arktest.assertEQ(u1.fld[0], 42.0) + arktest.assertEQ(u2.fld[1], 'b') } diff --git a/ets2panda/test/ast/parser/ets/unionFieldSameType_2.ets b/ets2panda/test/ast/parser/ets/unionFieldSameType_2.ets index dd5fdd90acbbce30dd389f1a8f89b9fcaef14f27..658c74dd23707ecbebc3c6c5aecfb7f36ccdcc30 100644 --- a/ets2panda/test/ast/parser/ets/unionFieldSameType_2.ets +++ b/ets2panda/test/ast/parser/ets/unionFieldSameType_2.ets @@ -23,6 +23,6 @@ let u1: A|B = new A let u2: A|B = new B function main() { - assertEQ(u1.fld[0], 42.0) - assertEQ(u2.fld[1], 'b') + arktest.assertEQ(u1.fld[0], 42.0) + arktest.assertEQ(u2.fld[1], 'b') } diff --git a/ets2panda/test/ast/parser/ets/unionFieldSameType_3.ets b/ets2panda/test/ast/parser/ets/unionFieldSameType_3.ets index 288522c9f63c2a7b1f4b2d24dae3bc821ce8b31c..a49267850d3d67f19b97430b7d4303aa23af31d1 100644 --- a/ets2panda/test/ast/parser/ets/unionFieldSameType_3.ets +++ b/ets2panda/test/ast/parser/ets/unionFieldSameType_3.ets @@ -23,6 +23,6 @@ let u1: A|B = new A let u2: A|B = new B function main() { - assertEQ(u1.fld('abc'), 4.0) - assertEQ(u2.fld('abc'), 13.0) + arktest.assertEQ(u1.fld('abc'), 4.0) + arktest.assertEQ(u2.fld('abc'), 13.0) } diff --git a/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets index 94b7879b28bc998a71ef37e9ca09723de8e90e8b..81b8aca00ec4a458b1f2dd162afd4ad6882428f0 100644 --- a/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets +++ b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets @@ -16,15 +16,17 @@ let x = z.meth(foo) { - assert(y[0] == 1) - assert(y[1] == 2) + arktest.assert(y[0] == 1) + arktest.assert(y[1] == 2) -classtext: string, reviver: ((key: string, value: NullishType) => NullishType) | undefined, type: Type +classtext: string, reviver: ((key: string, value: Any) => Any) | 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:99 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 30:60 Error SyntaxError: Expected '}', got 'eos'. */ \ No newline at end of file +/* @@? 22:75 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:77 Error SyntaxError: Unexpected token 'type'. */ +/* @@? 22:83 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/update_funcscope_error.ets b/ets2panda/test/ast/parser/ets/update_funcscope_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..3216a64552f5fe0a0b59cbe694ccbddc1df5aa4f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/update_funcscope_error.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. + */ + +type UpdateFunc = (u: Record) => Record; +type ReducerFunc = (key: string) => Record; + +export const updateIfChanged = (t: Record) => { + const reducerFunc: ReducerFunc = (key) => { + const value = u[key]; + const reduceResult = reduce( + value as Record, + (v: Record) => { + const baseU = u; + const updatedU: Record = { + ...baseU, + [key]: v + }; + return update(updatedU); + } + ); + return reduceResult; + }; +}; + +/* @@? 21:19 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 21:19 Error TypeError: Unresolved reference u */ +/* @@? 24:7 Error TypeError: Type '(v: Record) => Boolean' is not compatible with type '(previousValue: Boolean, currentValue: Boolean, index: Double, array: FixedArray) => Boolean' at index 2 */ +/* @@? 27:11 Error TypeError: Invalid record property */ +/* @@? 28:11 Error SyntaxError: Unexpected token. */ +/* @@? 28:12 Error SyntaxError: Unexpected token. */ +/* @@? 28:12 Error TypeError: Type '*ERROR_TYPE*' is not compatible with type 'String' at index 1 */ +/* @@? 28:15 Error SyntaxError: Unexpected token. */ +/* @@? 28:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 28:18 Error SyntaxError: Unexpected token 'v'. */ +/* @@? 29:10 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 30:16 Error TypeError: Unresolved reference update */ +/* @@? 30:16 Error TypeError: This expression is not callable. */ +/* @@? 32:5 Error SyntaxError: Unexpected token ')'. */ +/* @@? 33:12 Error TypeError: Unresolved reference reduceResult */ +/* @@? 33:12 Error TypeError: Unexpected return value, enclosing method return type is void. */ +/* @@? 35:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_14.ets b/ets2panda/test/ast/parser/ets/user_defined_14.ets index a52c018c9981486973ab3bca26f22271103411b4..31c17e0cc894d95cfb988decab385f757e4d58c6 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_14.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_14.ets @@ -13,6 +13,9 @@ * limitations under the License. */ -class typeof{ +class /* @@ label */typeof { a : string = "15"; } + +/* @@@ label Error SyntaxError: Hard keyword 'typeof' cannot be used as identifier */ +/* @@@ 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 0da893731848a9ca3ba48665644ac591fe0e1053..8f81e7dbc795a24a5188d7b7e80fe4eb86cfaa11 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_19.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_19.ets @@ -18,3 +18,5 @@ struct typeof{ } /* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ +/* @@? 16:8 Error SyntaxError: Hard keyword 'typeof' cannot be used as identifier */ +/* @@? 16:8 Error SyntaxError: Identifier expected, got 'typeof'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_20.ets b/ets2panda/test/ast/parser/ets/user_defined_20.ets index 2826718e9bcbdc71d589e1ce4e54c2731efef3c4..11c00c085ab04a1aaa9a32c9f8aa67f3a774f110 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_20.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_20.ets @@ -17,6 +17,5 @@ struct bigint{ a : string = "15"; } -/* @@? 16:8 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@? 16:8 Error SyntaxError: bigint is a predefined type, cannot be used as an identifier */ /* @@? 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 'bigint' is already defined with different type. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_21.ets b/ets2panda/test/ast/parser/ets/user_defined_21.ets index 6ed80976387fa0f0f4fe3a265d75d1bcc98ea334..a7715989bf1d418e8d4c0263dca804341ef44563 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_21.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_21.ets @@ -17,5 +17,4 @@ class /* @@ label */bigint{ a : string = "15"; } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ -/* @@? 1:3 Error TypeError: Variable 'bigint' is already defined with different type. */ +/* @@@ label Error SyntaxError: bigint is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_5.ets b/ets2panda/test/ast/parser/ets/user_defined_5.ets index bdf44a3c52233139d5dfcb3a16e90824bcb0b80b..a20b8680d4ed2d7c4dac1f52b113a95206279b00 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_5.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_5.ets @@ -17,5 +17,4 @@ enum /* @@ label */double { A, B, C } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ -/* @@@ label Error SyntaxError: Identifier expected, got 'double'. */ +/* @@@ label Error SyntaxError: double is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_7.ets b/ets2panda/test/ast/parser/ets/user_defined_7.ets index 67c6eec0952f3d56ce21ecaac8914f1f39d2f4bc..5b9519508f6746008b811c5d0d2d3eefcc2cb2d7 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_7.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_7.ets @@ -17,8 +17,7 @@ interface /* @@ label1 */double { name : string /* @@ label2 */= /* @@ label3 */"" /* @@ label4 */} -/* @@@ label1 Error SyntaxError: Cannot be used as user-defined type. */ -/* @@@ label1 Error SyntaxError: Identifier expected, got 'double'. */ +/* @@@ label1 Error SyntaxError: double is a predefined type, cannot be used as an identifier */ /* @@@ 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/user_defined_8.ets b/ets2panda/test/ast/parser/ets/user_defined_8.ets index 95556fc08294ee82fbe20c09051086b5d7fad317..52278742dd3f8ed2e018321cb303a067e5bcf713 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_8.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_8.ets @@ -17,7 +17,5 @@ struct string{ a : string = "15"; } -/* @@? 16:8 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@? 16:8 Error SyntaxError: string is a predefined type, cannot be used as an identifier */ /* @@? 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 'string' is already defined with different type. */ -/* @@? 17:16 Error TypeError: Type '"15"' cannot be assigned to type 'string' */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_9.ets b/ets2panda/test/ast/parser/ets/user_defined_9.ets index fecbee124f116921c19898efd6baa1ed741fd7bf..1170c80f98c44b47ee10471aed582e5cd53019a1 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_9.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_9.ets @@ -17,6 +17,4 @@ class /* @@ label */string{ a : string = "15"; } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ -/* @@? 1:3 Error TypeError: Variable 'string' is already defined with different type. */ -/* @@? 17:16 Error TypeError: Type '"15"' cannot be assigned to type 'string' */ +/* @@@ label Error SyntaxError: string is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/visible_signatures_1.ets b/ets2panda/test/ast/parser/ets/visible_signatures_1.ets index af181eab15443f6e6dfa3446719a3ae7838f6abf..7be7ca46cafcc0d527f869db047182a2e8d15a58 100644 --- a/ets2panda/test/ast/parser/ets/visible_signatures_1.ets +++ b/ets2panda/test/ast/parser/ets/visible_signatures_1.ets @@ -27,5 +27,6 @@ function main(): void { } -/* @@? 26:5 Error TypeError: Signature foo(a: double): int is not visible here. */ -/* @@? 26:5 Error TypeError: No matching call signature for foo(double) */ +/* @@? 20:13 Error TypeError: Function foo with this assembly signature already declared. */ +/* @@? 26:5 Error TypeError: Signature foo(a: Double|undefined): Int is not visible here. */ +/* @@? 26:5 Error TypeError: No matching call signature for foo(Double) */ diff --git a/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets b/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets new file mode 100644 index 0000000000000000000000000000000000000000..a00400dec82d046278ea07ca396db4188a53b65e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class expr01701 { + val: int; + + static run(): int { + let x: expr01701 | null= null; + let res: int; + try { + res = x!.val; + } catch (error) { + return 0; + } + return 2; + } +} + +function dasgAssert() { + let result = expr01701.run(); + arktest.assertEQ(result, 0); +} + +dasgAssert(); + +/* @@? 23:15 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ diff --git a/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets b/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7242bafee34c7be5227c29d2d9cbb4ffb3ff0ad --- /dev/null +++ b/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +final class C { + y: int + readonly x: C|undefined +} + +function f(c: C) { + if (c.x === undefined) { + c.x!.y + } +} + 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/wrongReadonlyUtilityType.ets b/ets2panda/test/ast/parser/ets/wrongReadonlyUtilityType.ets index 13d250bfdbe671753284b1b026d8281f2f75b928..4b832e61e6c221c1df519b125d73134934bc02ed 100644 --- a/ets2panda/test/ast/parser/ets/wrongReadonlyUtilityType.ets +++ b/ets2panda/test/ast/parser/ets/wrongReadonlyUtilityType.ets @@ -21,4 +21,7 @@ class A { let a: readonly = new A(); /* @@? 21:16 Error SyntaxError: Invalid Type. */ -/* @@? 21:20 Error SyntaxError: Readonly utility type expected but readonly found. */ +/* @@? 21:16 Error SyntaxError: Unexpected token '<'. */ +/* @@? 21:16 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 21:20 Error SyntaxError: Unexpected token '='. */ +/* @@? 21:22 Error SyntaxError: Unexpected token 'new'. */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_class_1.ets b/ets2panda/test/ast/parser/ets/wrong_context_class_1.ets index 6b6060566344907a04f96c393c290a22014e0225..76848aae0f9f83e4668fcc2fda5156914f68e2d2 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_class_1.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_class_1.ets @@ -22,5 +22,5 @@ function main() /* @@ label */a = /* @@ label1 */5 } -/* @@@ label Error TypeError: Class name 'a' used in the wrong context */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'a' */ +/* @@@ label Error SyntaxError: Class cannot be used as object. */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'a' */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_class_2.ets b/ets2panda/test/ast/parser/ets/wrong_context_class_2.ets index 7884b50d809a7e92387573203d7143dba805e6be..f26cb6dee62a19595f38e4a39a61b61ad9fc41ee 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_class_2.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_class_2.ets @@ -23,5 +23,5 @@ function main() b = a } -/* @@? 23:9 Error TypeError: Class name 'a' used in the wrong context */ -/* @@? 23:9 Error TypeError: Type 'a' cannot be assigned to type 'int' */ +/* @@? 23:9 Error SyntaxError: Class cannot be used as object. */ +/* @@? 23:9 Error TypeError: Type 'a' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_class_3.ets b/ets2panda/test/ast/parser/ets/wrong_context_class_3.ets index d0818058f7509ad8b2de829024f7ae2cccc7cad0..6b54667d9f58ff7fa9839619ce1637c9924a6597 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_class_3.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_class_3.ets @@ -22,5 +22,5 @@ function main() a++ } -/* @@? 22:5 Error TypeError: Class name 'a' used in the wrong context */ +/* @@? 22:5 Error SyntaxError: Class cannot be used as object. */ /* @@? 22:5 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ 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..79ccb2bf3b42f75c8be831257608c268bd56f91a 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: Class name 'a' used in the wrong context */ /* @@? 26:5 Error TypeError: Object type doesn't have proper index access method. */ +/* @@? 26:5 Error SyntaxError: Class cannot be used as object. */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_function_1.ets b/ets2panda/test/ast/parser/ets/wrong_context_function_1.ets index be1e154d0c3ec8e4f9b70c750020061443ac78b6..530534fa782f03c2c3d9a10dd5f7154ae432a355 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_function_1.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_function_1.ets @@ -22,5 +22,4 @@ function main() /* @@ label */a = /* @@ label1 */5 } -/* @@@ label Error TypeError: Function name 'a' used in the wrong context */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type '() => void' */ +/* @@@ label Error TypeError: Function name 'a' used in the wrong context */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_function_2.ets b/ets2panda/test/ast/parser/ets/wrong_context_function_2.ets index e4101c325c7a961eee0492fb7e7aff2b334045a7..69076b3d7b8d72942d1428c7b1fb18cc8905ec16 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_function_2.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_function_2.ets @@ -23,4 +23,4 @@ function main() b = /* @@ label */a } -/* @@@ label Error TypeError: Type '() => void' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '() => void' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_function_3.ets b/ets2panda/test/ast/parser/ets/wrong_context_function_3.ets index 74b8296e569fb0bbdf09cd3004228e5ac4e7409f..293065f2be6d6ec129f06280c62208559a08d3d3 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_function_3.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_function_3.ets @@ -23,4 +23,3 @@ function main() } /* @@? 22:5 Error TypeError: Function name 'a' used in the wrong context */ -/* @@? 22:5 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ 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/private_ctor_bad.js b/ets2panda/test/ast/parser/js/private_ctor_bad.js new file mode 100644 index 0000000000000000000000000000000000000000..1b9477045f2682176e219e5d18c7db2125030c6d --- /dev/null +++ b/ets2panda/test/ast/parser/js/private_ctor_bad.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 A { + #constructor(){} +} +/* @@? 18:6 Error SyntaxError: Private identifier can not be constructor. */ diff --git a/ets2panda/test/ast/parser/js/private_number_bad.js b/ets2panda/test/ast/parser/js/private_number_bad.js new file mode 100644 index 0000000000000000000000000000000000000000..94cd82cad0adec7fc72ee2b4572247a0019ed93a --- /dev/null +++ b/ets2panda/test/ast/parser/js/private_number_bad.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 WeAre { + #1 +} +/* @@? 17:6 Error SyntaxError: Unexpected token in private field. */ +/* @@? 17:6 Error SyntaxError: Private identifier name can not be number. */ diff --git a/ets2panda/test/ast/parser/js/private_ref_bad.js b/ets2panda/test/ast/parser/js/private_ref_bad.js new file mode 100644 index 0000000000000000000000000000000000000000..cc4b234705d69a92b2be25ca18a4cc86fb8deede --- /dev/null +++ b/ets2panda/test/ast/parser/js/private_ref_bad.js @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{ + m(){ + return this.#x + } +} +/* @@? 18:21 Error SyntaxError: Private field 'x' must be declared in an enclosing class */ diff --git a/ets2panda/test/ast/parser/js/private_sqbracket_bad.js b/ets2panda/test/ast/parser/js/private_sqbracket_bad.js new file mode 100644 index 0000000000000000000000000000000000000000..426ccec09f494b4ac77389b6317cfa181521c25e --- /dev/null +++ b/ets2panda/test/ast/parser/js/private_sqbracket_bad.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. + */ + +class WeAre { + #[ +} +/* @@? 17:6 Error SyntaxError: Unexpected token in private field. */ +/* @@? 17:6 Error SyntaxError: Unexpected character in private identifier. */ +/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 24:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/private_string_bad.js b/ets2panda/test/ast/parser/js/private_string_bad.js new file mode 100644 index 0000000000000000000000000000000000000000..58c411b6fd9fcc16fd4c6cbaa533c681c3b85836 --- /dev/null +++ b/ets2panda/test/ast/parser/js/private_string_bad.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 WeAre { + #"one" +} +/* @@? 17:6 Error SyntaxError: Unexpected token in private field. */ +/* @@? 17:6 Error SyntaxError: Private identifier name can not be string. */ diff --git a/ets2panda/test/ast/parser/js/static_property_prototype.js b/ets2panda/test/ast/parser/js/static_property_prototype.js new file mode 100644 index 0000000000000000000000000000000000000000..9162d059454a7425a3b8b9719dca04481bd2cbe9 --- /dev/null +++ b/ets2panda/test/ast/parser/js/static_property_prototype.js @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class A { + static "prototype" = 123; +} + +/* @@? 18:12 Error SyntaxError: Classes may not have static property named prototype. */ diff --git a/ets2panda/test/ast/parser/js/test-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/test_yield.js b/ets2panda/test/ast/parser/js/test_yield.js new file mode 100644 index 0000000000000000000000000000000000000000..172fafb5afd8b49d2da7514d6036513caec5dcc3 --- /dev/null +++ b/ets2panda/test/ast/parser/js/test_yield.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function* g(x = yield) {} + +/* @@? 16:17 Error SyntaxError: Yield is not allowed in generator parameters. */ diff --git a/ets2panda/test/ast/parser/js/this-expression.js b/ets2panda/test/ast/parser/js/this-expression.js index c0245f85315fa3eaad75d2a01c0434bf306f0ce9..884e65196010ee62a126622aa5a4316a560c97f8 100644 --- a/ets2panda/test/ast/parser/js/this-expression.js +++ b/ets2panda/test/ast/parser/js/this-expression.js @@ -17,3 +17,4 @@ this./* @@ label */"foo"; /* @@@ label Error SyntaxError: Identifier expected, got 'string literal'. */ +/* @@@ label Error SyntaxError: Number, string or computed value property name 'foo' is not allowed, use classes to access data by property names that are identifiers */ 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/test-interface2.ts b/ets2panda/test/ast/parser/ts/test-interface2.ts index 95377c99273b38af756a61dbb8f5904b22bb978e..9e3c4b26f6c39782c30d55d4bed86f79ddad8026 100644 --- a/ets2panda/test/ast/parser/ts/test-interface2.ts +++ b/ets2panda/test/ast/parser/ts/test-interface2.ts @@ -16,3 +16,4 @@ interface /* @@ label */5 { } /* @@@ label Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@@ label Error SyntaxError: Number, string or computed value property name '5' is not allowed, use classes to access data by property names that are identifiers */ diff --git a/ets2panda/test/ast/parser/ts/test_class_constructor.ts b/ets2panda/test/ast/parser/ts/test_class_constructor.ts new file mode 100644 index 0000000000000000000000000000000000000000..d525f7e84258e15e2e94906485ca65c87e3ae902 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_class_constructor.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class MyClass { + /* @@ label */"constructor" = 42; +} + +/* @@@ label Error SyntaxError: Classes may not have a field named 'constructor'. */ diff --git a/ets2panda/test/ast/parser/ts/test_generators.ts b/ets2panda/test/ast/parser/ts/test_generators.ts new file mode 100644 index 0000000000000000000000000000000000000000..06fe8230f5b9bdb489e9c2b7332c53a712fe9ab9 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_generators.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. + */ + +a: +/* @@ label */function* gen() { + yield 1; +} + +/* @@@ label Error SyntaxError: In strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement. */ +/* @@@ label Error SyntaxError: Generators can only be declared at the top level or inside a block. */ diff --git a/ets2panda/test/ast/parser/ts/test_insufficient_param.ts b/ets2panda/test/ast/parser/ts/test_insufficient_param.ts new file mode 100644 index 0000000000000000000000000000000000000000..41ee6d26764c4c0129680f1c94a836e7d79bcae7 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_insufficient_param.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +async (()=> {}, a) /* @@ label */=> expression; + +/* @@@ label Error SyntaxError: Insufficient formal parameter in arrow function. */ diff --git a/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts b/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts new file mode 100644 index 0000000000000000000000000000000000000000..555dfa4bbc9176a036fab04fea53a686f098017e --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +({ a: 1 } = {})/* @@ label */; + +/* @@@ label Error SyntaxError: Invalid left-hand side in assignment expression. */ diff --git a/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_async_function.ts b/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_async_function.ts new file mode 100644 index 0000000000000000000000000000000000000000..b1817950d806bf176b8b86ffcebde7a626f02d52 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_async_function.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. + */ + +while (true) async /* @@ label */function a() { }; + +/* @@@ label Error SyntaxError: Lexical declaration is not allowed in single statement context. */ diff --git a/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_class.ts b/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_class.ts new file mode 100644 index 0000000000000000000000000000000000000000..823d5add6dfca64c4f35484d600965b3e75bd2fc --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_lexical_dec_not_allowed_class.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. + */ + +while (true) /* @@ label */class a { }; + +/* @@@ label Error SyntaxError: Lexical declaration is not allowed in single statement context. */ diff --git a/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts b/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts new file mode 100644 index 0000000000000000000000000000000000000000..074a68340c82bed117018e9386bfb5e3db0814f1 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const /* @@ label */[...rest, x] = [1, 2, 3]; + +/* @@@ label Error SyntaxError: Rest parameter must be the last formal parameter. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/dynamic_import_interop_neg.ets b/ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts similarity index 80% rename from ets2panda/test/ast/compiler/ets/import_tests/dynamic_import_interop_neg.ets rename to ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts index b46d9869a8adfbd9faf6d31d6dd7eaee52c87298..327c4c4735770b59b331e556f339d9579d033e58 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/dynamic_import_interop_neg.ets +++ b/ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts @@ -13,6 +13,6 @@ * limitations under the License. */ -import /* @@ label */foo from 'dynamic_import_tests' +function f({ ...{ x } /* @@ label */}) {} -/* @@@ label Error TypeError: Default import is currently not implemented in dynamic import */ +/* @@@ label Error SyntaxError: RestParameter must be followed by an identifier in declaration contexts */ diff --git a/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts b/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b09f42bf39bfadc4c3645516c5865c295ff764d --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class MyClass { + static /* @@ label */prototype = {}; +} + +/* @@@ label Error SyntaxError: Classes may not have static property named prototype. */ diff --git a/ets2panda/test/ast/parser/ts/test_strict_mode_func.ts b/ets2panda/test/ast/parser/ts/test_strict_mode_func.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f8e7cd258a0b99d26e1f3291d86727af222b454 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_strict_mode_func.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. + */ + +a: +/* @@ label */function foo() { } + +/* @@@ label Error SyntaxError: In strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement. */ diff --git a/ets2panda/test/ast/parser/ts/test_unexpected_token.ts b/ets2panda/test/ast/parser/ts/test_unexpected_token.ts new file mode 100644 index 0000000000000000000000000000000000000000..a611c1c8f5432cbe5e0d6bbe5115995ff099528a --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_unexpected_token.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const obj = { + /* @@ label */+: 1 +}; + +/* @@@ label Error SyntaxError: Unexpected token. */ diff --git a/ets2panda/test/ast/parser/ts/test_yield_escaped.ts b/ets2panda/test/ast/parser/ts/test_yield_escaped.ts new file mode 100644 index 0000000000000000000000000000000000000000..32f77654e05c8c81465b62b8c4edbac1cdb2b246 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_yield_escaped.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +function* gen() { + var /* @@ label */yi\u0065ld /* @@ label1 */= 123; +} + +/* @@@ label Error SyntaxError: Escape sequences are not allowed in keyword. */ +/* @@@ label Error SyntaxError: Unexpected token. */ +/* @@@ label Error SyntaxError: Unexpected token 'yield'. */ +/* @@@ label Error SyntaxError: Unexpected identifier. */ +/* @@@ label1 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/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/benchmarks/README.md b/ets2panda/test/benchmarks/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4774895e4db5c49249240e6836aa8118bbf646b5 --- /dev/null +++ b/ets2panda/test/benchmarks/README.md @@ -0,0 +1,76 @@ +# Logic +- Run es2panda for benchmark files from this directory +- Dump perfmetrics to `/test-current-perf.txt` for current es2panda +- Dump perfmetrics to `/test-pre_merge-perf.txt` for another (pre-merge) es2panda +- Dump comparison report to `/test-report.txt` in format like `time=-90.00ms (-1.9%)` + +### Static mode +If `actual_perf > max_perf * (1 + static_regression)` - an error occurs. Example: +``` +[PERF REGRESSION] Failed for bench_1-current-perf.txt: Memory exceeded threshold. + Limit: 5.0%, Actual: +406.25% + Base: 32.00MB, New: 162.00MB + Threshold: < 33.60MB +``` + +If `actual_perf < max_perf * (1 + 3 * static_regression)` - an error occurs. Example: +``` +[UPDATE REQUIRED] Very good perf for bench_1-current-perf.txt: Please update *-max.txt. + Hint: use flag '--dump-perf-metrics' and Release build of es2panda. +``` + +### Dynamic mode +If `actual_perf > pre_merge_perf * dynamic_regression` - an error occurs (the same as in static mode). + +### Errors reporting +Errors are printed to the console and also to `/error_log.txt`. + +# Arguments +- `--mode` - 'static' to compare with `*-max.txt` files. 'dynamic' to compare with pre-merge es2panda. +- `--es2panda` - Path to current es2panda (aka /bin/es2panda) +- `--es2panda-pre-merge` - Path to pre-merge es2panda (aka /bin/es2panda) +- `--test-dir` - Path to test directory with test files +- `--work-dir` - Path to the working temp folder with gen, intermediate and report folders +- `--dynamic-regression` - Acceptable regression compared to the another (pre-merge) es2panda +- `--static-regression` - Acceptable regression compared to static vales from `*-max.txt` files +- `--runs` - The number of runs to average +- `--werror` - Warnings as errors + +# Max values +Each file have companion: for `test.ets` companion is `test-max.txt`. This file contains max values for metrics. + +# Local reproduction +```bash +# static mode +python3 /ets2panda/test/benchmarks/runner/runner.py --mode=static --es2panda=/bin/es2panda --work-dir=/e2p_benchmarks --test-dir=/ets2panda/test/benchmarks + +# dynamic mode +python3 /ets2panda/test/benchmarks/runner/runner.py --mode=dynamic --es2panda=/bin/es2panda --work-dir=/e2p_benchmarks --test-dir=/ets2panda/test/benchmarks --es2panda-pre-merge=/bin/es2panda +``` +See `--help` if needed. + +# CI +You can download artifacts for this job with perf stat. + +# Artifacts example + +test-perf.txt +``` +================ es2panda perf metrics (Averaged over 3 runs) ================ +:@phases : time=891.00ms mem=140.00MB +:@phases/ConstantExpressionLowering : time=233.00ms mem=0.26MB +:@phases/TopLevelStatements : time=193.00ms mem=79.00MB +:@phases/ResolveIdentifiers : time=83.40ms mem=6.00MB +:@phases/CheckerPhase : time=78.60ms mem=19.00MB +``` + +test-report.txt +``` +Performance Comparison: 'bench_1-max.txt' vs 'bench_1-current-perf.txt' +================================================================================ +:@EmitProgram : time=+2.90ms (+4.6%) mem=+0.00MB (+0.0%) +:@GenerateProgram : time=+4.67ms (+6.7%) mem=0.00MB (0.0%) +:@GenerateProgram/OptimizeBytecode : time=0.00ms (0.0%) mem=0.00MB (0.0%) +:@phases : time=+22.67ms (+2.6%) mem=+0.00MB (+0.0%) +:@phases/AmbientLowering : time=-0.07ms (-0.6%) mem=0.00MB (0.0%) +``` diff --git a/ets2panda/test/benchmarks/bench_1-max.txt b/ets2panda/test/benchmarks/bench_1-max.txt new file mode 100644 index 0000000000000000000000000000000000000000..81e3099f82e7696cbb68e727ae0288f68b6eb4ce --- /dev/null +++ b/ets2panda/test/benchmarks/bench_1-max.txt @@ -0,0 +1,66 @@ +================ es2panda perf metrics (Averaged over 500 runs) ================ + +:@phases : time=1472.50ms mem=159.89MB +:@GenerateProgram : time=439.95ms mem=0.00MB +:@phases/ConstantExpressionLowering : time=374.76ms mem=0.30MB +:@phases/TopLevelStatements : time=273.61ms mem=81.00MB +:@GenerateProgram/OptimizeBytecode : time=264.15ms mem=0.00MB +:@EmitProgram : time=148.99ms mem=31.22MB +:@phases/CheckerPhase : time=132.83ms mem=23.28MB +:@phases/ResolveIdentifiers : time=112.03ms mem=6.00MB +:@phases/InterfaceObjectLiteralLowering : time=81.20ms mem=7.00MB +:@phases/LambdaObjectConversion : time=74.07ms mem=5.00MB +:@phases/ScopesInitPhase : time=62.35ms mem=13.79MB +:@phases/PartialExportClassGen : time=45.10ms mem=8.00MB +:@phases/Unbox : time=29.11ms mem=0.74MB +:@phases/OptionalLowering : time=25.61ms mem=0.99MB +:@phases/ResizableArrayConvert : time=22.40ms mem=0.51MB +:@phases/InterfacePropertyDeclarationsPhase : time=21.20ms mem=1.00MB +:@phases/EnumLoweringPhase : time=19.05ms mem=0.81MB +:@phases/EnumPostCheckLoweringPhase : time=18.67ms mem=0.00MB +:@phases/OverloadMappingLowering : time=18.01ms mem=0.00MB +:@phases/DeclareOverloadLowering : time=17.97ms mem=0.00MB +:@phases/PromiseVoidInferencePhase : time=17.90ms mem=0.00MB +:@phases/InsertOptionalParametersAnnotation : time=17.38ms mem=0.74MB +:@phases/AmbientLowering : time=17.22ms mem=0.00MB +:@phases/ExpressionLambdaConstruction : time=17.15ms mem=0.00MB +:@phases/GradualTypeNarrowing : time=16.99ms mem=1.88MB +:@phases/DefaultParametersInConstructorLowering : time=16.67ms mem=0.52MB +:@phases/ObjectIndexLowering : time=3.65ms mem=0.71MB +:@phases/CreateGenericBridges : time=3.36ms mem=0.00MB +:@phases/ArrayLiteralLowering : time=3.24ms mem=0.52MB +:@phases/BoxingForLocals : time=1.64ms mem=0.00MB +:@phases/ObjectLiteralLowering : time=1.50ms mem=0.23MB +:@phases/PrimitiveConversion : time=1.26ms mem=0.00MB +:@phases/OpAssignmentLowering : time=1.22ms mem=0.00MB +:@phases/UnionLowering : time=0.95ms mem=0.00MB +:@phases/StringConstructorLowering : time=0.74ms mem=0.00MB +:@phases/OptionalArgumentsLowering : time=0.67ms mem=0.03MB +:@phases/LateInitializationConvert : time=0.63ms mem=0.00MB +:@phases/TypeFromLowering : time=0.63ms mem=0.00MB +:@phases/DefaultParametersLowering : time=0.62ms mem=0.00MB +:@phases/ExpandBracketsPhase : time=0.60ms mem=0.00MB +:@phases/CapturedVariables : time=0.57ms mem=0.00MB +:@phases/RestTupleConstructionPhase : time=0.54ms mem=0.00MB +:@phases/SpreadConstructionPhase : time=0.51ms mem=0.00MB +:@phases/DynamicImport : time=0.51ms mem=0.00MB +:@phases/StringComparisonLowering : time=0.47ms mem=0.00MB +:@phases/RestArgsLowering : time=0.37ms mem=0.00MB +:@phases/BigIntLowering : time=0.36ms mem=0.00MB +:@phases/ObjectIteratorLowering : time=0.32ms mem=0.00MB +:@phases/StringConstantsLowering : time=0.32ms mem=0.00MB +:@phases/SetterLowering : time=0.31ms mem=0.00MB +:@phases/RecordLowering : time=0.31ms mem=0.00MB +:@phases/ExtentionAccessorPhase : time=0.31ms mem=0.00MB +:@phases/AsyncMethodLowering : time=0.31ms mem=0.00MB +:@phases/AnnotationCopyPostLowering : time=0.28ms mem=0.00MB +:@phases/AnnotationCopyLowering : time=0.28ms mem=0.00MB +:@phases/SetJumpTargetPhase : time=0.26ms mem=0.00MB +:@phases/plugins-after-parse : time=0.01ms mem=0.00MB +:@phases/ExportAnonymousConstPhase : time=0.00ms mem=0.00MB +:@phases/plugins-after-lowering : time=0.00ms mem=0.00MB +:@phases/DeclGenPhase : time=0.00ms mem=0.00MB +:@phases/plugins-after-bind : time=0.00ms mem=0.00MB +:@phases/PackageImplicitImport : time=0.00ms mem=0.00MB +:@phases/plugins-after-check : time=0.00ms mem=0.00MB +:@phases/CFGBuilder : time=0.00ms mem=0.00MB diff --git a/ets2panda/test/benchmarks/bench_1.ets b/ets2panda/test/benchmarks/bench_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bfdd65f7d6450f345aa2cc11a53aa6076e6ac4e --- /dev/null +++ b/ets2panda/test/benchmarks/bench_1.ets @@ -0,0 +1,1574 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// --------------------------------------------------------------------------------------------------------------------- +// AccessBinaryTrees.ets +// --------------------------------------------------------------------------------------------------------------------- + +class TreeNode { + private left: TreeNode | null; + private right: TreeNode | null; + private item: int; + + constructor(left: TreeNode | null, right: TreeNode | null, item: int) { + this.left = left; + this.right = right; + this.item = item; + } + + public itemCheck(): int { + if (this.left == null) + return this.item; + else + return this.item + this.left!.itemCheck() - this.right!.itemCheck(); + } +} + +export class AccessBinaryTrees { + static readonly startDepth = 4; + static readonly endDepth = 7; + static readonly expected = -4; + + static bottomUpTree(item: int, depth: int): TreeNode { + if (depth > 0) { + return new TreeNode( + AccessBinaryTrees.bottomUpTree(2*item - 1, depth-1), + AccessBinaryTrees.bottomUpTree(2*item, depth-1), + item + ); + } + return new TreeNode(null, null, item); + } + + public run(): void { + let ret: int = 0; + + for (let n: int = AccessBinaryTrees.startDepth; n <= AccessBinaryTrees.endDepth; n++) { + let minDepth: int = AccessBinaryTrees.startDepth; + let maxDepth: int = max(minDepth + 2, n); + let stretchDepth: int = maxDepth + 1; + let check: int = AccessBinaryTrees.bottomUpTree(0, stretchDepth).itemCheck(); + + let longLivedTree = AccessBinaryTrees.bottomUpTree(0, maxDepth); + + for (let depth = minDepth; depth <= maxDepth; depth += 2) { + let iterations: int = 1 << (maxDepth - depth + minDepth); + + check = 0; + for (let i: int = 1; i <= iterations; i++) { + check += AccessBinaryTrees.bottomUpTree(i, depth).itemCheck(); + check += AccessBinaryTrees.bottomUpTree(-i, depth).itemCheck(); + } + } + + ret += longLivedTree.itemCheck(); + } + + arktest.assertEQ(ret, AccessBinaryTrees.expected, "Incorrect result") + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// RestTuple6.ets +// --------------------------------------------------------------------------------------------------------------------- + +class A2 {} +class B2 {} + +class C2 { + foo(...p: [A2, B2]): boolean { + return p[0] == p[1] + } + + moo(a:int, ...p: [A2, B2]): boolean { + return p[0] == p[1] + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// GenericBridges_02.ets +// --------------------------------------------------------------------------------------------------------------------- + +interface B3 { + f23(v: B3): B3; +} + +class C3 implements B3 { + + f13(v: T3): T3 { + return v; + } + + f23(v: C3): C3 { + return new C3(); + } + + f23(v: B3): B3 { + return this.f23(v as C3); + } + + f33(v: T3|string): string { + return "C3.f33"; + } + + f43(v: C3|Numeric): string { + return "C3.f43"; + } + + f53(x: T1|Z3|C3[]): string { + return "C3.f53"; + } + + f63(x: C3, y: C3): string { + return "C3.f63"; + } + + f73(x: T3, y: C3): string { + return "C3.f73"; + } + + f83(x: string): string { + return "C3.f83"; + } + + f93(z: Z3, y: T1): string { + return "C3.f93"; + } +} + +class D3 extends C3 { + f13(v: string): string { + return "D3.f13"; + } + + f13(v: Numeric|string|C3): string { + return this.f13(v as string); + } + + f13(v: Int): Int { + return 7; + } + + f23(v: D3): D3 { + return new D3(); + } + + f33(v: string): string { + return "D3.f33"; + } + + f43(v: D3): string { + return "D3.f43"; + } + + f43 (x: int, y: int): int { + return x + y; + } + + f53(x: string|W3|C3[]): string { + return "D3.f53"; + } + + f63(): string { + return "D3.f63"; + } + +// f73(x: string, y: D3): string { +// return "D3.f73"; +// } + + f83(x: string): string { + return "D3.f83"; + } + + f93(z: W3, y: string): string { + return "D3.f93-1"; + } + + f93(z: W3, y: Int): string { + return "D3.f93-2"; + } +} + +class F3 extends D3 {} + +class G3 extends C3 {} + +class E3 extends C3 { + + f13(v: U3): Integral { + if (v instanceof Int) { + return new Int(7); + } else if (v instanceof Long) { + return new Long(8); + } else { + return new Int(-1); + } + } + + f23(v: E3): E3 { + return new E3(); + } + + f33(){} + + f43(x:int, y: int): int { return x + y; } + +// f73(x: U3, y: E3): string { +// return "E3.f73"; +// } +} + +function foo13(c: C3) { + arktest.assertEQ(c.f13(0), 7) + arktest.assertEQ(c.f23(c).f13(0), 7) + arktest.assertEQ(c.f53(""), "C3.f53") + arktest.assertEQ(c.f63(c, c), "C3.f63") +} + +function foo23(c: C3) { + arktest.assertEQ(c.f13(0), 8) + arktest.assertEQ(c.f23(c).f13(0), 8) + arktest.assertEQ(c.f53(""), "C3.f53") + arktest.assertEQ(c.f73(3, c), "E3.f73") +} + +function ttt3(c: C3): void { + arktest.assertEQ(c.f13("ah"), "D3.f13") + arktest.assertEQ(c.f23(c).f13("ah"), "D3.f13") + arktest.assertEQ((c.f23(c as B3) as C3).f13("ah"), "D3.f13") + arktest.assertEQ(c.f33("ah"), "D3.f33") + arktest.assertEQ(c.f43(c), "D3.f43") + arktest.assertEQ(c.f53("ah"), "D3.f53") + arktest.assertEQ(c.f63(c, c), "C3.f63") + arktest.assertEQ((c as D3).f63(), "D3.f63") + arktest.assertEQ(c.f73("ah", c), "D3.f73") + arktest.assertEQ(c.f83(""), "D3.f83") + arktest.assertEQ(c.f93("", ""), "C3.f93") + arktest.assertEQ((c as D3).f93("", 0), "D3.f93-2") +} + +// --------------------------------------------------------------------------------------------------------------------- +// ArrowArity.ets +// --------------------------------------------------------------------------------------------------------------------- + +type S4 = string + +function xassert4(a: S4, b: S4) { arktest.assertEQ(a, b) } + +function p0call4(f: () => S4, a: S4[]) { + return f() +} +function p1call4(f: (p1: S4) => S4, a: S4[]) { + return f(a[0]) +} +function p2call4(f: (p1: S4, p2: S4) => S4, a: S4[]) { + return f(a[0], a[1]) +} +function p012call4(f: () => S4, a: S4[]) { + return p0call4(f, a) + p1call4(f, a) + p2call4(f, a) +} +function p_12call4(f: (p1: S4) => S4, a: S4[]) { + return p1call4(f, a) + p2call4(f, a) +} +function p__2call4(f: (p1: S4, p2: S4) => S4, a: S4[]) { + return p2call4(f, a) +} + +function r0__call4(f: (p1?: S4, p2?: S4) => S4, a: S4[]) { + return f() + f(a[0]) + f(a[0], a[1]) +} +function r_1_call4(f: (p1: S4, p2?: S4) => S4, a: S4[]) { + return f(a[0]) + f(a[0], a[1]) +} + +function testBasicArity4() { + let args = ["a", "b"] + let f0 = () => "/f0:" + let f1 = (a1: S4) => "/f1:" + a1 + let f2 = (a1: S4, a2: S4) => "/f2:" + a1 + a2 + + xassert4(p012call4(f0, args), "/f0:/f0:/f0:") + xassert4(p_12call4(f0, args), "/f0:/f0:") + xassert4(p_12call4(f1, args), "/f1:a/f1:a") + xassert4(p__2call4(f0, args), "/f0:") + xassert4(p__2call4(f1, args), "/f1:a") + xassert4(p__2call4(f2, args), "/f2:ab") + + xassert4(r0__call4(f0, args), "/f0:/f0:/f0:") + xassert4(r_1_call4(f0, args), "/f0:/f0:") + xassert4(r_1_call4(f1, args), "/f1:a/f1:a") +} +testBasicArity4(); + +function testOptionalArity4() { + let args = ["a", "b"] + let tou = (v?: string) => v ?? "u" + let f0 = (a1?: S4, a2?: S4) => "/f0:" + tou(a1) + tou(a2) + let f1 = (a1: S4, a2?: S4) => "/f1:" + a1 + tou(a2) + let f2 = (a1: S4, a2: S4) => "/f2:" + a1 + a2 + + xassert4(p012call4(f0, args), "/f0:uu/f0:au/f0:ab") + xassert4(p_12call4(f0, args), "/f0:au/f0:ab") + xassert4(p_12call4(f1, args), "/f1:au/f1:ab") + xassert4(p__2call4(f0, args), "/f0:ab") + xassert4(p__2call4(f1, args), "/f1:ab") + xassert4(p__2call4(f2, args), "/f2:ab") + + xassert4(r0__call4(f0, args), "/f0:uu/f0:au/f0:ab") + xassert4(r_1_call4(f0, args), "/f0:au/f0:ab") + xassert4(r_1_call4(f1, args), "/f1:au/f1:ab") +} +testOptionalArity4(); + +function testDfltArity4() { + let args = ["a", "b"] + let f0 = (a1: S4 = "x", a2: S4 = "y") => "/f0:" + a1 + a2 + let f1 = (a1: S4, a2: S4 = "y") => "/f1:" + a1 + a2 + let f2 = (a1: S4, a2: S4) => "/f2:" + a1 + a2 + + xassert4(p012call4(f0, args), "/f0:xy/f0:ay/f0:ab") + xassert4(p_12call4(f0, args), "/f0:ay/f0:ab") + xassert4(p_12call4(f1, args), "/f1:ay/f1:ab") + xassert4(p__2call4(f0, args), "/f0:ab") + xassert4(p__2call4(f1, args), "/f1:ab") + xassert4(p__2call4(f2, args), "/f2:ab") + + xassert4(r0__call4(f0, args), "/f0:xy/f0:ay/f0:ab") + xassert4(r_1_call4(f0, args), "/f0:ay/f0:ab") + xassert4(r_1_call4(f1, args), "/f1:ay/f1:ab") +} +testDfltArity4() + +function testDfltEvaluation4() { + let counter = "c" + let inc = () => (counter += "x") + let f = (a: string = inc()) => a + xassert4(f("a"), "a") + xassert4(f(), "cx") + xassert4(f(), "cxx") + xassert4(f(undefined), "cxxx") +} +testDfltEvaluation4() + +function testArrowExprCalls4() { + let x = (a1: S4, a2?: S4, a3?: S4) => a1 + (a2 ?? "u") + (a3 ?? "u") + xassert4(x("a"), "auu") + xassert4(x("a", "b"), "abu") + xassert4(x("a", "b", "c"), "abc") + + xassert4(((a?: S4) => a ?? "u")(), "u") + // xassert4(((a?: S4) => a ?? "u")("a"), "a") // #22952: broken +} +testArrowExprCalls4() + +class X4 { + constructor(v: (p?: T4) => T4) { this.fv = v } + get f() { return this.fv } + fv: (p?: T4) => T4 +} +function gcall4(x: X4, a: T4) { + (x.f)(); + (x.f)(a); + (x.fv)(); + (x.fv)(a); +} +function testGenerics4() { + let res: string = ":" + let fn = (a?: string) => { + res += (a ?? "D"); + return res; + }; + gcall4(new X4(fn), "a") // #22952: inference fails + xassert4(res, ":DaDa") +} +testGenerics4(); + +function foo4(a1: S4, a2?: S4) { return a1 + (a2 ?? "D") } +function testFuncRef4() { + let f = (a1: S4, a2?: S4) => foo4(a1, a2) // #22952: foo4 is overloaded + xassert4(f("a"), "aD") + xassert4(f("a", undefined), "aD") + xassert4(f("a", "b"), "ab") +} +testFuncRef4(); + +// --------------------------------------------------------------------------------------------------------------------- +// OptionalChains.ets +// --------------------------------------------------------------------------------------------------------------------- + +function assert_n5(v: Object | null | undefined) { arktest.assertTrue(v === null); } +function assert_u5(v: Object | null | undefined) { arktest.assertTrue(v === undefined); } +function assert_o5(v: Object | null | undefined) { arktest.assertTrue(v !== null && v !== undefined); } +function assert_npe5(f: () => void) { + try { + f(); + } catch (e) { + return; + } + arktest.assertTrue(false, "npe was not thrown") +} + +class Link5 { + m(): Link5 { return this; } + f: Link5 = this; + a: Link5[] = [(this)]; + c: () => Link5 = () => this + + om(): Link5 | null { return this.m() } + of: Link5 | null = this.f; + oa: Link5[] | null = this.a; + oc: (() => Link5) | null = this.c; + + nm(): Link5 | null { return null } + nf: Link5 | null = null; + na: Link5[] | null = null; + nc: (() => Link5) | null = null; + + static noevalFlag = true; + noeval(): Link5 { if (Link5.noevalFlag) { throw new Error("never evaluated"); } return this; } +} + +function test15(l: Link5 | null, nl: Link5 | null) { + assert_o5(l?.m()); + assert_o5(l?.f); + assert_o5(l?.a[0]); + assert_o5(l?.c()); + assert_o5(l?.of!.f); + + assert_u5(nl?.m()); + assert_u5(nl?.f); + assert_u5(nl?.a[0]); + assert_u5(nl?.c()); + assert_u5(nl?.of!.f); + assert_u5(nl?.nf!.f); + + nl?.m().noeval(); + nl?.f.noeval(); + nl?.a[0].noeval(); + nl?.c().noeval(); + nl?.of!.f.noeval(); + assert_npe5(() => { nl?.of!.f! }); +} + +function test25(l: Link5 | null, nl: Link5 | null) { + assert_o5(l?.m().f.a[0].c()); + assert_o5(l?.f.m().c().a[0]); + assert_o5(l?.a[0].c().f.m()); + assert_o5(l?.c().m().a[0].f); + assert_o5(l?.c().m().of!.a[0].oc!().f); + + assert_u5(nl?.m().f.a[0].c()); + assert_u5(nl?.f.m().c().a[0]); + assert_u5(nl?.a[0].c().f.m()); + assert_u5(nl?.c().m().a[0].f); + assert_u5(nl?.c().m().of!.a[0].oc!().f); + + nl?.m().f.a[0].c().noeval(); + nl?.f.m().c().a[0].noeval(); + nl?.a[0].c().f.m().noeval(); + nl?.c().m().a[0].f.noeval(); + nl?.c().m().of!.a[0].oc!().f.noeval(); +} + +function test35(l: Link5 | null, nl: Link5 | null) { + assert_o5(l?.om()?.of?.oa?.[0].oc?.()); + assert_o5(l?.of?.om()?.oc?.().oa?.[0]); + assert_o5(l?.oa?.[0]?.oc?.().of?.om()); + assert_o5(l?.oc?.().om()?.oa?.[0].of); + assert_o5(l?.oc?.().om()?.of!.oa?.[0].oc!().of); + + assert_u5(nl?.om()?.of?.oa?.[0].oc?.()); + assert_u5(nl?.of?.om()?.oc?.().oa?.[0]); + assert_u5(nl?.oa?.[0]?.oc?.().of?.om()); + assert_u5(nl?.oc?.().om()?.oa?.[0].of); + assert_u5(nl?.oc!().om()?.of!.oa![0].oc!().of); + + nl?.om()?.of?.oa?.[0].oc?.().noeval(); + nl?.of?.om()?.oc?.().oa?.[0].noeval(); + nl?.oa?.[0]?.oc?.().of?.om()?.noeval(); + nl?.oc?.().om()?.oa?.[0].of?.noeval(); + nl?.oc?.().om()?.of!.oa?.[0].oc!().of?.noeval(); +} + +function test45(l: Link5 | null, nl: Link5 | null) { + assert_npe5(() => { nl?.of! }); + nl?.of!.f; +} + +function test55(l: Link5 | null, nl: Link5 | null) { + l?.f.a[0]?.f.c(); + nl?.f.a[0]?.f.c().noeval(); + assert_npe5(() => { nl?.f.a[0]?.f.c()! }); + assert_npe5(() => { (nl?.f?.a)?.[0].f! }); + assert_u5(l?.f.a[0].nf?.a[0].noeval()?.m()); + + let u: Link5 | undefined = l?.f.oc?.().na?.[0].noeval().f?.oa?.[0]; +} + +// --------------------------------------------------------------------------------------------------------------------- +// UnionAsAndInstanceof.ets +// --------------------------------------------------------------------------------------------------------------------- + +function assert_ccexc6(f: () => void) { + try { + f(); + } catch (e) { + arktest.assertTrue(e instanceof ClassCastError) + return; + } + arktest.assertTrue(false, "exception expected") +} + +function assert_nothrow6(f: () => void) { + try { + f(); + } catch (e) { + arktest.assertTrue(false, "unexpected exception") + } +} + +class A6 { } +class B6 { } +class C6 { } + +function foo6(x: Object | null | undefined) { return x as Object } + +function test_nullsafety6() { + // Handling of Object may be a bit different, so test it separately + // let f = ... until inference in form ((p)=>expr)(a) is broken + assert_ccexc6(() => { let f = ((x: Object | null | undefined) => x as Object); f(null); }); + assert_ccexc6(() => { let f = ((x: Object | null | undefined) => x as Object); f(undefined); }); + assert_ccexc6(() => { let f = ((x: Object | null) => x as Object); f(null); }); + assert_ccexc6(() => { let f = ((x: Object | undefined) => x as Object); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: Object | null | undefined) => x as Object | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: Object | null | undefined) => x as Object | null); f(undefined); }); + assert_ccexc6(() => { let f = ((x: Object | null) => x as Object | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: Object | undefined) => x as Object | null); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6); f(undefined); }); + assert_ccexc6(() => { let f = ((x: A6 | null) => x as A6); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | undefined) => x as A6); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | null); f(undefined); }); + assert_ccexc6(() => { let f = ((x: A6 | null) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | undefined) => x as A6 | null); f(undefined); }); + + + assert_nothrow6(() => { let f = ((x: Object | null | undefined) => x as Object); f(new Object()); }); + assert_nothrow6(() => { let f = ((x: Object | null | undefined) => x as Object); f(new Object); }); + assert_nothrow6(() => { let f = ((x: Object | null) => x as Object); f(new Object()); }); + assert_nothrow6(() => { let f = ((x: Object | undefined) => x as Object); f(new Object()); }); + + assert_nothrow6(() => { let f = ((x: Object | null | undefined) => x as Object | undefined); f(new Object()); }); + assert_nothrow6(() => { let f = ((x: Object | null | undefined) => x as Object | null); f(new Object()); }); + assert_nothrow6(() => { let f = ((x: Object | null) => x as Object | undefined); f(new Object()); }); + assert_nothrow6(() => { let f = ((x: Object | undefined) => x as Object | null); f(new Object()); }); + + assert_nothrow6(() => { let f = ((x: A6 | null | undefined) => x as A6); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | null | undefined) => x as A6); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | null) => x as A6); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | undefined) => x as A6); f(new A6()); }); + + assert_nothrow6(() => { let f = ((x: A6 | null | undefined) => x as A6 | undefined); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | null | undefined) => x as A6 | null); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | null) => x as A6 | undefined); f(new A6()); }); + assert_nothrow6(() => { let f = ((x: A6 | undefined) => x as A6 | null); f(new A6()); }); +} + +function test_unions6() { + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6) => x as A6); f(new C6()); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6) => x as A6 | B6); f(new C6()); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6 | null) => x as A6 | B6); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6 | undefined) => x as A6 | B6); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | null); f(undefined); }); + assert_ccexc6(() => { let f = ((x: A6 | null) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | undefined) => x as A6 | null); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6) => x as A6); f(new C6()); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6) => x as A6 | B6); f(new C6()); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6 | null) => x as A6 | B6); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | B6 | C6 | undefined) => x as A6 | B6); f(undefined); }); + + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | null | undefined) => x as A6 | null); f(undefined); }); + assert_ccexc6(() => { let f = ((x: A6 | null) => x as A6 | undefined); f(null); }); + assert_ccexc6(() => { let f = ((x: A6 | undefined) => x as A6 | null); f(undefined); }); +} + +// --------------------------------------------------------------------------------------------------------------------- +// UncheckedCasts.ets +// --------------------------------------------------------------------------------------------------------------------- + +function assert_ccexc7(f: () => void) { + try { + f(); + } catch (e) { + arktest.assertTrue(e instanceof ClassCastError) + return; + } + arktest.assertTrue(false, "exception expected") +} + +class A7 { } +class B7 { } +class C7 { } +class X7 { } + +function erase7(x: Object | null | undefined): T7 { return x as T7; } + +function test_substitution7() { + assert_ccexc7(() => { erase7(null); }) + assert_ccexc7(() => { erase7(undefined); }) + assert_ccexc7(() => { erase7(null); }) + assert_ccexc7(() => { erase7(undefined); }) + + assert_ccexc7(() => { erase7(null); }) + assert_ccexc7(() => { erase7(undefined); }) + assert_ccexc7(() => { erase7(null); }) + assert_ccexc7(() => { erase7(undefined); }) + + assert_ccexc7(() => { erase7(undefined); }) + assert_ccexc7(() => { erase7(new Object()); }) + assert_ccexc7(() => { erase7(new B7()); }) + + assert_ccexc7(() => { erase7(undefined); }) + assert_ccexc7(() => { erase7(new Object()); }) + assert_ccexc7(() => { erase7(new C7()); }) + + assert_ccexc7(() => { erase7>(new B7[0]); }) +} + +class Erased7 { + constructor(x: Object | null | undefined) { this.t7 = x as T7; } + t7: T7; +} + +function test_substitution_memberexpr7() { + assert_ccexc7(() => { new Erased7(null).t7; }) + assert_ccexc7(() => { new Erased7(undefined).t7; }) + assert_ccexc7(() => { new Erased7(null).t7; }) + assert_ccexc7(() => { new Erased7(undefined).t7; }) + + assert_ccexc7(() => { new Erased7(null).t7; }) + assert_ccexc7(() => { new Erased7(undefined).t7; }) + assert_ccexc7(() => { new Erased7(null).t7; }) + assert_ccexc7(() => { new Erased7(undefined).t7; }) + + assert_ccexc7(() => { new Erased7(undefined).t7; }) + assert_ccexc7(() => { new Erased7(new Object()).t7; }) + assert_ccexc7(() => { new Erased7(new B7()).t7; }) + + assert_ccexc7(() => { new Erased7(undefined).t7; }) + assert_ccexc7(() => { new Erased7(new Object()).t7; }) + assert_ccexc7(() => { new Erased7(new C7()).t7; }) + + assert_ccexc7(() => { new Erased7>(new B7[0]).t7; }) +} + +function cast_to_tparam7(x: Object | null | undefined) { x as T7; } + +function test_constraint7() { + assert_ccexc7(() => { cast_to_tparam7(undefined); }) + assert_ccexc7(() => { cast_to_tparam7(new Object()); }) + assert_ccexc7(() => { cast_to_tparam7(new C7()); }) +} + +function to_basetype7(x: Object | null | undefined) { return x as X7; } + +function test_basetype7() { + assert_ccexc7(() => { to_basetype7(null); }) + assert_ccexc7(() => { to_basetype7(undefined); }) + assert_ccexc7(() => { to_basetype7(new Object()); }) + assert_ccexc7(() => { to_basetype7(new C7()); }) +} + +// --------------------------------------------------------------------------------------------------------------------- +// partialTypeRuntime_2.ets +// --------------------------------------------------------------------------------------------------------------------- + +class Class18 { fld: Number = 2; } + +function test_18(): void { + let class1_partial: Partial = {fld: 3}; + arktest.assertEQ(class1_partial.fld, 3) + class1_partial.fld = undefined; + arktest.assertTrue(class1_partial.fld === undefined) +} + +// ----------------------------------------------- + +class Class28 { + fld: Number = 2; + foo(a0: Partial) { + a0.fld = undefined; + } +} + +function test_28(): void { + let class2_original: Class28 = new Class28(); + let class2_partial: Partial = {fld: 3}; + arktest.assertEQ(class2_partial.fld, 3) + class2_original.foo(class2_partial); + arktest.assertTrue(class2_partial.fld === undefined) +} + +// ----------------------------------------------- + +class Class38 { + mmeb: Number = 2; + foo(a0: Partial){ + a0.mmeb = undefined; + } +} + +class Class48 extends Class38 {} + +class Class58 extends Class48 { + mmeb: Number = 2; + foo(a0: Partial){ + a0.mmeb = undefined; + } +} + +function test_38(): void { + let class3_original: Class38 = new Class38(); + let class5_original: Class38 = new Class58(); + let class3_partial: Partial = {mmeb: 8}; + let class5_partial: Partial = {mmeb: 10}; + class3_original.foo(class5_partial); + class5_original.foo(class3_partial); + arktest.assertTrue(class3_partial.mmeb === undefined) + arktest.assertTrue(class5_partial.mmeb === undefined) +} + +// ----------------------------------------------- + +class Class68 { + mmeb: Number = 2; + foo(a0: Partial){ + if(this.mmeb == 3){ + return; + } + + this.bar(a0); + } + bar(a0: Partial){ + this.mmeb = 3; + this.foo(a0); + } +} + +class Class78 { fld: Number = 6;} + +class Class88 { + baz(a0: Partial){ + a0.fld = undefined; + } +} + +function test_48(): void { + let class7_partial: Partial = {fld: 8}; + let class6_original: Class68 = new Class68(); + class6_original.foo(class7_partial); +} + +// ----------------------------------------------- + +class Class98 { fld: Number = 8; } + +class Class108 extends Class98 { memb: Number = 9; } + +function test_58(): void { + let class10_partial: Partial = {memb: 7, fld: 5}; + + arktest.assertEQ(class10_partial.memb, 7) + arktest.assertEQ(class10_partial.fld, 5) + + class10_partial.memb = undefined; + class10_partial.fld = undefined; + + arktest.assertTrue(class10_partial.memb === undefined) + arktest.assertTrue(class10_partial.fld === undefined) +} + +//--------------------------------------- + + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_01.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C33 { + bar(): string { + return ""; + } +} + +function foo33(c: Object|null|undefined): string { + if (c instanceof string) { + arktest.assertEQ(c.length, 11) + c = "Case 1"; + } else if (c instanceof C33) { + arktest.assertEQ(c.bar(), "Class C33") + c = "Case 2"; + } else if (c instanceof Int) { + arktest.assertEQ(c * 7, 49) + c = "Case 3"; + } else if (c instanceof null) { + arktest.assertEQ(c, null) + c = "Case 4"; + } else { + c = "Case 5"; + } + + arktest.assertEQ(c.length, 6) + return c; +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_02.ets +// --------------------------------------------------------------------------------------------------------------------- + +class A31 { + bar(): string { + return "Class A31"; + } +} + +class B31 extends A31 {} + +class C31 extends B31 { + bar(): string { + return "Class C31"; + } +} + +function foo31(c: Int|String|A31|null|undefined): void { + if (c instanceof String) { + arktest.assertEQ(c.length, 11) + } else if (c instanceof C31) { + arktest.assertEQ(c.bar(), "Class C31") + } else if (c instanceof Int) { + arktest.assertEQ(c * c, 49) + } else if (c === undefined) { + arktest.assertEQ(c, undefined) + } else { + arktest.assertEQ(c, null) + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_03.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C32 { + constructor() {} + + constructor(a: int) { + this.x = a; + } + + bar(): string { + return "Class C32"; + } + + baz(): int { + return this.x; + } + + private x: int = 7; +} + +function foo32(c: Object|null|undefined): string { + if (c instanceof string && (c.length == 11 || c == "Test")) { + c = "Case 1"; + } else if (c instanceof C32 && c.baz() == 7) { + arktest.assertEQ(c.bar(), "Class C32") + c = "Case 2"; + } else if (c instanceof Int && c >= 0) { + arktest.assertTrue(c >= 0) + c = "Case 3"; + } else if (c instanceof null) { + arktest.assertEQ(c, null) + c = "Case 4"; + } else { + c = "Case 5"; + } + + arktest.assertEQ(c.length, 6) + return c; +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_04.ets +// --------------------------------------------------------------------------------------------------------------------- + +function fooAnd34(x: String|null, y: String|null): string { + if (x != null && y != null) { + return x + " " + y; + } else if (x == null && y == null) { + return "null"; + } else if (x != null && y == null) { + return x; + } else if (x == null && y != null) { + return y; + } else { + throw new Error("Unreachable"); + } +} + +function fooOr134(x: String|null, y: String|null): string { + if (x != null || y != null) { + return "case 1"; + } else if (x == null && y == null) { + return "null"; + } else { + throw new Error("Unreachable"); + } +} + +function fooOr234(x: String|null, y: String|null): string { + if (x == null || y == null) { + return "case 1"; + } else if (x != null && y != null) { + return x + " " + y; + } else { + throw new Error("Unreachable"); + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_05.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C35 { + readonly a: boolean + constructor(a_: boolean = false) { + this.a = a_; + } +} + +function foo135(x: C35|null|undefined): string { + if (x == null || !x.a) { + return x != null ? "false1" : "null"; + } else { + return x.a ? "true2" : "false2"; + } +} + +function foo235(x: C35|null|undefined): string { + if (x != null && x.a) { + return "true"; + } else { + return x != null ? "false" : "null"; + } +} + +function bar35(x: C35|null|undefined, y: boolean, z: boolean): string { + if ((x instanceof C35 && y) || (x instanceof C35 && z)) { + return (x.a ? "true1" : "false1") + y + z; + } else { + return (x != null ? (x.a ? "true2" : "false2") : "null") + y + z; + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_06.ets +// --------------------------------------------------------------------------------------------------------------------- + +function foo36(x: int): string | undefined +{ + let rc: string|undefined = "default"; + + label1: switch(x) { + case 0: + rc = "case 0"; + break; + case 1: { + let rc1: string|undefined = ():string => {return "case 1";}(); + label2: switch(rc) { + case "default": + rc = undefined; + break label2; + default: + break label1; + } + rc = rc1; + break; + } + case 2: + rc = undefined; + let rc2: string|null = ():string => {return "case 2";}(); + return rc2; + case 3: + rc = "case 3"; + break; + case 4: + rc = undefined; + break; + case 5: + rc = "case 5"; + break; + default: + return rc != null ? rc :"case 4" + } + + return rc; +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_08.ets +// --------------------------------------------------------------------------------------------------------------------- + +function foo37(flag37: boolean): int { + + let x: int|undefined = 0; + let y: int|undefined = 1; + let z: int|undefined = 2; + let w: int|undefined = 3; + + try { + y = 1; + if (flag37) { + throw new Error(); + } + } catch(ex) { + if (ex instanceof NullPointerError) { + z = 2; + } else { + w = undefined + } + } + + return x + y! + z + w!; +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_09.ets +// --------------------------------------------------------------------------------------------------------------------- + +class A38 { + prev_: A38|undefined = undefined; + next_: A38|undefined = undefined; + + m() { + const prev = this.prev_; + const next = this.next_; + + if (prev) { + this.prev_ = undefined; + prev.next_ = next; + } + + if (next) { + this.next_ = undefined; + next.prev_ = prev; + } + + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_10.ets +// --------------------------------------------------------------------------------------------------------------------- + +interface It39 { +} + +class Cl39 implements It39 { + + constructor(p: T39) { + this.x = p; + } + + static resolve(value: U|It39): Cl39 { + if (value instanceof Cl39) { + return value as Cl39; + } + return new Cl39(value as U); + } + + x: T39; + + print(): string { + if (this.x == undefined) { + return "value is " + this.x; + } + else if (this.x instanceof string) { + return "string: '" + this.x + "'"; + } else { + return "number = " + this.x; + } + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_11.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C41 {} + +function foo41(arg?: boolean): C41 | undefined { + if (arg == undefined) { + return undefined; + } + return arg == false ? undefined : new C41(); +} + +function bar41(arg?: boolean): C41 | undefined { + if (arg == true) return new C41(); + return arg == false ? undefined : new C41(); +} + +function baz41(arg?: boolean): int { + if (arg == undefined) return 0; + arktest.assertEQ(typeof arg, "boolean") + return 1; +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_13.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C43 {} + +function foo43(arg?: number): C43 | undefined { + if (arg == 5) return new C43(); + return arg == 3 ? undefined : new C43(); +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_14.ets +// --------------------------------------------------------------------------------------------------------------------- + +class A44 { + A44(a44?: T44 | number[]) { + if (a44 instanceof Error) { + return this.D(a44); + } else if (a44 instanceof undefined) { + return this.B(a44); + } else if (a44 instanceof number[]) { + return this.E(a44); + } else { + return this.C(a44); + } + } + + B(b: undefined) { + return "undefined"; + } + + C(c: T44) { + return "Generic"; + } + + D(d: Error) { + return "Error"; + } + + E(e: number[]) { + return "number[]" + } +} + +let a44 = new A44(); +arktest.assertEQ(a44.A44(Error()), "Error"); +arktest.assertEQ(a44.A44(undefined), "undefined"); +arktest.assertEQ(a44.A44(1), "Generic"); +arktest.assertEQ(a44.A44([1, 2, 3]), "number[]") + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_15.ets +// --------------------------------------------------------------------------------------------------------------------- + +// Issue #22779 - smart cast in return statement +function isEmpty45(text?: string): boolean { + return text === undefined || text === null || text.length === 0 +} + +// Some other examples +function foo45(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 +} + +// --------------------------------------------------------------------------------------------------------------------- +// SmartCast_16.ets +// --------------------------------------------------------------------------------------------------------------------- + +class C45 { + readonly fld: T45 + constructor(p: T45) { + this.fld = p + } +} + +type NestedC45 = String | C45 | Error + + +function main(): void { + // ----------------------------------------------------------------------------------------------------------------- + // AccessBinaryTrees.ets + // ----------------------------------------------------------------------------------------------------------------- + + let a = new AccessBinaryTrees; + a.run(); + + // ----------------------------------------------------------------------------------------------------------------- + // ArrayLiteral.ets + // ----------------------------------------------------------------------------------------------------------------- + + let a1: byte = 2; + let b1: short = 20000; + let c1: int = 2000000; + let d1: long = 200000000000; + let e1: float = 2.2f; + let f1: double = 2.2222222222; + let g1: double[] = [a1, b1, c1, d1, e1, f1]; + arktest.assertEQ(g1[0], 2) + arktest.assertEQ(g1[1], 20000) + arktest.assertEQ(g1[2], 2000000) + arktest.assertEQ(g1[3], 200000000000) + arktest.assertEQ(g1[4], (Double.toFloat(2.2))) + arktest.assertEQ(g1[5], 2.2222222222) + + const h1: byte = 2; + const i1: short = 2; + const j1: int = 2; + const k1: long = 2; + const l1: float = 2.0f; + const m1: double = 2.0; + const n1: byte[] = [h1, Short.toByte(i1), Int.toByte(j1), Long.toByte(k1), Float.toByte(l1), Double.toByte(m1)]; + arktest.assertEQ(n1[0], 2) + arktest.assertEQ(n1[1], 2) + arktest.assertEQ(n1[2], 2) + arktest.assertEQ(n1[3], 2) + arktest.assertEQ(n1[4], 2) + arktest.assertEQ(n1[5], 2) + + let o1: Object[] = [1, 1.1, "testStr", new Int(2), d1, k1]; + arktest.assertEQ(o1[0] as Int, 1) + arktest.assertEQ(o1[1] as Double, 1.1) + arktest.assertTrue((o1[2] as String).equals("testStr")) + arktest.assertEQ(o1[3] as Int, 2) + arktest.assertEQ(o1[4] as Long, 200000000000) + arktest.assertEQ(o1[5] as Long, 2) + + let p1: long[] = [new Int(3), new Short(2 as short), new Long(4)]; + arktest.assertEQ(p1[0], 3) + arktest.assertEQ(p1[1], 2) + arktest.assertEQ(p1[2], 4) + + // ----------------------------------------------------------------------------------------------------------------- + // RestTuple6.ets + // ----------------------------------------------------------------------------------------------------------------- + + let a12: [A2, B2] = [new A2, new B2] + arktest.assertTrue((new C2()).foo(...a12) == false) + arktest.assertTrue((new C2()).moo(12, ...a12) == false) + arktest.assertTrue((new C2()).foo(...[new A2, new B2]) == false) + arktest.assertTrue((new C2()).moo(12, ...[new A2, new B2]) == false) + arktest.assertTrue((new C2()).foo(...[new A2, new B2] as [A2, B2]) == false) + arktest.assertTrue((new C2()).moo(12, ...[new A2, new B2] as [A2, B2]) == false) + arktest.assertTrue((new C2()).foo(new A2, new B2) == false) + arktest.assertTrue((new C2()).moo(12, new A2, new B2) == false) + + // ----------------------------------------------------------------------------------------------------------------- + // GenericBridges_02.ets + // ----------------------------------------------------------------------------------------------------------------- + + ttt3(new D3()) + let c3: C3 = new E3(); + foo13(c3); + foo23(new E3()); + + // ----------------------------------------------------------------------------------------------------------------- + // OptionalChains.ets + // ----------------------------------------------------------------------------------------------------------------- + + test15(new Link5(), null) + test25(new Link5(), null) + test35(new Link5(), null) + test45(new Link5(), null) + test55(new Link5(), null) + + // ----------------------------------------------------------------------------------------------------------------- + // UnionAsAndInstanceof.ets + // ----------------------------------------------------------------------------------------------------------------- + + test_nullsafety6(); + test_unions6(); + + // ----------------------------------------------------------------------------------------------------------------- + // UncheckedCasts.ets + // ----------------------------------------------------------------------------------------------------------------- + + test_substitution7(); + test_substitution_memberexpr7(); + test_constraint7(); + test_basetype7(); + + // ----------------------------------------------------------------------------------------------------------------- + // partialTypeRuntime_2.ets + // ----------------------------------------------------------------------------------------------------------------- + + test_18(); + test_28(); + test_38(); + test_48(); + test_58(); + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_01.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(foo33("Test string"), "Case 1") + arktest.assertEQ(foo33(new Int(7)), "Case 3") + arktest.assertEQ(foo33(new C33()), "Case 2") + arktest.assertEQ(foo33(null), "Case 4") + arktest.assertEQ(foo33(undefined), "Case 5") + arktest.assertEQ(foo33(new Number(3.0)), "Case 5") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_02.ets + // ----------------------------------------------------------------------------------------------------------------- + + foo31("Test string"); + foo31(new Int(7)); + foo31(new C31()); + foo31(null); + foo31(undefined); + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_03.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(foo32("Test string"), "Case 1") + arktest.assertEQ(foo32("Test"), "Case 1") + arktest.assertEQ(foo32("Test string 2"), "Case 5") + arktest.assertEQ(foo32("test"), "Case 5") + + arktest.assertEQ(foo32(new Int(5)), "Case 3") + arktest.assertEQ(foo32(new Int(0)), "Case 3") + arktest.assertEQ(foo32(new Int(-5)), "Case 5") + + arktest.assertEQ(foo32(new C32(7)), "Case 2") + arktest.assertEQ(foo32(new C32()), "Case 2") + arktest.assertEQ(foo32(new C32(17)), "Case 5") + + arktest.assertEQ(foo32(null), "Case 4") + + arktest.assertEQ(foo32(undefined), "Case 5") + arktest.assertEQ(foo32(new Number(3.0)), "Case 5") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_04.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(fooAnd34("Test", "string"), "Test string") + arktest.assertEQ(fooAnd34("Test", null), "Test") + arktest.assertEQ(fooAnd34(null, "string"), "string") + arktest.assertEQ(fooAnd34(null, null), "null") + + arktest.assertEQ(fooOr134("Test", "string"), "case 1") + arktest.assertEQ(fooOr134("Test", null), "case 1") + arktest.assertEQ(fooOr134(null, "string"), "case 1") + arktest.assertEQ(fooOr134(null, null), "null") + + arktest.assertEQ(fooOr234("Test", "string"), "Test string") + arktest.assertEQ(fooOr234("Test", null), "case 1") + arktest.assertEQ(fooOr234(null, "string"), "case 1") + arktest.assertEQ(fooOr234(null, null), "case 1") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_05.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(foo135(null), "null") + arktest.assertEQ(foo235(null), "null") + arktest.assertEQ(bar35(null, true, true), "nulltruetrue") + arktest.assertEQ(bar35(null, true, false), "nulltruefalse") + arktest.assertEQ(bar35(null, false, true), "nullfalsetrue") + arktest.assertEQ(bar35(null, false, false), "nullfalsefalse") + + arktest.assertEQ(foo135(undefined), "null") + arktest.assertEQ(foo235(undefined), "null") + arktest.assertEQ(bar35(undefined, true, true), "nulltruetrue") + arktest.assertEQ(bar35(undefined, true, false), "nulltruefalse") + arktest.assertEQ(bar35(undefined, false, true), "nullfalsetrue") + arktest.assertEQ(bar35(undefined, false, false), "nullfalsefalse") + + let c = new C35(); + arktest.assertEQ(foo135(c), "false1") + arktest.assertEQ(foo235(c), "false") + arktest.assertEQ(bar35(c, true, true), "false1truetrue") + arktest.assertEQ(bar35(c, true, false), "false1truefalse") + arktest.assertEQ(bar35(c, false, true), "false1falsetrue") + arktest.assertEQ(bar35(c, false, false), "false2falsefalse") + + c = new C35(true); + arktest.assertEQ(foo135(c), "true2") + arktest.assertEQ(foo235(c), "true") + arktest.assertEQ(bar35(c, true, true), "true1truetrue") + arktest.assertEQ(bar35(c, true, false), "true1truefalse") + arktest.assertEQ(bar35(c, false, true), "true1falsetrue") + arktest.assertEQ(bar35(c, false, false), "true2falsefalse") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_06.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(foo36(0), "case 0") + arktest.assertEQ(foo36(1), "case 1") + arktest.assertEQ(foo36(2), "case 2") + arktest.assertEQ(foo36(3), "case 3") + arktest.assertEQ(foo36(4), "case 4") + arktest.assertEQ(foo36(5), "case 5") + arktest.assertEQ(foo36(7), "default") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_07.ets + // ----------------------------------------------------------------------------------------------------------------- + + let x363: int | boolean | string = 7; + arktest.assertEQ(x363, 7) + x363--; + arktest.assertEQ(x363, 6) + x363 = x363 == 7; + arktest.assertTrue(!x363) + x363 = !x363; + arktest.assertEQ(x363, true) + x363 = "x363 = " + x363.toString(); + arktest.assertEQ(x363, "x363 = true") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_08.ets + // ----------------------------------------------------------------------------------------------------------------- + + let flag37: boolean = false; + arktest.assertEQ(foo37(flag37), 6) + try { + foo37(!flag37); + } catch(ex) { + flag37 = true; + } + arktest.assertTrue(flag37) + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_10.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(Cl39.resolve(undefined).print(), "value is undefined") + arktest.assertEQ(Cl39.resolve("test").print(), "string: 'test'") + arktest.assertEQ(Cl39.resolve(5.5).print(), "number = 5.5") + arktest.assertEQ(Cl39.resolve(new Int(8)).print(), "number = 8") + + arktest.assertEQ(Cl39.resolve(new Cl39(null)).print(), "value is null") + arktest.assertEQ(Cl39.resolve(new Cl39("TEST")).print(), "string: 'TEST'") + arktest.assertEQ(Cl39.resolve(new Cl39(7.7)).print(), "number = 7.7") + arktest.assertEQ(Cl39.resolve(new Cl39(new Int(-8))).print(), "number = -8") + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_11.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertTrue(foo41(true) instanceof C41) + arktest.assertEQ(foo41(false), undefined) + arktest.assertEQ(foo41(), undefined) + + arktest.assertTrue(bar41(true) instanceof C41) + arktest.assertEQ(bar41(false), undefined) + arktest.assertTrue(bar41() instanceof C41) + + arktest.assertEQ(baz41(true), 1) + arktest.assertEQ(baz41(false), 1) + arktest.assertEQ(baz41(), 0) + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_12.ets + // ----------------------------------------------------------------------------------------------------------------- + + let resolve42: ((value: string) => void) | null = null; + + let p42 = new Promise((_resolve: (value: string)=> void): void => { + resolve42 = _resolve; + }); + + resolve42!("abc"); // no smart cast! + + let x42: Number|String|undefined = "test1"; + let y42: Number|String|undefined = "test2" + let z42: Number|String|undefined = 7 + + let lam42: () => void = () => { + let y42: Number|String|undefined = 2; // hides outer declaration! + x42 = z42; + let tmp: number = y42; // smart cast is used + arktest.assertEQ(tmp, 2); + }; + + if (x42 instanceof string) { + let tmp: string = x42 as string; // no smart cast! + arktest.assertEQ(tmp, "test1"); + } + + lam42(); + + arktest.assertEQ(x42, 7); + + if (y42 instanceof string) { + let tmp: string = y42; // smart cast is used + arktest.assertEQ(tmp, "test2"); + } + + let w42: number = z42; // smart cast is used + arktest.assertEQ(w42, 7) + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_13.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertTrue(foo43(5) instanceof C43) + arktest.assertEQ(foo43(3), undefined) + arktest.assertTrue(foo43(undefined) instanceof C43) + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_15.ets + // ----------------------------------------------------------------------------------------------------------------- + + arktest.assertEQ(isEmpty45(), true) + arktest.assertEQ(isEmpty45(""), true) + arktest.assertEQ(isEmpty45("a"), false) + arktest.assertEQ(foo45(), true) + + // ----------------------------------------------------------------------------------------------------------------- + // SmartCast_16.ets + // ----------------------------------------------------------------------------------------------------------------- + + let x45: NestedC45 = new C45>(new C45(new Error())) + let ok45 = x45 instanceof C45 && x45.fld instanceof C45 && x45.fld.fld instanceof Error + let aaa = ok45 ? 0 : 1 + +} diff --git a/ets2panda/test/benchmarks/etsstdlib-max.txt b/ets2panda/test/benchmarks/etsstdlib-max.txt new file mode 100644 index 0000000000000000000000000000000000000000..ab8a25fbeba5dce556305e95ec236cb135547251 --- /dev/null +++ b/ets2panda/test/benchmarks/etsstdlib-max.txt @@ -0,0 +1,66 @@ +================ es2panda perf metrics (Averaged over 500 runs) ================ + +:@phases : time=4770.18ms mem=324.00MB +:@GenerateProgram : time=2571.34ms mem=0.00MB +:@GenerateProgram/OptimizeBytecode : time=1896.82ms mem=0.00MB +:@phases/CheckerPhase : time=1781.74ms mem=81.00MB +:@EmitProgram : time=485.84ms mem=130.58MB +:@phases/Unbox : time=437.00ms mem=38.00MB +:@phases/ConstantExpressionLowering : time=363.29ms mem=0.28MB +:@phases/LambdaObjectConversion : time=328.18ms mem=22.00MB +:@phases/TopLevelStatements : time=277.34ms mem=83.00MB +:@phases/GradualTypeNarrowing : time=198.37ms mem=19.00MB +:@phases/ResolveIdentifiers : time=123.95ms mem=5.13MB +:@phases/OpAssignmentLowering : time=116.33ms mem=18.00MB +:@phases/InterfaceObjectLiteralLowering : time=76.22ms mem=7.00MB +:@phases/ScopesInitPhase : time=60.61ms mem=13.00MB +:@phases/ObjectIndexLowering : time=52.64ms mem=1.90MB +:@phases/PartialExportClassGen : time=50.08ms mem=8.00MB +:@phases/CreateGenericBridges : time=43.00ms mem=3.00MB +:@phases/RestArgsLowering : time=42.90ms mem=4.00MB +:@phases/BoxingForLocals : time=41.18ms mem=1.88MB +:@phases/PrimitiveConversion : time=39.01ms mem=4.00MB +:@phases/ArrayLiteralLowering : time=38.51ms mem=4.00MB +:@phases/LateInitializationConvert : time=38.24ms mem=0.00MB +:@phases/ObjectIteratorLowering : time=30.96ms mem=1.00MB +:@phases/UnionLowering : time=25.90ms mem=0.04MB +:@phases/ObjectLiteralLowering : time=25.72ms mem=0.00MB +:@phases/OptionalArgumentsLowering : time=25.23ms mem=0.22MB +:@phases/StringConstructorLowering : time=25.14ms mem=0.00MB +:@phases/TypeFromLowering : time=24.09ms mem=0.00MB +:@phases/ExpandBracketsPhase : time=23.46ms mem=0.00MB +:@phases/SetterLowering : time=23.02ms mem=0.27MB +:@phases/StringComparisonLowering : time=21.98ms mem=0.00MB +:@phases/RecordLowering : time=21.10ms mem=0.00MB +:@phases/ExtentionAccessorPhase : time=20.90ms mem=0.00MB +:@phases/InterfacePropertyDeclarationsPhase : time=20.54ms mem=1.00MB +:@phases/DynamicImport : time=20.29ms mem=0.00MB +:@phases/BigIntLowering : time=19.61ms mem=0.00MB +:@phases/EnumPostCheckLoweringPhase : time=19.03ms mem=0.21MB +:@phases/ResizableArrayConvert : time=18.56ms mem=0.48MB +:@phases/EnumLoweringPhase : time=18.53ms mem=0.83MB +:@phases/RestTupleConstructionPhase : time=18.49ms mem=0.23MB +:@phases/DefaultParametersLowering : time=18.43ms mem=0.26MB +:@phases/OptionalLowering : time=18.42ms mem=0.49MB +:@phases/AsyncMethodLowering : time=18.41ms mem=0.00MB +:@phases/OverloadMappingLowering : time=18.02ms mem=0.00MB +:@phases/SpreadConstructionPhase : time=17.69ms mem=0.00MB +:@phases/DeclareOverloadLowering : time=17.58ms mem=0.00MB +:@phases/PromiseVoidInferencePhase : time=17.22ms mem=0.00MB +:@phases/AnnotationCopyPostLowering : time=16.95ms mem=0.00MB +:@phases/AnnotationCopyLowering : time=16.86ms mem=0.00MB +:@phases/InsertOptionalParametersAnnotation : time=16.86ms mem=0.48MB +:@phases/AmbientLowering : time=16.77ms mem=0.00MB +:@phases/CapturedVariables : time=16.71ms mem=0.00MB +:@phases/ExpressionLambdaConstruction : time=16.60ms mem=0.03MB +:@phases/DefaultParametersInConstructorLowering : time=16.21ms mem=0.51MB +:@phases/SetJumpTargetPhase : time=16.00ms mem=0.00MB +:@phases/DeclGenPhase : time=0.02ms mem=0.00MB +:@phases/plugins-after-parse : time=0.01ms mem=0.00MB +:@phases/plugins-after-lowering : time=0.00ms mem=0.00MB +:@phases/plugins-after-bind : time=0.00ms mem=0.00MB +:@phases/CFGBuilder : time=0.00ms mem=0.00MB +:@phases/StringConstantsLowering : time=0.00ms mem=0.00MB +:@phases/plugins-after-check : time=0.00ms mem=0.00MB +:@phases/ExportAnonymousConstPhase : time=0.00ms mem=0.00MB +:@phases/PackageImplicitImport : time=0.00ms mem=0.00MB diff --git a/ets2panda/test/benchmarks/runner/arg_parser.py b/ets2panda/test/benchmarks/runner/arg_parser.py new file mode 100644 index 0000000000000000000000000000000000000000..40cf4e5e8f1de82bcf3d3c86a5a612ad76564ef2 --- /dev/null +++ b/ets2panda/test/benchmarks/runner/arg_parser.py @@ -0,0 +1,71 @@ +#!/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 + + +def parse_arguments() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Cpp headers parser to .yaml") + + parser.add_argument("--mode", "-m", type=str, required=True, help="Mode: 'static' or 'dynamic'") + parser.add_argument("--es2panda", "-e", type=str, required=True, help="Path to current es2panda") + parser.add_argument("--es2panda-pre-merge", "-c", type=str, required=False, help="Path to pre_merge es2panda") + parser.add_argument("--test-dir", "-t", type=str, required=True, help="Path to test directory with test files") + parser.add_argument("--work-dir", "-a", type=str, required=True, help="Path to the working temp folder") + parser.add_argument("--werror", "-w", action="store_true", help="Warnings as errors") + parser.add_argument( + "--dynamic-regression", + "-d", + type=float, + required=False, + default=0.05, + help="Acceptable regression compared to the pre_merge", + ) + parser.add_argument( + "--static-regression", + "-s", + type=float, + required=False, + default=0.1, + help="Acceptable regression compared to static measurement", + ) + parser.add_argument("--runs", "-n", type=int, required=False, default=25, help="Number of times to run the command") + + return parser.parse_args() + + +def check_arguments(args: argparse.Namespace) -> argparse.Namespace: + if args.mode not in ["static", "dynamic"]: + raise RuntimeError(f"Invalid mode: {args.mode}\nSee --help for more.") + if not os.path.isfile(args.es2panda): + raise RuntimeError(f"Bad path to current es2panda: {args.es2panda}\nSee --help for more.") + if args.mode == "dynamic" and not os.path.isfile(args.es2panda_pre_merge): + raise RuntimeError(f"Bad path to pre_merge es2panda: {args.es2panda_pre_merge}\nSee --help for more.") + if not os.path.isdir(args.test_dir): + raise RuntimeError(f"Bad path to test_dir: {args.test_dir}\nSee --help for more.") + if args.dynamic_regression > 1 or args.dynamic_regression < -1: + raise RuntimeError( + f"Static regression must be in value range [-1, 1], current: {args.dynamic_regression}\n" + "See --help for more." + ) + if args.static_regression > 1 or args.static_regression < -1: + raise RuntimeError( + f"Static regression must be in value range [-1, 1], current: {args.static_regression}\n" + "See --help for more." + ) + + return args diff --git a/ets2panda/test/benchmarks/runner/benchmark_comparator.py b/ets2panda/test/benchmarks/runner/benchmark_comparator.py new file mode 100644 index 0000000000000000000000000000000000000000..6ad4a97c940dbce79c9c2673b0fa48d0cf41fce9 --- /dev/null +++ b/ets2panda/test/benchmarks/runner/benchmark_comparator.py @@ -0,0 +1,150 @@ +#!/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 os +from pathlib import Path +from typing import Dict, Optional, Tuple, List, Callable + +from metrics_utils import parse_perf_file, format_diff, format_time_ms, format_mem_mb + + +def _get_phase_comparison(phase: str, base: Optional[Dict], new: Optional[Dict]) -> Tuple[str, str, str]: + if base and new: + label = phase + time_diff = new["time_ns"] - base["time_ns"] + mem_diff = new["mem_bytes"] - base["mem_bytes"] + time_str = format_diff(time_diff, base["time_ns"], format_time_ms) + mem_str = format_diff(mem_diff, base["mem_bytes"], format_mem_mb) + elif new: + label = f"{phase} [NEW]" + time_str = f"+{format_time_ms(new['time_ns'])}" + mem_str = f"+{format_mem_mb(new['mem_bytes'])}" + elif base: + label = f"{phase} [REMOVED]" + time_str = f"-{format_time_ms(base['time_ns'])}" + mem_str = f"-{format_mem_mb(base['mem_bytes'])}" + else: + return "", "", "" + return label, time_str, mem_str + + +def _write_report(report_path: Path, base_name: str, new_name: str, results: List[Dict]) -> None: + if not results: + print("No common or unique phases to compare.") + return + + max_phase_len = max(len(r["phase"]) for r in results) + header = f"Performance Comparison: '{base_name}' vs '{new_name}'\n" + "=" * 80 + + lines = [header] + for r in results: + phase_str = f":@{r['phase']}" + lines.append(f"{phase_str:<{max_phase_len + 3}}: time={r['time_str']:<25} mem={r['mem_str']:<25}") + + report_path.write_text("\n".join(lines), encoding="utf-8") + print(f"\n✅ Comparison finished! Results saved to: {report_path}") + + +def _print_and_log(level: str, msg: str, log_dir: Path) -> None: + if level == "Error": + print(f"\n❌ {msg}") + path = log_dir / "error_log.txt" + else: + print(f"\n⚠️ {msg}") + path = log_dir / "warning_log.txt" + with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT | os.O_APPEND, mode=511), "a", encoding="utf-8") as f: + f.write(msg + "\n") + + +def _check_regression( + metric_name: str, + base_data: Dict, + new_data: Dict, + regression: float, + perf_name: str, + log_dir: Path, + is_static: bool = False, +) -> None: + format_func: Callable[[float], str] + success = True + if metric_name == "Time": + key = "time_ns" + format_func = format_time_ms + elif metric_name == "Memory": + key = "mem_bytes" + format_func = format_mem_mb + else: + raise RuntimeError(f"Unsupported metric: {metric_name}") + + base_sum = sum(base_data.get(p, {}).get(key, 0) for p in ["phases", "EmitProgram"]) + new_sum = sum(new_data.get(p, {}).get(key, 0) for p in ["phases", "EmitProgram"]) + + upper_threshold = base_sum * (1 + regression) + if new_sum > upper_threshold: + msg = ( + f"[PERF REGRESSION] Failed for {perf_name}: {metric_name} exceeded upper threshold.\n" + f"\tLimit: {regression:.1%}, Actual: +{((new_sum / base_sum) - 1) * 100:.2f}%\n" + f"\tBase: {format_func(base_sum)}, New: {format_func(new_sum)}\n" + f"\tThreshold: < {format_func(upper_threshold)}\n" + ) + _print_and_log("Error", msg, log_dir) + success = False + + lower_threshold = base_sum * (1 - regression * 3) + if is_static and new_sum < lower_threshold: + msg = ( + f"[UPDATE REQUIRED] Very good perf for {perf_name}: {metric_name} exceeded lower threshold.\n" + f"\tLimit: -{regression * 3:.1%}, Actual: {((new_sum / base_sum) - 1) * 100:.2f}%\n" + f"\tBase: {format_func(base_sum)}, New: {format_func(new_sum)}\n" + f"\tThreshold: > {format_func(lower_threshold)}\n\n" + "Please update *-max.txt.\n" + ) + _print_and_log("Warning", msg, log_dir) + success = False + + if success: + print(f"\n✅ {metric_name} regression check for {perf_name} finished!") + msg = ( + f"[UPDATE REQUIRED] Perf statistics for {perf_name}: {metric_name} exceeded lower threshold.\n" + f"\tLimit: {regression:.1%}, Actual: +{((new_sum / base_sum) - 1) * 100:.2f}%\n" + f"\tBase: {format_func(base_sum)}, New: {format_func(new_sum)}\n" + ) + _print_and_log("Info", msg, log_dir) + + +def compare_perf_files( + new_perf_path: Path, base_perf_path: Path, report_path: Path, regression: float, log_dir: Path +) -> None: + base_data = parse_perf_file(base_perf_path) + new_data = parse_perf_file(new_perf_path) + + if not new_data: + raise RuntimeError("New perf data is empty") + if not base_data: + raise RuntimeError("Base perf data is empty") + + is_static = base_perf_path.name.find("-max.txt") != -1 + _check_regression("Time", base_data, new_data, regression, new_perf_path.name, log_dir, is_static) + _check_regression("Memory", base_data, new_data, regression, new_perf_path.name, log_dir, is_static) + results = [] + all_phases = sorted(list(set(base_data.keys()) | set(new_data.keys()))) + + for phase in all_phases: + label, time_str, mem_str = _get_phase_comparison(phase, base_data.get(phase), new_data.get(phase)) + if label: + results.append({"phase": label, "time_str": time_str, "mem_str": mem_str}) + + _write_report(report_path, base_perf_path.name, new_perf_path.name, results) diff --git a/ets2panda/test/benchmarks/runner/benchmark_runner.py b/ets2panda/test/benchmarks/runner/benchmark_runner.py new file mode 100644 index 0000000000000000000000000000000000000000..9df01f66c625a38ad5c2baa461193ed63b366228 --- /dev/null +++ b/ets2panda/test/benchmarks/runner/benchmark_runner.py @@ -0,0 +1,101 @@ +#!/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 subprocess +import re +from collections import defaultdict +from pathlib import Path +from typing import List, Dict, Union, DefaultDict + +from metrics_utils import parse_metric_value, format_time_ms, format_mem_mb + + +def run_and_parse(command: List) -> Dict: + print(f"Executing: {' '.join(command)}") + try: + result = subprocess.run(command, capture_output=True, text=True, check=True, encoding="utf-8") + except (FileNotFoundError, subprocess.CalledProcessError) as e: + print(f"Error executing command: {e}") + if isinstance(e, subprocess.CalledProcessError): + print(f"Stdout:\n{e.stdout}\nStderr:\n{e.stderr}") + return {} + + line_regex = re.compile(r":@(?P[\w\/-]+)\s*:\s*time=(?P